From 27b5c978dbe310aa2853ab4a5832e1a38d92434e Mon Sep 17 00:00:00 2001 From: Roman Olearski Date: Fri, 21 Apr 2017 14:24:40 +0200 Subject: [PATCH] completing scheduled (restored) witnesses, setting as default --- genesis.json | 6 +-- libraries/chain/db_block.cpp | 5 ++- libraries/chain/db_update.cpp | 35 +++++++++-------- libraries/chain/db_witness_schedule.cpp | 39 +++++-------------- .../chain/protocol/chain_parameters.hpp | 3 +- .../graphene/chain/witness_scheduler.hpp | 29 ++++++++++++-- libraries/plugins/witness/witness.cpp | 16 +++++++- 7 files changed, 77 insertions(+), 56 deletions(-) diff --git a/genesis.json b/genesis.json index 039e51b6..a2931763 100644 --- a/genesis.json +++ b/genesis.json @@ -1,5 +1,5 @@ { - "initial_timestamp": "2017-01-10T08:52:15", + "initial_timestamp": "2017-04-20T14:00:00", "max_core_supply": "1000000000000000", "initial_parameters": { "current_fees": { @@ -445,7 +445,7 @@ "collateral_records": [ { "collateral": -1, - "debt": 100000000000000, + "debt": 1000000000000000, "owner": "TEST6eTLvHVD1Qg5rUoEnKgTvpXaW2p7xHyce" } ], @@ -461,7 +461,7 @@ "collateral_records": [ { "collateral": -1, - "debt": 100000000000000, + "debt": 1000000000000000, "owner": "TEST6eTLvHVD1Qg5rUoEnKgTvpXaW2p7xHyce" } ], diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index 3aba9ea5..21949d77 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -528,6 +528,8 @@ void database::_apply_block( const signed_block& next_block ) ++_current_trx_in_block; } + if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM) + update_witness_schedule(next_block); update_global_dynamic_data(next_block); update_signing_witness(signing_witness, next_block); update_last_irreversible_block(); @@ -552,8 +554,6 @@ void database::_apply_block( const signed_block& next_block ) update_maintenance_flag( maint_needed ); if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) update_witness_schedule(); - if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM) - update_witness_schedule(next_block); if( !_node_property_object.debug_updates.empty() ) apply_debug_updates(); @@ -562,6 +562,7 @@ void database::_apply_block( const signed_block& next_block ) _applied_ops.clear(); notify_changed_objects(); + } FC_CAPTURE_AND_RETHROW( (next_block.block_num()) ) } void database::notify_changed_objects() diff --git a/libraries/chain/db_update.cpp b/libraries/chain/db_update.cpp index 6838468a..1d3bc23d 100644 --- a/libraries/chain/db_update.cpp +++ b/libraries/chain/db_update.cpp @@ -44,30 +44,34 @@ namespace graphene { namespace chain { void database::update_global_dynamic_data( const signed_block& b ) { - const dynamic_global_property_object& _dgp = - dynamic_global_property_id_type(0)(*this); + const dynamic_global_property_object& _dgp = dynamic_global_property_id_type(0)(*this); + const global_property_object& gpo = get_global_properties(); uint32_t missed_blocks = get_slot_at_time( b.timestamp ); + //#define DIRTY_TRICK // problem with missed_blocks can occur when "maintenance_interval" set to few minutes #ifdef DIRTY_TRICK if (missed_blocks != 0) { #else assert( missed_blocks != 0 ); #endif - missed_blocks--; - for( uint32_t i = 0; i < missed_blocks; ++i ) { - const auto& witness_missed = get_scheduled_witness( i+1 )(*this); - if( witness_missed.id != b.witness ) { - /* - const auto& witness_account = witness_missed.witness_account(*this); - if( (fc::time_point::now() - b.timestamp) < fc::seconds(30) ) - wlog( "Witness ${name} missed block ${n} around ${t}", ("name",witness_account.name)("n",b.block_num())("t",b.timestamp) ); - */ + if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) + { + missed_blocks--; + for( uint32_t i = 0; i < missed_blocks; ++i ) { + const auto& witness_missed = get_scheduled_witness( i+1 )(*this); + if( witness_missed.id != b.witness ) { + /* + const auto& witness_account = witness_missed.witness_account(*this); + if( (fc::time_point::now() - b.timestamp) < fc::seconds(30) ) + wlog( "Witness ${name} missed block ${n} around ${t}", ("name",witness_account.name)("n",b.block_num())("t",b.timestamp) ); + */ - modify( witness_missed, [&]( witness_object& w ) { - w.total_missed++; - }); - } + modify( witness_missed, [&]( witness_object& w ) { + w.total_missed++; + }); + } + } } #ifdef DIRTY_TRICK } @@ -173,7 +177,6 @@ void database::update_last_irreversible_block() } ); } } - void database::clear_expired_transactions() { try { //Look for expired transactions in the deduplication list, and remove them. diff --git a/libraries/chain/db_witness_schedule.cpp b/libraries/chain/db_witness_schedule.cpp index 9b968311..3a2378a9 100644 --- a/libraries/chain/db_witness_schedule.cpp +++ b/libraries/chain/db_witness_schedule.cpp @@ -92,42 +92,20 @@ fc::time_point_sec database::get_slot_time(uint32_t slot_num)const const global_property_object& gpo = get_global_properties(); - if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) - { - if( dpo.dynamic_flags & dynamic_global_property_object::maintenance_flag ) - slot_num += gpo.parameters.maintenance_skip_slots; + if( dpo.dynamic_flags & dynamic_global_property_object::maintenance_flag ) + slot_num += gpo.parameters.maintenance_skip_slots; - // "slot 0" is head_slot_time - // "slot 1" is head_slot_time, - // plus maint interval if head block is a maint block - // plus block interval if head block is not a maint block - return head_slot_time + (slot_num * interval); - } - - if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM) - { - // "slot 0" is head_slot_time - // "slot 1" is head_slot_time, - // plus maint interval if head block is a maint block - // plus block interval if head block is not a maint block - return head_slot_time - + (slot_num + - ( - (dpo.dynamic_flags & dynamic_global_property_object::maintenance_flag) - ? gpo.parameters.maintenance_skip_slots : 0 - ) - ) * interval - ; - } - return fc::time_point_sec(); + // "slot 0" is head_slot_time + // "slot 1" is head_slot_time, + // plus maint interval if head block is a maint block + // plus block interval if head block is not a maint block + return head_slot_time + (slot_num * interval); } uint32_t database::get_slot_at_time(fc::time_point_sec when)const { fc::time_point_sec first_slot_time = get_slot_time( 1 ); -#ifndef NDEBUG - std::cout << "@get_slot_at_time " << when.to_iso_string() << " " << first_slot_time.to_iso_string() << "\n"; -#endif + //@ROL std::cout << "@get_slot_at_time " << when.to_iso_string() << " " << first_slot_time.to_iso_string() << "\n"; if( when < first_slot_time ) return 0; return (when - first_slot_time).to_seconds() / block_interval() + 1; @@ -197,6 +175,7 @@ void database::update_witness_schedule(const signed_block& next_block) // triggering FC_ASSERT elsewhere assert( schedule_slot > 0 ); + witness_id_type first_witness; bool slot_is_near = wso.scheduler.get_slot( schedule_slot-1, first_witness ); diff --git a/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp b/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp index 3a3b759c..14a66e7d 100644 --- a/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp +++ b/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp @@ -69,7 +69,8 @@ namespace graphene { namespace chain { uint16_t accounts_per_fee_scale = GRAPHENE_DEFAULT_ACCOUNTS_PER_FEE_SCALE; ///< number of accounts between fee scalings uint8_t account_fee_scale_bitshifts = GRAPHENE_DEFAULT_ACCOUNT_FEE_SCALE_BITSHIFTS; ///< number of times to left bitshift account registration fee at each scaling uint8_t max_authority_depth = GRAPHENE_MAX_SIG_CHECK_DEPTH; - uint8_t witness_schedule_algorithm = GRAPHENE_WITNESS_SHUFFLED_ALGORITHM; ///< 0 shuffled, 1 scheduled + //uint8_t witness_schedule_algorithm = GRAPHENE_WITNESS_SHUFFLED_ALGORITHM; ///< 0 shuffled, 1 scheduled + uint8_t witness_schedule_algorithm = GRAPHENE_WITNESS_SCHEDULED_ALGORITHM; ///< 0 shuffled, 1 scheduled /* rps tournament parameters constraints */ uint32_t min_round_delay = TOURNAMENT_MIN_ROUND_DELAY; ///< miniaml delay between games uint32_t max_round_delay = TOURNAMENT_MAX_ROUND_DELAY; ///< maximal delay between games diff --git a/libraries/chain/include/graphene/chain/witness_scheduler.hpp b/libraries/chain/include/graphene/chain/witness_scheduler.hpp index 5feef417..42dfe149 100644 --- a/libraries/chain/include/graphene/chain/witness_scheduler.hpp +++ b/libraries/chain/include/graphene/chain/witness_scheduler.hpp @@ -24,6 +24,9 @@ #include +// @ROL helpfull dumps when debugging +//#define ROL_DUMP + namespace graphene { namespace chain { //using boost::container::flat_set; @@ -249,6 +252,9 @@ class generic_witness_scheduler template< typename T > void update( const T& revised_set ) { +#ifdef ROL_DUMP + wdump((revised_set)); +#endif set< WitnessID > current_set; set< WitnessID > schedule_set; @@ -293,7 +299,10 @@ class generic_witness_scheduler insert_all( insertion_set ); remove_all( removal_set ); - +#ifdef ROL_DUMP + wdump((_eligible)); + wdump((_schedule)); +#endif return; } @@ -308,8 +317,16 @@ class generic_witness_scheduler bool get_slot( OffsetType offset, WitnessID& wit )const { +#ifdef ROL_DUMP + wdump((_schedule)(_schedule.size())(offset)); +#endif + if (_schedule.empty()) + return false; //@ROL wit is 1.6.0! if( offset >= _schedule.size() ) - return false; + { + wit = _schedule[ 0 ]; + return false; + } wit = _schedule[ offset ]; return true; } @@ -320,6 +337,9 @@ class generic_witness_scheduler */ void reset_schedule( WitnessID first_witness ) { +#ifdef ROL_DUMP + wdump((first_witness)); +#endif _schedule.clear(); for( const WitnessID& wid : _ineligible_no_turn ) { @@ -335,8 +355,11 @@ class generic_witness_scheduler _tokens += _ineligible_waiting_for_token.size(); _ineligible_waiting_for_token.clear(); if( debug ) check_invariant(); - +#ifdef ROL_DUMP + wdump((_eligible)); +#endif auto it = std::find( _eligible.begin(), _eligible.end(), first_witness ); + //@ROL: maybe good idea, when wit is 1.6.0 if ( it == _eligible.end() ) return; assert( it != _eligible.end() ); _schedule.push_back( *it ); diff --git a/libraries/plugins/witness/witness.cpp b/libraries/plugins/witness/witness.cpp index adbca09f..a3a73133 100644 --- a/libraries/plugins/witness/witness.cpp +++ b/libraries/plugins/witness/witness.cpp @@ -228,7 +228,9 @@ block_production_condition::block_production_condition_enum witness_plugin::mayb { chain::database& db = database(); fc::time_point now_fine = graphene::time::now(); - fc::time_point_sec now = now_fine + fc::microseconds( 500000 ); + fc::time_point_sec now = now_fine; + if (db.get_global_properties().parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) + now += fc::microseconds( 500000 ); // If the next block production opportunity is in the present or future, we're synced. if( !_production_enabled ) @@ -258,6 +260,7 @@ block_production_condition::block_production_condition_enum witness_plugin::mayb assert( now > db.head_block_time() ); graphene::chain::witness_id_type scheduled_witness = db.get_scheduled_witness( slot ); + // we must control the witness scheduled to produce the next block. if( _witnesses.find( scheduled_witness ) == _witnesses.end() ) { @@ -266,6 +269,7 @@ block_production_condition::block_production_condition_enum witness_plugin::mayb } fc::time_point_sec scheduled_time = db.get_slot_time( slot ); + wdump((slot)(scheduled_witness)(scheduled_time)(now)); graphene::chain::public_key_type scheduled_key = scheduled_witness( db ).signing_key; auto private_key_itr = _private_keys.find( scheduled_key ); @@ -282,18 +286,28 @@ block_production_condition::block_production_condition_enum witness_plugin::mayb return block_production_condition::low_participation; } + // the local clock must be at least 1 second ahead of head_block_time. + //if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM) + //if( (now - db.head_block_time()).to_seconds() < GRAPHENE_MIN_BLOCK_INTERVAL ) { + // return block_production_condition::local_clock; //Not producing block because head block is less than a second old. + //} + if( llabs((scheduled_time - now).count()) > fc::milliseconds( 500 ).count() ) { capture("scheduled_time", scheduled_time)("now", now); return block_production_condition::lag; } + //if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM) + ilog("Witness ${id} production slot has arrived; generating a block now...", ("id", scheduled_witness)); + auto block = db.generate_block( scheduled_time, scheduled_witness, private_key_itr->second, _production_skip_flags ); + capture("n", block.block_num())("t", block.timestamp)("c", now); fc::async( [this,block](){ p2p_node().broadcast(net::block_message(block)); } );