void wallet_db::remove_transaction( const transaction_id_type& record_id )
 {
    const auto rec = lookup_transaction( record_id );
    if( !rec.valid() ) return;
    remove_item( rec->wallet_record_index );
    transactions.erase( record_id );
 }
Beispiel #2
0
 void WalletDb::remove_transaction( const TransactionIdType& entry_id )
 {
    const auto rec = lookup_transaction( entry_id );
    if( !rec.valid() ) return;
    remove_item( rec->wallet_entry_index );
    transactions.erase( entry_id );
 }
Beispiel #3
0
   void WalletDb::store_transaction( const TransactionData& transaction )
   { try {
       FC_ASSERT( is_open() ,"Wallet not open!");
       FC_ASSERT( transaction.entry_id != TransactionIdType() );
       FC_ASSERT( transaction.is_virtual || transaction.trx.id() != SignedTransaction().id() );

       oWalletTransactionEntry transaction_entry = lookup_transaction( transaction.entry_id );
       if( !transaction_entry.valid() )
           transaction_entry = WalletTransactionEntry();

       TransactionData& temp = *transaction_entry;
       temp = transaction;

       store_and_reload_entry( *transaction_entry );
   } FC_CAPTURE_AND_RETHROW( (transaction) ) }
Beispiel #4
0
   void wallet_db::store_transaction( const transaction_data& transaction )
   { try {
       FC_ASSERT( is_open() );
       FC_ASSERT( transaction.record_id != transaction_id_type() );
       FC_ASSERT( transaction.is_virtual || transaction.trx.id() != signed_transaction().id() );

       owallet_transaction_record transaction_record = lookup_transaction( transaction.record_id );
       if( !transaction_record.valid() )
           transaction_record = wallet_transaction_record();

       transaction_data& temp = *transaction_record;
       temp = transaction;

       store_and_reload_record( *transaction_record );
   } FC_CAPTURE_AND_RETHROW( (transaction) ) }
