@@ -352,10 +352,19 @@ signed_block database::_generate_block(
352
352
witness_id_type scheduled_witness = get_scheduled_witness ( slot_num );
353
353
FC_ASSERT ( scheduled_witness == witness_id );
354
354
355
- const auto & witness_obj = witness_id (*this );
356
-
357
355
if ( !(skip & skip_witness_signature) )
358
- FC_ASSERT ( witness_obj.signing_key == block_signing_private_key.get_public_key () );
356
+ {
357
+ auto signing_key = find_witness_key_from_cache ( witness_id );
358
+ if ( signing_key.valid () ) // witness in cache
359
+ {
360
+ FC_ASSERT ( *signing_key == block_signing_private_key.get_public_key () );
361
+ }
362
+ else // witness not in cache
363
+ {
364
+ const auto & witness_obj = witness_id (*this );
365
+ FC_ASSERT ( witness_obj.signing_key == block_signing_private_key.get_public_key () );
366
+ }
367
+ }
359
368
360
369
static const size_t max_block_header_size = fc::raw::pack_size ( signed_block_header () ) + 4 ;
361
370
auto maximum_block_size = get_global_properties ().parameters .maximum_block_size ;
@@ -374,11 +383,12 @@ signed_block database::_generate_block(
374
383
// the value of the "when" variable is known, which means we need to
375
384
// re-apply pending transactions in this method.
376
385
//
386
+
387
+ // pop pending state (reset to head block state)
377
388
_pending_tx_session.reset ();
378
389
_pending_tx_session = _undo_db.start_undo_session ();
379
390
380
391
uint64_t postponed_tx_count = 0 ;
381
- // pop pending state (reset to head block state)
382
392
for ( const processed_transaction& tx : _pending_tx )
383
393
{
384
394
size_t new_total_size = total_block_size + fc::raw::pack_size ( tx );
@@ -457,6 +467,9 @@ void database::pop_block()
457
467
458
468
_popped_tx.insert ( _popped_tx.begin (), head_block->transactions .begin (), head_block->transactions .end () );
459
469
470
+ // Note: for better performance, can move this to where calls pop_block();
471
+ refresh_witness_key_cache ();
472
+
460
473
} FC_CAPTURE_AND_RETHROW () }
461
474
462
475
void database::clear_pending ()
@@ -532,6 +545,9 @@ void database::_apply_block( const signed_block& next_block )
532
545
533
546
_issue_453_affected_assets.clear ();
534
547
548
+ if ( !(skip&skip_witness_key_cache_update) )
549
+ skip |= force_witness_key_cache_update;
550
+
535
551
for ( const auto & trx : next_block.transactions )
536
552
{
537
553
/* We do not need to push the undo state for each transaction
@@ -720,4 +736,43 @@ bool database::before_last_checkpoint()const
720
736
return (_checkpoints.size () > 0 ) && (_checkpoints.rbegin ()->first >= head_block_num ());
721
737
}
722
738
739
+ void database::init_witness_key_cache ( std::set<witness_id_type>& witnesses )
740
+ {
741
+ for ( const witness_id_type& wit : witnesses )
742
+ _witness_key_cache[wit]; // add it
743
+ }
744
+
745
+ void database::update_witness_key_cache ( witness_id_type wit, const public_key_type& pub_key )
746
+ {
747
+ if ( _witness_key_cache.empty () )
748
+ return ;
749
+ uint32_t skip = get_node_properties ().skip_flags ;
750
+ if ( (skip&force_witness_key_cache_update) )
751
+ {
752
+ auto itr = _witness_key_cache.find ( wit );
753
+ if ( itr != _witness_key_cache.end () )
754
+ itr->second = pub_key;
755
+ }
756
+ }
757
+
758
+ void database::refresh_witness_key_cache ()
759
+ {
760
+ for ( auto & wit_key : _witness_key_cache )
761
+ {
762
+ const witness_object* wit_obj = find ( wit_key.first );
763
+ if ( wit_obj )
764
+ wit_key.second = wit_obj->signing_key ;
765
+ else
766
+ wit_key.second .reset ();
767
+ }
768
+ }
769
+
770
+ optional<public_key_type> database::find_witness_key_from_cache ( witness_id_type wit ) const
771
+ {
772
+ auto itr = _witness_key_cache.find ( wit );
773
+ if ( itr != _witness_key_cache.end () )
774
+ return itr->second ;
775
+ return optional<public_key_type>();
776
+ }
777
+
723
778
} }
0 commit comments