未验证 提交 0616aae2 编写于 作者: K Kevin Heifner 提交者: GitHub

Merge pull request #1085 from EOSIO/mongo_db_plugin_GH#1047

Mongo db plugin to eos-noon
......@@ -75,7 +75,7 @@ before_install:
script:
- mkdir build && cd build
- ${CMAKE_DIR}cmake -G Ninja -DWASM_LLVM_CONFIG=$TRAVIS_BUILD_DIR/ext/wasm-compiler/bin/llvm-config -DSecp256k1_ROOT_DIR=$TRAVIS_BUILD_DIR/ext -DBINARYEN_ROOT=$TRAVIS_BUILD_DIR/ext/wasm-compiler -DCMAKE_PREFIX_PATH=$TRAVIS_BUILD_DIR/ext -DCMAKE_BUILD_TYPE=Release $EOS_CMAKE_OPTIONS ..
- ${CMAKE_DIR}cmake -G Ninja -DWASM_LLVM_CONFIG=$TRAVIS_BUILD_DIR/ext/wasm-compiler/bin/llvm-config -DSecp256k1_ROOT_DIR=$TRAVIS_BUILD_DIR/ext -DBINARYEN_ROOT=$TRAVIS_BUILD_DIR/ext/wasm-compiler -DCMAKE_PREFIX_PATH=$TRAVIS_BUILD_DIR/ext -DCMAKE_BUILD_TYPE=Release -DBUILD_MONGO_DB_PLUGIN=true $EOS_CMAKE_OPTIONS ..
- ninja -j4
# - tests/eosd_run_test.sh --host=localhost --port=8888
- '[ "$TRAVIS_OS_NAME" == "osx" ] || tests/chain_test'
......
......@@ -34,6 +34,7 @@ list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules" )
set(CMAKE_EXPORT_COMPILE_COMMANDS "ON")
set(BUILD_DOXYGEN FALSE CACHE BOOL "Build doxygen documentation on every make")
set(BUILD_MONGO_DB_PLUGIN FALSE CACHE BOOL "Build mongo database plugin")
set(EOS_EGENESIS_JSON "${CMAKE_CURRENT_SOURCE_DIR}/genesis.json" )
#set (ENABLE_INSTALLER 1)
......@@ -59,6 +60,19 @@ LIST(APPEND BOOST_COMPONENTS thread
locale)
SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
if(UNIX)
if(APPLE)
set(whole_archive_flag "-force_load")
set(no_whole_archive_flag "")
else()
set(whole_archive_flag "--whole-archive")
set(no_whole_archive_flag "--no-whole-archive")
endif()
else()
set(whole_archive_flag "--whole-archive")
set(no_whole_archive_flag "--no-whole-archive")
endif()
IF( WIN32 )
SET(BOOST_ROOT $ENV{BOOST_ROOT})
set(Boost_USE_MULTITHREADED ON)
......@@ -177,8 +191,8 @@ else()
endif()
add_subdirectory( libraries )
add_subdirectory( programs )
add_subdirectory( plugins )
add_subdirectory( programs )
add_subdirectory( tests )
add_subdirectory( tools )
......@@ -230,12 +244,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/genesis.json ${CMAKE_CURRENT_BINARY_D
include(FindDoxygen)
if(NOT DOXYGEN_FOUND)
message(STATUS "Doxygen not found. Contract documentation will not be generated.")
else()
message(STATUS "Doxygen found. Contract documentation will be generated.")
set(DOXY_EOS_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" CACHE INTERNAL "Version string used in PROJECT_NUMBER.")
# CMake strips trailing path separators off of variables it knows are paths,
# so the trailing '/' Doxygen expects is embedded in the doxyfile.
......@@ -248,15 +259,14 @@ else()
endif(DOXYGEN_DOT_FOUND)
configure_file("eos.doxygen.in" "${CMAKE_BINARY_DIR}/eos.doxygen")
if(BUILD_DOXYGEN)
# !! Core developers who don't want to see the doxygen output on every build
# !! should remove the 'ALL' option from both commands below.
# Doxygen has issues making destination directories more than one level deep, so do it for it.
add_custom_target(make_doc_dir ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${DOXY_DOC_DEST_DIR}")
add_custom_target(contract_documentation ALL
COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/eos.doxygen"
DEPENDS make_doc_dir
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMENT "Building doxygen documentation into ${DOXY_DOC_DEST_DIR}..."
VERBATIM)
message(STATUS "Doxygen found. Contract documentation will be generated.")
# Doxygen has issues making destination directories more than one level deep, so do it for it.
add_custom_target(make_doc_dir ALL COMMAND ${CMAKE_COMMAND} -E make_directory "${DOXY_DOC_DEST_DIR}")
add_custom_target(contract_documentation ALL
COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/eos.doxygen"
DEPENDS make_doc_dir
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMENT "Building doxygen documentation into ${DOXY_DOC_DEST_DIR}..."
VERBATIM)
endif(BUILD_DOXYGEN)
endif()
......@@ -52,6 +52,9 @@ chain_controller::chain_controller( const chain_controller::controller_config& c
{
_initialize_indexes();
for (auto& f : cfg.applied_irreversible_block_callbacks)
applied_irreversible_block.connect(f);
contracts::chain_initializer starter(cfg.genesis);
starter.register_types(*this, _db);
......@@ -1065,15 +1068,34 @@ void chain_controller::_initialize_chain(contracts::chain_initializer& starter)
auto acts = starter.prepare_database(*this, _db);
transaction genesis_setup_transaction;
// create a block for our genesis transaction to send to applied_irreversible_block below
signed_block block{};
block.producer = config::system_account_name;
block_trace btrace{block};
btrace.region_traces.emplace_back();
auto& rtrace = btrace.region_traces.back();
rtrace.cycle_traces.emplace_back();
auto& ctrace = rtrace.cycle_traces.back();
ctrace.shard_traces.emplace_back();
auto& strace = ctrace.shard_traces.back();
signed_transaction genesis_setup_transaction; // not actually signed, signature checking is skipped
genesis_setup_transaction.actions = move(acts);
block.input_transactions.emplace_back(genesis_setup_transaction);
ilog( "applying genesis transaction" );
with_skip_flags(skip_scope_check | skip_transaction_signatures | skip_authority_check | received_block | genesis_setup,
[&](){
transaction_metadata tmeta( genesis_setup_transaction );
__apply_transaction( tmeta );
transaction_trace ttrace = __apply_transaction( tmeta );
strace.append(ttrace);
});
// TODO: Should we write this genesis block instead of faking it on startup?
strace.calculate_root();
applied_block(btrace);
applied_irreversible_block(block);
ilog( "done applying genesis transaction" );
});
}
......
......@@ -67,6 +67,7 @@ namespace eosio { namespace chain {
path shared_memory_dir = config::default_shared_memory_dir;
uint64_t shared_memory_size = config::default_shared_memory_size;
bool read_only = false;
std::vector<signal<void(const signed_block&)>::slot_type> applied_irreversible_block_callbacks;
contracts::genesis_state_type genesis;
};
......
add_subdirectory(net_plugin)
add_subdirectory(net_api_plugin)
#add_subdirectory(p2p_plugin)
add_subdirectory(http_plugin)
add_subdirectory(chain_plugin)
add_subdirectory(chain_api_plugin)
......@@ -11,3 +10,4 @@ add_subdirectory(wallet_plugin)
add_subdirectory(wallet_api_plugin)
add_subdirectory(txn_test_gen_plugin)
add_subdirectory(faucet_testnet_plugin)
add_subdirectory(mongo_db_plugin)
......@@ -12,6 +12,8 @@ namespace eosio {
using namespace eosio;
static appbase::abstract_plugin& _account_history_api_plugin = app().register_plugin<account_history_api_plugin>();
account_history_api_plugin::account_history_api_plugin(){}
account_history_api_plugin::~account_history_api_plugin(){}
......
......@@ -9,6 +9,8 @@
namespace eosio {
static appbase::abstract_plugin& _chain_api_plugin = app().register_plugin<chain_api_plugin>();
using namespace eosio;
class chain_api_plugin_impl {
......
......@@ -45,6 +45,7 @@ public:
fc::optional<fork_database> fork_db;
fc::optional<block_log> block_logger;
fc::optional<chain_controller::controller_config> chain_config = chain_controller::controller_config();
fc::optional<chain_controller> chain;
chain_id_type chain_id;
uint32_t rcvd_block_txn_execution_time;
......@@ -135,15 +136,12 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
}
if (options.at("replay-blockchain").as<bool>()) {
fc::remove_all(app().data_dir() / default_shared_memory_dir);
ilog("Replay requested: wiping database");
/// TODO: db->wipe_database();
fc::remove_all(app().data_dir() / default_shared_memory_dir);
}
if (options.at("resync-blockchain").as<bool>()) {
ilog("Resync requested: wiping database and blocks");
fc::remove_all(app().data_dir() / default_shared_memory_dir);
ilog("Resync requested: wiping blocks");
/// TODO: db->wipe_database();
fc::remove_all(my->block_log_dir);
}
if (options.at("skip-transaction-signatures").as<bool>()) {
......@@ -184,26 +182,20 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
my->rate_limits.per_code_account = options.at("per-code-account-transaction-msg-rate-limit").as<uint32_t>();*/
}
using applied_irreversible_block_func = typename decltype(((chain_controller*)nullptr)->applied_irreversible_block)::slot_type;
void chain_plugin::plugin_startup()
void chain_plugin::plugin_startup()
{ try {
optional<applied_irreversible_block_func> applied_func;
FC_ASSERT( fc::exists( my->genesis_file ),
FC_ASSERT( fc::exists( my->genesis_file ),
"unable to find genesis file '${f}', check --genesis-json argument",
("f",my->genesis_file.generic_string()) );
chain_controller::controller_config config;
config.block_log_dir = my->block_log_dir;
config.shared_memory_dir = app().data_dir() / default_shared_memory_dir;
config.read_only = my->readonly;
config.genesis = fc::json::from_file(my->genesis_file).as<contracts::genesis_state_type>();
my->chain_config->block_log_dir = my->block_log_dir;
my->chain_config->shared_memory_dir = app().data_dir() / default_shared_memory_dir;
my->chain_config->read_only = my->readonly;
my->chain_config->genesis = fc::json::from_file(my->genesis_file).as<contracts::genesis_state_type>();
if (my->genesis_timestamp.sec_since_epoch() > 0) {
config.genesis.initial_timestamp = my->genesis_timestamp;
my->chain_config->genesis.initial_timestamp = my->genesis_timestamp;
}
my->chain.emplace(config);
my->chain.emplace(*my->chain_config);
if(!my->readonly) {
ilog("starting chain in read/write mode");
......@@ -211,9 +203,11 @@ void chain_plugin::plugin_startup()
}
ilog("Blockchain started; head block is #${num}, genesis timestamp is ${ts}",
("num", my->chain->head_block_num())("ts", (std::string)config.genesis.initial_timestamp));
("num", my->chain->head_block_num())("ts", (std::string)my->chain_config->genesis.initial_timestamp));
my->chain_config.reset();
} FC_CAPTURE_AND_RETHROW( (my->genesis_file.generic_string()) ) }
} FC_CAPTURE_AND_RETHROW( (my->genesis_file.generic_string()) ) }
void chain_plugin::plugin_shutdown() {
my->chain.reset();
......@@ -252,6 +246,11 @@ bool chain_plugin::is_skipping_transaction_signatures() const {
return my->skip_flags & skip_transaction_signatures;
}
chain_controller::controller_config& chain_plugin::chain_config() {
// will trigger optional assert if called before/after plugin_initialize()
return *my->chain_config;
}
chain_controller& chain_plugin::chain() { return *my->chain; }
const chain_controller& chain_plugin::chain() const { return *my->chain; }
......
......@@ -309,6 +309,8 @@ public:
// return true if --skip-transaction-signatures passed to eosd
bool is_skipping_transaction_signatures() const;
// Only call this in plugin_initialize() to modify chain_controller constructor configuration
chain_controller::controller_config& chain_config();
// Only call this after plugin_startup()!
chain_controller& chain();
// Only call this after plugin_startup()!
......
......@@ -48,6 +48,8 @@ FC_REFLECT(eosio::detail::faucet_testnet_create_account_rate_limited_response, (
namespace eosio {
static appbase::abstract_plugin& _faucet_testnet_plugin = app().register_plugin<faucet_testnet_plugin>();
using namespace eosio::chain;
using public_key_type = chain::public_key_type;
using key_pair = std::pair<std::string, std::string>;
......
......@@ -23,6 +23,9 @@
#include <memory>
namespace eosio {
static appbase::abstract_plugin& _http_plugin = app().register_plugin<http_plugin>();
namespace asio = boost::asio;
using std::map;
......
if(BUILD_MONGO_DB_PLUGIN)
file(GLOB HEADERS "include/eosio/mongo_db_plugin/*.hpp")
add_library( mongo_db_plugin
mongo_db_plugin.cpp
${HEADERS} )
find_package(libmongoc-1.0 1.8)
if (libmongoc-1.0_FOUND)
# EOS has no direct dependencies on libmongoc but its shared libraries
# will need to be present at runtime for the C++ libraries we use:
# libbsoncxx & libmongocxx (both from github.com/mongodb/mongo-cxx-driver)
# The *.cmake package files provided by mongo-cxx-driver don't give us the
# absolute path to the libraries, which is needed whenever they are not
# installed in system-known locations. CMake requires the absolute paths
# in target_link_libraries() since we are builiding an archive and the
# link step for all executables using this archive must include the
# mongo-cxx-driver libraries libmongocxx and libbsoncxx.
find_package(libbsoncxx REQUIRED)
message(STATUS "Found bsoncxx headers: ${LIBBSONCXX_INCLUDE_DIRS}")
find_library(EOS_LIBBSONCXX ${LIBBSONCXX_LIBRARIES}
PATHS ${LIBBSONCXX_LIBRARY_DIRS} NO_DEFAULT_PATH)
message(STATUS "Found bsoncxx library: ${EOS_LIBBSONCXX}")
find_package(libmongocxx REQUIRED)
message(STATUS "Found mongocxx headers: ${LIBMONGOCXX_INCLUDE_DIRS}")
find_library(EOS_LIBMONGOCXX ${LIBMONGOCXX_LIBRARIES}
PATHS ${LIBMONGOCXX_LIBRARY_DIRS} NO_DEFAULT_PATH)
message(STATUS "Found mongocxx library: ${EOS_LIBMONGOCXX}")
else()
message("Could NOT find MongoDB. mongo_db_plugin with MongoDB support will not be included.")
# sudo apt-get install pkg-config libssl-dev libsasl2-dev
# wget https://github.com/mongodb/mongo-c-driver/releases/download/1.8.0/mongo-c-driver-1.8.0.tar.gz
# tar xzf mongo-c-driver-1.8.0.tar.gz
# cd mongo-c-driver-1.8.0
# ./configure --disable-automatic-init-and-cleanup --enable-static
# make
# sudo make install
#
# git clone https://github.com/mongodb/mongo-cxx-driver.git --branch releases/stable --depth 1
# cd mongo-cxx-driver/build
# cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local ..
# sudo make EP_mnmlstc_core
# make
# sudo make install
#
# sudo apt-get install mongodb
endif()
target_include_directories(mongo_db_plugin
PRIVATE ${LIBMONGOCXX_INCLUDE_DIRS} ${LIBBSONCXX_INCLUDE_DIRS}
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
)
target_compile_definitions(mongo_db_plugin
PRIVATE ${LIBMONGOCXX_DEFINITIONS} ${LIBBSONCXX_DEFINITIONS}
)
target_link_libraries(mongo_db_plugin
PUBLIC chain_plugin eosio_chain appbase
${EOS_LIBMONGOCXX} ${EOS_LIBBSONCXX}
)
install( TARGETS
mongo_db_plugin
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
install( FILES ${HEADERS} DESTINATION "include/eosio/mongo_db_plugin" )
else()
message("mongo_db_plugin not selected and will be omitted.")
endif()
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once
#include <eosio/chain_plugin/chain_plugin.hpp>
#include <appbase/application.hpp>
#include <memory>
namespace eosio {
using mongo_db_plugin_impl_ptr = std::shared_ptr<class mongo_db_plugin_impl>;
/**
* Provides persistence to MongoDB for:
* Blocks
* Transactions
* Actions
* Accounts
*
* See data dictionary (DB Schema Definition - EOS API) for description of MongoDB schema.
*
* The goal ultimately is for all chainbase data to be mirrored in MongoDB via a delayed node processing
* irreversible blocks. Currently, only Blocks, Transactions, Messages, and Account balance it mirrored.
* Chainbase is being rewritten to be multi-threaded. Once chainbase is stable, integration directly with
* a mirror database approach can be followed removing the need for the direct processing of Blocks employed
* with this implementation.
*
* If MongoDB env not available (#ifndef MONGODB) this plugin is a no-op.
*/
class mongo_db_plugin : public plugin<mongo_db_plugin> {
public:
APPBASE_PLUGIN_REQUIRES((chain_plugin))
mongo_db_plugin();
virtual ~mongo_db_plugin();
virtual void set_program_options(options_description& cli, options_description& cfg) override;
void plugin_initialize(const variables_map& options);
void plugin_startup();
void plugin_shutdown();
private:
mongo_db_plugin_impl_ptr my;
};
}
此差异已折叠。
......@@ -19,6 +19,7 @@ FC_REFLECT(eosio::detail::net_api_plugin_empty, );
namespace eosio {
static appbase::abstract_plugin& _net_api_plugin = app().register_plugin<net_api_plugin>();
using namespace eosio;
......
......@@ -33,6 +33,8 @@ namespace fc {
}
namespace eosio {
static appbase::abstract_plugin& _net_plugin = app().register_plugin<net_plugin>();
using std::vector;
using boost::asio::ip::tcp;
......@@ -1337,7 +1339,7 @@ namespace eosio {
auto socket = std::make_shared<tcp::socket>( std::ref( app().get_io_service() ) );
acceptor->async_accept( *socket, [socket,this]( boost::system::error_code ec ) {
if( !ec ) {
int visitors = 0;
uint32_t visitors = 0;
for (auto &conn : connections) {
if(conn->current() && conn->peer_addr.empty()) {
visitors++;
......
......@@ -19,6 +19,8 @@ using std::vector;
namespace eosio {
static appbase::abstract_plugin& _producer_plugin = app().register_plugin<producer_plugin>();
using namespace eosio::chain;
class producer_plugin_impl {
......
......@@ -22,6 +22,8 @@ FC_REFLECT(eosio::detail::txn_test_gen_empty, );
namespace eosio {
static appbase::abstract_plugin& _txn_test_gen_plugin = app().register_plugin<txn_test_gen_plugin>();
using namespace eosio::chain;
#define CALL(api_name, api_handle, call_name, INVOKE, http_response_code) \
......
......@@ -20,6 +20,7 @@ FC_REFLECT(eosio::detail::wallet_api_plugin_empty, );
namespace eosio {
static appbase::abstract_plugin& _wallet_api_plugin = app().register_plugin<wallet_api_plugin>();
using namespace eosio;
......
......@@ -4,6 +4,7 @@
*/
#include <eosio/wallet_plugin/wallet_plugin.hpp>
#include <eosio/wallet_plugin/wallet_manager.hpp>
#include <boost/filesystem/path.hpp>
#include <chrono>
......
......@@ -28,16 +28,33 @@ configure_file(config.hpp.in config.hpp ESCAPE_QUOTES)
target_include_directories(eosiod PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
if(UNIX)
if(APPLE)
set(whole_archive_flag "-force_load")
set(no_whole_archive_flag "")
else()
set(whole_archive_flag "--whole-archive")
set(no_whole_archive_flag "--no-whole-archive")
endif()
else()
set(whole_archive_flag "--whole-archive")
set(no_whole_archive_flag "--no-whole-archive")
endif()
target_link_libraries( eosiod
PRIVATE appbase
PRIVATE account_history_api_plugin account_history_plugin
# PRIVATE db_plugin
PRIVATE chain_api_plugin producer_plugin chain_plugin
PRIVATE wallet_api_plugin
PRIVATE net_plugin net_api_plugin txn_test_gen_plugin
PRIVATE http_plugin faucet_testnet_plugin
PRIVATE -Wl,${whole_archive_flag} account_history_api_plugin -Wl,${no_whole_archive_flag} account_history_plugin
PRIVATE -Wl,${whole_archive_flag} chain_api_plugin -Wl,${no_whole_archive_flag} producer_plugin chain_plugin
PRIVATE -Wl,${whole_archive_flag} wallet_api_plugin -Wl,${no_whole_archive_flag}
PRIVATE net_plugin net_api_plugin -Wl,${whole_archive_flag} txn_test_gen_plugin -Wl,${no_whole_archive_flag}
PRIVATE http_plugin -Wl,${whole_archive_flag} faucet_testnet_plugin -Wl,${no_whole_archive_flag}
PRIVATE eosio_chain fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} )
if(BUILD_MONGO_DB_PLUGIN)
target_link_libraries( eosiod
PRIVATE -Wl,${whole_archive_flag} mongo_db_plugin -Wl,${no_whole_archive_flag} )
endif()
install( TARGETS
eosiod
......
......@@ -4,17 +4,9 @@
*/
#include <appbase/application.hpp>
#include <eosio/producer_plugin/producer_plugin.hpp>
#include <eosio/chain_plugin/chain_plugin.hpp>
#include <eosio/http_plugin/http_plugin.hpp>
#include <eosio/chain_api_plugin/chain_api_plugin.hpp>
#include <eos/net_plugin/net_plugin.hpp>
#include <eos/net_api_plugin/net_api_plugin.hpp>
#include <eosio/account_history_plugin/account_history_plugin.hpp>
#include <eosio/account_history_api_plugin/account_history_api_plugin.hpp>
#include <eosio/wallet_api_plugin/wallet_api_plugin.hpp>
#include <eosio/txn_test_gen_plugin/txn_test_gen_plugin.hpp>
#include <eosio/faucet_testnet_plugin/faucet_testnet_plugin.hpp>
#include <fc/log/logger_config.hpp>
#include <fc/log/appender.hpp>
......@@ -87,14 +79,6 @@ int main(int argc, char** argv)
{
try {
app().set_version(eosio::eosiod::config::version);
app().register_plugin<chain_api_plugin>();
app().register_plugin<producer_plugin>();
app().register_plugin<account_history_api_plugin>();
app().register_plugin<net_plugin>();
app().register_plugin<net_api_plugin>();
app().register_plugin<txn_test_gen_plugin>();
app().register_plugin<wallet_api_plugin>();
app().register_plugin<faucet_testnet_plugin>();
if(!app().initialize<chain_plugin, http_plugin, net_plugin>(argc, argv))
return -1;
initialize_logging();
......
......@@ -868,7 +868,7 @@ launcher_def::write_config_file (tn_node_def &node) {
cfg << "plugin = eosio::producer_plugin\n";
}
if( instance.has_db ) {
cfg << "plugin = eosio::db_plugin\n";
cfg << "plugin = eosio::mongo_db_plugin\n";
}
cfg << "plugin = eosio::chain_api_plugin\n"
<< "plugin = eosio::account_history_api_plugin\n";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册