@@ -331,10 +331,19 @@ signed_block database::_generate_block(
331
331
witness_id_type scheduled_witness = get_scheduled_witness ( slot_num );
332
332
FC_ASSERT ( scheduled_witness == witness_id );
333
333
334
- const auto & witness_obj = witness_id (*this );
335
-
336
334
if ( !(skip & skip_witness_signature) )
337
- FC_ASSERT ( witness_obj.signing_key == block_signing_private_key.get_public_key () );
335
+ {
336
+ auto signing_key = find_witness_key_from_cache ( witness_id );
337
+ if ( signing_key.valid () ) // witness in cache
338
+ {
339
+ FC_ASSERT ( *signing_key == block_signing_private_key.get_public_key () );
340
+ }
341
+ else // witness not in cache
342
+ {
343
+ const auto & witness_obj = witness_id (*this );
344
+ FC_ASSERT ( witness_obj.signing_key == block_signing_private_key.get_public_key () );
345
+ }
346
+ }
338
347
339
348
static const size_t max_block_header_size = fc::raw::pack_size ( signed_block_header () ) + 4 ;
340
349
auto maximum_block_size = get_global_properties ().parameters .maximum_block_size ;
@@ -353,11 +362,12 @@ signed_block database::_generate_block(
353
362
// the value of the "when" variable is known, which means we need to
354
363
// re-apply pending transactions in this method.
355
364
//
365
+
366
+ // pop pending state (reset to head block state)
356
367
_pending_tx_session.reset ();
357
368
_pending_tx_session = _undo_db.start_undo_session ();
358
369
359
370
uint64_t postponed_tx_count = 0 ;
360
- // pop pending state (reset to head block state)
361
371
for ( const processed_transaction& tx : _pending_tx )
362
372
{
363
373
size_t new_total_size = total_block_size + fc::raw::pack_size ( tx );
@@ -436,6 +446,9 @@ void database::pop_block()
436
446
437
447
_popped_tx.insert ( _popped_tx.begin (), head_block->transactions .begin (), head_block->transactions .end () );
438
448
449
+ // Note: for better performance, can move this to where calls pop_block();
450
+ refresh_witness_key_cache ();
451
+
439
452
} FC_CAPTURE_AND_RETHROW () }
440
453
441
454
void database::clear_pending ()
@@ -511,6 +524,9 @@ void database::_apply_block( const signed_block& next_block )
511
524
512
525
_issue_453_affected_assets.clear ();
513
526
527
+ if ( !(skip&skip_witness_key_cache_update) )
528
+ skip |= force_witness_key_cache_update;
529
+
514
530
for ( const auto & trx : next_block.transactions )
515
531
{
516
532
/* We do not need to push the undo state for each transaction
@@ -699,4 +715,43 @@ bool database::before_last_checkpoint()const
699
715
return (_checkpoints.size () > 0 ) && (_checkpoints.rbegin ()->first >= head_block_num ());
700
716
}
701
717
718
+ void database::init_witness_key_cache ( std::set<witness_id_type>& witnesses )
719
+ {
720
+ for ( const witness_id_type& wit : witnesses )
721
+ _witness_key_cache[wit]; // add it
722
+ }
723
+
724
+ void database::update_witness_key_cache ( witness_id_type wit, const public_key_type& pub_key )
725
+ {
726
+ if ( _witness_key_cache.empty () )
727
+ return ;
728
+ uint32_t skip = get_node_properties ().skip_flags ;
729
+ if ( (skip&force_witness_key_cache_update) )
730
+ {
731
+ auto itr = _witness_key_cache.find ( wit );
732
+ if ( itr != _witness_key_cache.end () )
733
+ itr->second = pub_key;
734
+ }
735
+ }
736
+
737
+ void database::refresh_witness_key_cache ()
738
+ {
739
+ for ( auto & wit_key : _witness_key_cache )
740
+ {
741
+ const witness_object* wit_obj = find ( wit_key.first );
742
+ if ( wit_obj )
743
+ wit_key.second = wit_obj->signing_key ;
744
+ else
745
+ wit_key.second .reset ();
746
+ }
747
+ }
748
+
749
+ optional<public_key_type> database::find_witness_key_from_cache ( witness_id_type wit ) const
750
+ {
751
+ auto itr = _witness_key_cache.find ( wit );
752
+ if ( itr != _witness_key_cache.end () )
753
+ return itr->second ;
754
+ return optional<public_key_type>();
755
+ }
756
+
702
757
} }
0 commit comments