void fire_delegate_operation::evaluate( transaction_evaluation_state& eval_state )
   { try {
       auto delegate_record = eval_state._current_state->get_account_record( this->delegate_id );
       if( !delegate_record ) FC_CAPTURE_AND_THROW( unknown_account_id, (delegate_id) );
       if( !delegate_record->is_delegate() ) FC_CAPTURE_AND_THROW( not_a_delegate, (delegate_record) );

       switch( (fire_delegate_operation::reason_type)this->reason )
       {
          case fire_delegate_operation::multiple_blocks_signed:
          {
             auto proof = fc::raw::unpack<multiple_block_proof>( this->data );

             FC_ASSERT( proof.first.id() != proof.second.id() );
             FC_ASSERT( proof.first.timestamp == proof.second.timestamp )
             FC_ASSERT( proof.first.signee() == proof.second.signee() )
             FC_ASSERT( proof.first.validate_signee( delegate_record->active_key() ) );

             // then fire the delegate
             // this maintains the invariant of total votes == total shares
             delegate_record->adjust_votes_against( delegate_record->votes_for() );
             delegate_record->adjust_votes_for( -delegate_record->votes_for() );
             eval_state._current_state->store_account_record( *delegate_record );
             break;
          }
          case fire_delegate_operation::invalid_testimony:
          {
             auto testimony = fc::raw::unpack<signed_delegate_testimony>( this->data );

             bool is_delegates_key = false;
             auto signee = testimony.signee();
             for( auto key : delegate_record->active_key_history )
             {
                if( signee == key.second )
                {
                   is_delegates_key = true;
                   break;
                }
             }
             if( !is_delegates_key ) FC_CAPTURE_AND_THROW( not_a_delegate_signature, (signee)(delegate_record) );

             auto trx_loc = eval_state._current_state->get_transaction( testimony.transaction_id );
             // delegate said it was valid, but it is invalid
             if( !trx_loc && testimony.valid )
             {
                delegate_record->adjust_votes_against( delegate_record->votes_for() );
                delegate_record->adjust_votes_for( -delegate_record->votes_for() );
                eval_state._current_state->store_account_record( *delegate_record );
             }
             else
             {
                FC_CAPTURE_AND_THROW( invalid_fire_operation );
             }
             break;
          }
       }
   } FC_CAPTURE_AND_RETHROW( (*this) ) }
Пример #2
0
   void transaction_evaluation_state::update_delegate_votes()
   {
      auto asset_rec = _current_state->get_asset_record( BASE_ASSET_ID );
      auto max_votes = 2 * (asset_rec->current_share_supply / BTS_BLOCKCHAIN_NUM_DELEGATES);

      for( auto del_vote : net_delegate_votes )
      {
         auto del_rec = _current_state->get_name_record( del_vote.first );
         FC_ASSERT( !!del_rec );
         del_rec->adjust_votes_for( del_vote.second.votes_for );
         del_rec->adjust_votes_against( del_vote.second.votes_against );
         if( del_rec->votes_for() > max_votes || del_rec->votes_against() > max_votes )
            fail( BTS_DELEGATE_MAX_VOTE_LIMIT, fc::variant() );
         _current_state->store_name_record( *del_rec );
      }
   }