[bitshares/bitshares-core] Fix issue #125: sign block with old key if signing key updated in same block (#1203)

pmconrad commented on this pull request.

> private:
void _apply_block( const signed_block& next_block );
processed_transaction _apply_transaction( const signed_transaction& trx );
void _cancel_bids_and_revive_mpa( const asset_object& bitasset, const asset_bitasset_data_object& bad );

+ /// For tracking signing keys of specified witnesses, only update when applied a block or popped a block
+ flat_map< witness_id_type, optional > _witness_key_cache;

IMO it is a bad idea to introduce block-dependent state in database that is not covered by object_db. This state must be maintained manually, which is fragile. I think the problem at hand can be solved in a more simple way.

> @@ -250,7 +253,7 @@ block_production_condition::block_production_condition_enum witness_plugin::mayb
}

fc::time_point_sec scheduled_time = db.get_slot_time( slot );
— graphene::chain::public_key_type scheduled_key = scheduled_witness( db ).signing_key;
+ graphene::chain::public_key_type scheduled_key = *db.find_witness_key_from_cache( scheduled_witness ); // should be valid

I think instead of using the cache, witness_plugin could simply connect to the «database::applied_block« signal and use that to retrieve the latest keys of the witness(es) it is interested in.

> if( !(skip & skip_witness_signature) )
— FC_ASSERT( witness_obj.signing_key == block_signing_private_key.get_public_key() );
+ {
+ auto signing_key = find_witness_key_from_cache( witness_id );

Instead of using the cache, simply move the existing FC_ASSERT down a couple of lines, after «_pending_tx_session.reset();«