diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index 3bb8ad68..da87cf93 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -22,6 +22,7 @@ #include #include +#include #include @@ -240,19 +241,18 @@ namespace detail { if( _options->count("resync-blockchain") ) _chain_db->wipe(_data_dir / "blockchain", true); + flat_map loaded_checkpoints; if( _options->count("checkpoint") ) { auto cps = _options->at("checkpoint").as>(); - flat_map loaded_checkpoints; loaded_checkpoints.reserve( cps.size() ); for( auto cp : cps ) { auto item = fc::json::from_string(cp).as >(); loaded_checkpoints[item.first] = item.second; } - _chain_db->add_checkpoints( loaded_checkpoints ); } - + _chain_db->add_checkpoints( loaded_checkpoints ); if( _options->count("replay-blockchain") ) { @@ -265,6 +265,18 @@ namespace detail { _chain_db->reindex(_data_dir / "blockchain", initial_state()); } + if (!_options->count("genesis-json") && + _chain_db->get_global_properties().chain_id != graphene::egenesis::get_egenesis_chain_id()) { + elog("Detected old database. Nuking and starting over."); + _chain_db->wipe(_data_dir / "blockchain", true); + _chain_db.reset(); + _chain_db = std::make_shared(); + _chain_db->add_checkpoints(loaded_checkpoints); + _chain_db->open(_data_dir / "blockchain", initial_state); + } + + graphene::time::now(); + if( _options->count("apiaccess") ) _apiaccess = fc::json::from_file( _options->at("apiaccess").as() ) .as(); diff --git a/libraries/fc b/libraries/fc index cb006ba0..9c868b39 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit cb006ba03c9bf67e6e7cf6a4a8387d387aa4bd3c +Subproject commit 9c868b3927a7c0aad3f628ad0071c92f11a0923c diff --git a/programs/full_web_node/BlockChain.cpp b/programs/full_web_node/BlockChain.cpp index 8756fbf1..a5b192bc 100644 --- a/programs/full_web_node/BlockChain.cpp +++ b/programs/full_web_node/BlockChain.cpp @@ -15,7 +15,7 @@ #include BlockChain::BlockChain() - : chainThread(fc::thread::current()), + : chainThread(new fc::thread("chainThread")), fcTaskScheduler(new QTimer(this)), grapheneApp(new graphene::app::application) { @@ -25,25 +25,33 @@ BlockChain::BlockChain() fcTaskScheduler->start(); } -BlockChain::~BlockChain(){ - grapheneApp->shutdown_plugins(); +BlockChain::~BlockChain() { + startFuture.cancel_and_wait(__FUNCTION__); + chainThread->async([this] { + grapheneApp->shutdown_plugins(); + delete grapheneApp; + }).wait(); + delete chainThread; } void BlockChain::start() { - try { - grapheneApp->register_plugin(); - grapheneApp->register_plugin(); + startFuture = chainThread->async([this] { + try { + grapheneApp->register_plugin(); + grapheneApp->register_plugin(); - QString dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); - QDir(dataDir).mkpath("."); - boost::program_options::variables_map map; - map.insert({"rpc-endpoint",boost::program_options::variable_value(std::string("127.0.0.1:8090"), false)}); - map.insert({"seed-node",boost::program_options::variable_value(std::vector{("104.200.28.117:61705")}, false)}); - grapheneApp->initialize(dataDir.toStdString(), map); - grapheneApp->startup(); - grapheneApp->startup_plugins(); - } catch (const fc::exception& e) { - elog("Crap went wrong: ${e}", ("e", e.to_detail_string())); - } + QString dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + QDir(dataDir).mkpath("."); + boost::program_options::variables_map map; + map.insert({"rpc-endpoint",boost::program_options::variable_value(std::string("127.0.0.1:8090"), false)}); + map.insert({"seed-node",boost::program_options::variable_value(std::vector{("104.200.28.117:61705")}, false)}); + grapheneApp->initialize(dataDir.toStdString(), map); + grapheneApp->startup(); + grapheneApp->startup_plugins(); + } catch (const fc::exception& e) { + elog("Crap went wrong: ${e}", ("e", e.to_detail_string())); + } + QMetaObject::invokeMethod(this, "started"); + }); } diff --git a/programs/full_web_node/BlockChain.hpp b/programs/full_web_node/BlockChain.hpp index 115bfa6e..b1efef63 100644 --- a/programs/full_web_node/BlockChain.hpp +++ b/programs/full_web_node/BlockChain.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include class QTimer; @@ -9,9 +11,10 @@ namespace graphene { namespace app { class application; } } class BlockChain : public QObject { Q_OBJECT - fc::thread& chainThread; + fc::thread* chainThread; QTimer* fcTaskScheduler; graphene::app::application* grapheneApp; + fc::future startFuture; public: BlockChain(); @@ -19,4 +22,7 @@ public: public Q_SLOTS: void start(); + +Q_SIGNALS: + void started(); }; diff --git a/programs/full_web_node/main.cpp b/programs/full_web_node/main.cpp index 1f6bdcc7..7ae44f84 100644 --- a/programs/full_web_node/main.cpp +++ b/programs/full_web_node/main.cpp @@ -20,20 +20,13 @@ int main(int argc, char *argv[]) app.setOrganizationDomain("cryptonomex.org"); app.setOrganizationName("Cryptonomex, Inc."); - QThread chainThread; - fc::promise::ptr chain = new fc::promise; - QObject::connect(&chainThread, &QThread::started, [&app, &chain] { - chain->set_value(new BlockChain); - }); - chainThread.start(); - QtWebEngine::initialize(); fc::http::server webGuiServer; fc::thread serverThread("HTTP server thread"); serverThread.async([&webGuiServer] { webGuiServer.listen(fc::ip::endpoint::from_string("127.0.0.1:8080")); webGuiServer.on_request([](const fc::http::request& request, const fc::http::server::response& response) { - QString path = QStringLiteral("/Users/nathan/graphene-ui/web/bundle") + QString::fromStdString(request.path); + QString path = QStringLiteral("/Users/nathan/graphene-ui/web/dist") + QString::fromStdString(request.path); if (path.endsWith('/')) path.append(QStringLiteral("index.html")); QFile file(path); @@ -52,13 +45,9 @@ int main(int argc, char *argv[]) }); }); + qmlRegisterType("Graphene.FullNode", 1, 0, "BlockChain"); QQmlApplicationEngine engine; - auto chainPtr = chain->wait(); - engine.rootContext()->setContextProperty(QStringLiteral("blockChain"), chainPtr); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); - auto ret = app.exec(); - chainPtr->deleteLater(); - chainThread.exit(ret); - return ret; + return app.exec(); } diff --git a/programs/full_web_node/qml/main.qml b/programs/full_web_node/qml/main.qml index 7fa1f9ff..c3280179 100644 --- a/programs/full_web_node/qml/main.qml +++ b/programs/full_web_node/qml/main.qml @@ -2,17 +2,32 @@ import QtQuick 2.5 import QtQuick.Window 2.2 import QtWebEngine 1.0 +import Graphene.FullNode 1.0 + Window { id: window width: Screen.width / 2 height: Screen.height / 2 + visible: true + BlockChain { + id: blockChain + onStarted: webView.url = "http://localhost:8080" + } Component.onCompleted: blockChain.start() Rectangle { anchors.fill: parent; color: "#1F1F1F" } + Text { + font.pointSize: 20 + anchors.centerIn: parent + text: qsTr("Loading...") + color: "white" + } WebEngineView { + id: webView + visible: false anchors.fill: parent - url: "http://localhost:8080" - onLoadProgressChanged: if (loadProgress === 100) window.visible = true + onLoadProgressChanged: if (loadProgress === 100) visible = true + onJavaScriptConsoleMessage: console.log(JSON.stringify(arguments)) } }