diff --git a/libraries/chain/db_witness_schedule.cpp b/libraries/chain/db_witness_schedule.cpp index 3c4a4710..1b3d951a 100644 --- a/libraries/chain/db_witness_schedule.cpp +++ b/libraries/chain/db_witness_schedule.cpp @@ -62,17 +62,32 @@ fc::time_point_sec database::get_slot_time(uint32_t slot_num)const return fc::time_point_sec(); auto interval = block_interval(); + const dynamic_global_property_object& dpo = get_dynamic_global_properties(); if( head_block_num() == 0 ) { // n.b. first block is at genesis_time plus one block interval - fc::time_point_sec genesis_time = get_dynamic_global_properties().time; + fc::time_point_sec genesis_time = dpo.time; return genesis_time + slot_num * interval; } auto head_block_abs_slot = head_block_time().sec_since_epoch() / interval; - fc::time_point_sec first_slot_time(head_block_abs_slot * interval); - return first_slot_time + slot_num * interval; + fc::time_point_sec head_slot_time(head_block_abs_slot * interval); + + const global_property_object& gpo = get_global_properties(); + + // "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 + ; } uint32_t database::get_slot_at_time(fc::time_point_sec when)const diff --git a/libraries/chain/include/graphene/chain/config.hpp b/libraries/chain/include/graphene/chain/config.hpp index 75e6f54b..9940ae79 100644 --- a/libraries/chain/include/graphene/chain/config.hpp +++ b/libraries/chain/include/graphene/chain/config.hpp @@ -46,6 +46,7 @@ #define GRAPHENE_DEFAULT_MAX_BLOCK_SIZE (GRAPHENE_DEFAULT_MAX_TRANSACTION_SIZE*GRAPHENE_DEFAULT_BLOCK_INTERVAL*200000) #define GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION (60*60*24) // seconds, aka: 1 day #define GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL (60*60*24) // seconds, aka: 1 day +#define GRAPHENE_DEFAULT_MAINTENANCE_SKIP_SLOTS 3 // number of slots to skip for maintenance interval #define GRAPHENE_DEFAULT_MAX_EXPIRATION_SEC (60*60) // 1 hour #define GRAPHENE_MIN_UNDO_HISTORY 10 diff --git a/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp b/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp index b1854109..ac91d777 100644 --- a/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp +++ b/libraries/chain/include/graphene/chain/protocol/chain_parameters.hpp @@ -37,6 +37,7 @@ namespace graphene { namespace chain { smart_ref current_fees; ///< current schedule of fees uint8_t block_interval = GRAPHENE_DEFAULT_BLOCK_INTERVAL; ///< interval in seconds between blocks uint32_t maintenance_interval = GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL; ///< interval in sections between blockchain maintenance events + uint8_t maintenance_skip_slots = GRAPHENE_DEFAULT_MAINTENANCE_SKIP_SLOTS; ///< number of block_intervals to skip at maintenance time uint32_t committee_proposal_review_period = GRAPHENE_DEFAULT_COMMITTEE_PROPOSAL_REVIEW_PERIOD_SEC; ///< minimum time in seconds that a proposed transaction requiring committee authority may not be signed, prior to expiration uint32_t maximum_transaction_size = GRAPHENE_DEFAULT_MAX_TRANSACTION_SIZE; ///< maximum allowable size in bytes for a transaction uint32_t maximum_block_size = GRAPHENE_DEFAULT_MAX_BLOCK_SIZE; ///< maximum allowable size in bytes for a block @@ -75,6 +76,7 @@ FC_REFLECT( graphene::chain::chain_parameters, (current_fees) (block_interval) (maintenance_interval) + (maintenance_skip_slots) (committee_proposal_review_period) (maximum_transaction_size) (maximum_block_size) diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index 5207514f..bfc46f62 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -974,7 +974,7 @@ void set_expiration( const database& db, transaction& tx ) { const chain_parameters& params = db.get_global_properties().parameters; tx.set_reference_block(db.head_block_id()); - tx.set_expiration( db.head_block_time() + fc::seconds( params.block_interval * 3 ) ); + tx.set_expiration( db.head_block_time() + fc::seconds( params.block_interval * (params.maintenance_skip_slots + 1) * 3 ) ); return; }