transaction_builder& transaction_builder::cancel_market_order( const order_id_type& order_id )
{   try {
        const auto order = _wimpl->_blockchain->get_market_order( order_id );
        if( !order.valid() )
            FC_THROW_EXCEPTION( unknown_market_order, "Cannot find that market order!" );

        const auto owner_address = order->get_owner();
        const auto owner_key_record = _wimpl->_wallet_db.lookup_key( owner_address );
        if( !owner_key_record.valid() || !owner_key_record->has_private_key() )
            FC_THROW_EXCEPTION( private_key_not_found, "Cannot find the private key for that market order!" );

        const auto account_record = _wimpl->_wallet_db.lookup_account( owner_key_record->account_address );
        FC_ASSERT( account_record.valid() );

        asset balance = order->get_balance();
        if( balance.amount == 0 ) FC_CAPTURE_AND_THROW( zero_amount, (order) );

        switch( order_type_enum( order->type ) )
        {
        case ask_order:
            trx.ask( -balance, order->market_index.order_price, owner_address );
            break;
        case bid_order:
            trx.bid( -balance, order->market_index.order_price, owner_address );
            break;
        case short_order:
            trx.short_sell( -balance, order->market_index.order_price, owner_address );
            break;
        default:
            FC_THROW_EXCEPTION( invalid_cancel, "You cannot cancel this type of order!" );
            break;
        }

        //Credit this account the cancel proceeds
        credit_balance(account_record->owner_address(), balance);
        //Set order key for this account if not already set
        if( order_keys.find(account_record->owner_address()) == order_keys.end() )
        {
            const oasset_record asset_record = _wimpl->_blockchain->get_asset_record( balance.asset_id );
            FC_ASSERT( asset_record.valid() );
            if( asset_record->flag_is_active( asset_record::restricted_accounts ) )
                order_keys[ account_record->owner_address() ] = account_record->active_key();
            else
                order_keys[ account_record->owner_address() ] = owner_key_record->public_key;
        }

        auto entry = ledger_entry();
        entry.from_account = owner_key_record->public_key;
        entry.to_account = account_record->owner_key;
        entry.amount = balance;
        entry.memo = "cancel " + order->get_small_id();

        transaction_record.is_market = true;
        transaction_record.ledger_entries.push_back( entry );

        required_signatures.insert( owner_address );
        return *this;
    }
    FC_CAPTURE_AND_RETHROW( (order_id) )
}
transaction_builder& transaction_builder::update_asset( const string& symbol,
                                                        const optional<string>& name,
                                                        const optional<string>& description,
                                                        const optional<variant>& public_data,
                                                        const optional<double>& maximum_share_supply,
                                                        const optional<uint64_t>& precision )
{ try {
    const oasset_record asset_record = _wimpl->_blockchain->get_asset_record( symbol );
    FC_ASSERT( asset_record.valid() );

    const oaccount_record issuer_account_record = _wimpl->_blockchain->get_account_record( asset_record->issuer_account_id );
    if( !issuer_account_record.valid() )
        FC_THROW_EXCEPTION( unknown_account, "Unknown issuer account id!" );

    trx.update_asset( asset_record->id, name, description, public_data, maximum_share_supply, precision );
    deduct_balance( issuer_account_record->active_key(), asset() );

    ledger_entry entry;
    entry.from_account = issuer_account_record->active_key();
    entry.to_account = issuer_account_record->active_key();
    entry.memo = "update " + symbol + " asset";

    transaction_record.ledger_entries.push_back( entry );

    required_signatures.insert( issuer_account_record->active_key() );
    return *this;
} FC_CAPTURE_AND_RETHROW( (symbol)(name)(description)(public_data)(maximum_share_supply)(precision) ) }
transaction_builder& transaction_builder::submit_bid(const wallet_account_record& from_account,
        const asset& real_quantity,
        const price& quote_price)
{   try {
        validate_market(quote_price.quote_asset_id, quote_price.base_asset_id);
        asset cost;
        if( real_quantity.asset_id == quote_price.quote_asset_id )
            cost = real_quantity;
        else
        {
            cost = real_quantity * quote_price;
            FC_ASSERT(cost.asset_id == quote_price.quote_asset_id);
        }

        const oasset_record base_asset_record = _wimpl->_blockchain->get_asset_record( quote_price.base_asset_id );
        FC_ASSERT( base_asset_record.valid() );

        public_key_type order_key;
        if( base_asset_record->flag_is_active( asset_record::restricted_accounts ) )
            order_key = from_account.active_key();
        else
            order_key = order_key_for_account( from_account.owner_address(), from_account.name );

        order_keys[ from_account.owner_address() ] = order_key;

        //Charge this account for the bid
        deduct_balance(from_account.owner_address(), cost);
        trx.bid(cost, quote_price, order_key);

        if( trx.expiration == time_point_sec() )
            trx.expiration = blockchain::now() + WALLET_DEFAULT_MARKET_TRANSACTION_EXPIRATION_SEC;

        auto entry = ledger_entry();
        entry.from_account = from_account.owner_key;
        entry.to_account = order_key;
        entry.amount = cost;
        entry.memo = "buy " + _wimpl->_blockchain->get_asset_symbol(quote_price.base_asset_id) +
                     " @ " + _wimpl->_blockchain->to_pretty_price(quote_price);

        transaction_record.is_market = true;
        transaction_record.ledger_entries.push_back(entry);

        required_signatures.insert(order_key);
        return *this;
    }
    FC_CAPTURE_AND_RETHROW( (from_account.name)(real_quantity)(quote_price) )
}
   void deposit_operation::evaluate( transaction_evaluation_state& eval_state )const
   { try {
       if( this->amount <= 0 )
          FC_CAPTURE_AND_THROW( negative_deposit, (amount) );

       switch( withdraw_condition_types( this->condition.type ) )
       {
          case withdraw_signature_type:
          case withdraw_multisig_type:
          case withdraw_escrow_type:
             break;
          default:
             FC_CAPTURE_AND_THROW( invalid_withdraw_condition, (*this) );
       }

       const balance_id_type deposit_balance_id = this->balance_id();

       obalance_record cur_record = eval_state.pending_state()->get_balance_record( deposit_balance_id );
       if( !cur_record.valid() )
       {
          cur_record = balance_record( this->condition );
          if( this->condition.type == withdraw_escrow_type )
             cur_record->meta_data = variant_object("creating_transaction_id", eval_state.trx.id() );
       }

       if( cur_record->balance == 0 )
       {
          cur_record->deposit_date = eval_state.pending_state()->now();
       }
       else
       {
          fc::uint128 old_sec_since_epoch( cur_record->deposit_date.sec_since_epoch() );
          fc::uint128 new_sec_since_epoch( eval_state.pending_state()->now().sec_since_epoch() );

          fc::uint128 avg = (old_sec_since_epoch * cur_record->balance) + (new_sec_since_epoch * this->amount);
          avg /= (cur_record->balance + this->amount);

          cur_record->deposit_date = time_point_sec( avg.to_integer() );
       }

       cur_record->balance += this->amount;
       eval_state.sub_balance( asset( this->amount, cur_record->asset_id() ) );

       if( cur_record->condition.asset_id == 0 && cur_record->condition.slate_id )
          eval_state.adjust_vote( cur_record->condition.slate_id, this->amount );

       cur_record->last_update = eval_state.pending_state()->now();

       const oasset_record asset_rec = eval_state.pending_state()->get_asset_record( cur_record->condition.asset_id );
       FC_ASSERT( asset_rec.valid() );

       if( asset_rec->is_market_issued() )
       {
           FC_ASSERT( cur_record->condition.slate_id == 0 );
       }

       const auto& owners = cur_record->owners();
       for( const address& owner : owners )
       {
           FC_ASSERT( asset_rec->address_is_whitelisted( owner ) );
       }

       eval_state.pending_state()->store_balance_record( *cur_record );
   } FC_CAPTURE_AND_RETHROW( (*this) ) }