int
detach_from_network( uint64_t datapath_id, uint32_t vni,
                     overlay_operation_completed_handler callback, void *user_data ) {
  debug( "Detaching a switch %#" PRIx64 " from an overlay network ( vni = %#x, callback = %p, user_data = %p ).",
         datapath_id, vni, callback, user_data );

  char *local_address = NULL;
  char *broadcast_address = NULL;
  uint16_t local_port = 0;
  uint16_t broadcast_port = 0;

  if ( !valid_vni( vni ) ) {
    return OVERLAY_NETWORK_OPERATION_FAILED;
  }

  transaction_entry *entry = lookup_transaction( datapath_id, vni );
  if ( entry != NULL ) {
    if ( entry->datapath_id == datapath_id && entry->vni == vni &&
         entry->operation == OPERATION_DETACH ) {
      debug( "Same operation is in progress ( datapath_id = %#" PRIx64 ", vni = %#x, operation = %#x ).",
             entry->datapath_id, entry->vni, entry->operation );
      return OVERLAY_NETWORK_OPERATION_IN_PROGRESS;
    }
    error( "Another operation is in progress ( datapath_id = %#" PRIx64 ", vni = %#x, operation = %#x ).",
           entry->datapath_id, entry->vni, entry->operation );
    return OVERLAY_NETWORK_OPERATION_FAILED;
  }

  bool ret = add_transaction( datapath_id, vni, OPERATION_DETACH, callback, user_data );
  if ( !ret ) {
    error( "Failed to add a transaction for detaching from a network "
           "( datapath_id = %" PRIx64 ", vni = %#x, callback = %p, user_data = %p ).",
           datapath_id, vni, callback, user_data );
    return OVERLAY_NETWORK_OPERATION_FAILED;
  }

  ret = get_overlay_info( vni, datapath_id, &local_address, &local_port, &broadcast_address, &broadcast_port );
  if ( !ret ) {
    error( "Failed to retrieve overlay network information ( datapath_id = %#" PRIx64 ", vni = %#x ).",
           datapath_id, vni );
    goto error;
  }

  entry = lookup_transaction( datapath_id, vni );
  if ( entry == NULL ) {
    error( "Failed to retrieve transaction entry ( datapath_id = %#" PRIx64 ", vni = %#x ).",
           datapath_id, vni );
    goto error;
  }

  ret = delete_tunnel_from_tep( entry, vni, datapath_id );
  if ( !ret ) {
    if ( entry->n_ongoing_http_requests == 0 ) {
      error( "Failed to delete a tunnel." );
      goto error;
    }
    error( "Failed to delete a tunnel, but http request to delete a tunnel is ongoing." );
  }

  if ( !valid_multicast_address( broadcast_address ) ) {
    if ( ret ) {
      ret = delete_tep_from_packet_reflectors( entry, vni, local_address );
      if ( !ret ) {
        if ( entry->n_ongoing_http_requests == 0 ) {
          error( "Failed to delete TEP from all Packet Reflectors." );
          goto error;
        }
        error( "Failed to delete TEP from some Packet Reflectors." );
      }
    }
  }

  xfree( broadcast_address );
  xfree( local_address );

  debug( "A HTTP request is sent to HTTP client thread ( datapath_id = %" PRIx64 ", vni = %#x, callback = %p, user_data = %p ).",
         datapath_id, vni, callback, user_data );

  return OVERLAY_NETWORK_OPERATION_SUCCEEDED;

error:
  delete_transaction( datapath_id, vni );

  if ( broadcast_address != NULL ) {
    xfree( broadcast_address );
  }
  if ( local_address != NULL ) {
    xfree( local_address );
  }

  return OVERLAY_NETWORK_OPERATION_FAILED;
}
/*!	Returns the writable block data for the requested blockNumber.
	If \a cleared is true, the block is not read from disk; an empty block
	is returned.

	This is the only method to insert a block into a transaction. It makes
	sure that the previous block contents are preserved in that case.
*/
static void*
get_writable_cached_block(block_cache* cache, fssh_off_t blockNumber, fssh_off_t base,
	fssh_off_t length, int32_t transactionID, bool cleared)
{
	TRACE(("get_writable_cached_block(blockNumber = %Ld, transaction = %d)\n",
		blockNumber, transactionID));

	if (blockNumber < 0 || blockNumber >= cache->max_blocks) {
		fssh_panic("get_writable_cached_block: invalid block number %"
			FSSH_B_PRIdOFF " (max %" FSSH_B_PRIdOFF ")", blockNumber,
			cache->max_blocks - 1);
	}

	bool allocated;
	cached_block* block = get_cached_block(cache, blockNumber, &allocated,
		!cleared);
	if (block == NULL)
		return NULL;

	block->discard = false;

	// if there is no transaction support, we just return the current block
	if (transactionID == -1) {
		if (cleared)
			fssh_memset(block->current_data, 0, cache->block_size);

		block->is_dirty = true;
			// mark the block as dirty

		return block->current_data;
	}

	cache_transaction* transaction = block->transaction;

	if (transaction != NULL && transaction->id != transactionID) {
		// TODO: we have to wait here until the other transaction is done.
		//	Maybe we should even panic, since we can't prevent any deadlocks.
		fssh_panic("get_writable_cached_block(): asked to get busy writable block (transaction %d)\n", (int)transaction->id);
		put_cached_block(cache, block);
		return NULL;
	}
	if (transaction == NULL && transactionID != -1) {
		// get new transaction
		transaction = lookup_transaction(cache, transactionID);
		if (transaction == NULL) {
			fssh_panic("get_writable_cached_block(): invalid transaction %d!\n",
				(int)transactionID);
			put_cached_block(cache, block);
			return NULL;
		}
		if (!transaction->open) {
			fssh_panic("get_writable_cached_block(): transaction already done!\n");
			put_cached_block(cache, block);
			return NULL;
		}

		block->transaction = transaction;

		// attach the block to the transaction block list
		block->transaction_next = transaction->first_block;
		transaction->first_block = block;
		transaction->num_blocks++;
	}

	bool wasUnchanged = block->original_data == NULL
		|| block->previous_transaction != NULL;

	if (!(allocated && cleared) && block->original_data == NULL) {
		// we already have data, so we need to preserve it
		block->original_data = cache->Allocate();
		if (block->original_data == NULL) {
			FATAL(("could not allocate original_data\n"));
			put_cached_block(cache, block);
			return NULL;
		}

		fssh_memcpy(block->original_data, block->current_data, cache->block_size);
	}
	if (block->parent_data == block->current_data) {
		// remember any previous contents for the parent transaction
		block->parent_data = cache->Allocate();
		if (block->parent_data == NULL) {
			// TODO: maybe we should just continue the current transaction in this case...
			FATAL(("could not allocate parent\n"));
			put_cached_block(cache, block);
			return NULL;
		}

		fssh_memcpy(block->parent_data, block->current_data, cache->block_size);
		transaction->sub_num_blocks++;
	} else if (transaction != NULL && transaction->has_sub_transaction
		&& block->parent_data == NULL && wasUnchanged)
		transaction->sub_num_blocks++;

	if (cleared)
		fssh_memset(block->current_data, 0, cache->block_size);

	block->is_dirty = true;

	return block->current_data;
}