Progress #148: early implementation of solution 2

Needs testing in all the different scenarios, but we no longer fail to
start when resyncing.
This commit is contained in:
Nathan Hourt 2015-07-10 14:17:13 -04:00
parent c0da987b02
commit 0f6e5a74cd
3 changed files with 43 additions and 9 deletions

View file

@ -32,6 +32,7 @@
#include <fc/rpc/websocket_api.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/signals2.hpp>
#include <iostream>
@ -284,11 +285,17 @@ namespace detail {
{ try {
ilog("Got block #${n} from network", ("n", blk_msg.block.block_num()));
try {
return _chain_db->push_block( blk_msg.block, _is_block_producer? database::skip_nothing : database::skip_transaction_signatures );
return _chain_db->push_block(blk_msg.block, _is_block_producer? database::skip_nothing : database::skip_transaction_signatures);
} catch( const fc::exception& e ) {
elog("Error when pushing block:\n${e}", ("e", e.to_detail_string()));
throw;
}
if( !_is_finished_syncing && !sync_mode )
{
_is_finished_syncing = true;
_self->syncing_finished();
}
} FC_CAPTURE_AND_RETHROW( (blk_msg)(sync_mode) ) }
virtual bool handle_transaction(const graphene::net::trx_message& trx_msg, bool sync_mode) override
@ -408,7 +415,7 @@ namespace detail {
* @param item_count the number of items known to the node that haven't been sent to handle_item() yet.
* After `item_count` more calls to handle_item(), the node will be in sync
*/
virtual void sync_status(uint32_t item_type, uint32_t item_count) override
virtual void sync_status(uint32_t item_type, uint32_t item_count) override
{
// any status reports to GUI go here
}
@ -416,7 +423,7 @@ namespace detail {
/**
* Call any time the number of connected peers changes.
*/
virtual void connection_count_changed(uint32_t c) override
virtual void connection_count_changed(uint32_t c) override
{
// any status reports to GUI go here
}
@ -470,6 +477,8 @@ namespace detail {
std::shared_ptr<fc::http::websocket_tls_server> _websocket_tls_server;
std::map<string, std::shared_ptr<abstract_plugin>> _plugins;
bool _is_finished_syncing = false;
};
}
@ -579,6 +588,11 @@ optional< api_access_info > application::get_api_access_info( const string& user
return my->get_api_access_info( username );
}
bool application::is_finished_syncing() const
{
return my->_is_finished_syncing;
}
void graphene::app::application::add_plugin(const string& name, std::shared_ptr<graphene::app::abstract_plugin> p)
{
my->_plugins[name] = p;

View file

@ -77,6 +77,10 @@ namespace graphene { namespace app {
void set_block_production(bool producing_blocks);
fc::optional< api_access_info > get_api_access_info( const string& username )const;
bool is_finished_syncing()const;
/// Emitted when syncing finishes (is_finished_syncing will return true)
boost::signals2::signal<void()> syncing_finished;
private:
void add_plugin( const string& name, std::shared_ptr<abstract_plugin> p );
std::shared_ptr<detail::application_impl> my;

View file

@ -86,12 +86,28 @@ void witness_plugin::plugin_initialize(const boost::program_options::variables_m
void witness_plugin::plugin_startup()
{ try {
std::set<chain::witness_id_type> bad_wits;
//Start NTP time client
graphene::time::now();
for( auto wit : _witnesses )
chain::database& d = database();
std::set<chain::witness_id_type> bad_wits;
//Start NTP time client
graphene::time::now();
for( auto wit : _witnesses )
{
auto signing_key = wit(database()).signing_key;
if( d.find(wit) == nullptr )
{
if( app().is_finished_syncing() )
{
elog("ERROR: Unable to find witness ${w}, even though syncing has finished. This witness will be ignored.",
("w", wit));
continue;
} else {
wlog("WARNING: Unable to find witness ${w}. Postponing initialization until syncing finishes.",
("w", wit));
app().syncing_finished.connect([this]{plugin_startup();});
return;
}
}
auto signing_key = wit(d).signing_key;
if( !_private_keys.count(signing_key) )
{
// Check if it's a duplicate key of one I do have
@ -119,7 +135,7 @@ void witness_plugin::plugin_startup()
{
ilog("Launching block production for ${n} witnesses.", ("n", _witnesses.size()));
app().set_block_production(true);
schedule_next_production(database().get_global_properties().parameters);
schedule_next_production(d.get_global_properties().parameters);
} else
elog("No witnesses configured! Please add witness IDs and private keys to configuration.");
} FC_CAPTURE_AND_RETHROW() }