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 ); }
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 ); }
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) ) }
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; }