bool bdb_common::save_block(txn_guard_ptr txn, uint32_t depth, const message::block& serial_block) { protobuf::Block proto_block = block_header_to_protobuf(depth, serial_block); for (uint32_t tx_index = 0; tx_index < serial_block.transactions.size(); ++tx_index) { const message::transaction& block_tx = serial_block.transactions[tx_index]; const hash_digest& tx_hash = hash_transaction(block_tx); if (!save_transaction(txn, depth, tx_index, tx_hash, block_tx)) { log_fatal() << "Could not save transaction"; return false; } proto_block.add_transactions( std::string(tx_hash.begin(), tx_hash.end())); } std::ostringstream oss; if (!proto_block.SerializeToOstream(&oss)) { log_fatal() << "Protobuf serialization failed"; return false; } readable_data_type key, value; key.set(depth); value.set(oss.str()); if (db_blocks_->put(txn->get(), key.get(), value.get(), 0) != 0) { log_fatal() << "bdb put() failed"; return false; } return true; }
static gboolean commit_transaction( GncSqlBackend* be, QofInstance* inst ) { g_return_val_if_fail( be != NULL, FALSE ); g_return_val_if_fail( inst != NULL, FALSE ); g_return_val_if_fail( GNC_IS_TRANS(inst), FALSE ); return save_transaction( be, GNC_TRANS(inst), /* do_save_splits */FALSE ); }
bool leveldb_common::save_block( uint32_t height, const block_type& serial_block) { leveldb_transaction_batch batch; // Write block header + tx hashes data_chunk raw_block_data( 80 + 4 + serial_block.transactions.size() * hash_digest_size); // Downcast to base header type so serializer selects that. auto header_end = satoshi_save( serial_block.header, raw_block_data.begin()); BITCOIN_ASSERT(std::distance(raw_block_data.begin(), header_end) == 80); auto serial_hashes = make_serializer(header_end); // Write the number of transactions... serial_hashes.write_4_bytes(serial_block.transactions.size()); // ... And now the tx themselves. for (uint32_t tx_index = 0; tx_index < serial_block.transactions.size(); ++tx_index) { const transaction_type& block_tx = serial_block.transactions[tx_index]; const hash_digest& tx_hash = hash_transaction(block_tx); if (!save_transaction(batch, height, tx_index, tx_hash, block_tx)) { log_fatal(LOG_BLOCKCHAIN) << "Could not save transaction"; return false; } serial_hashes.write_hash(tx_hash); } BITCOIN_ASSERT(serial_hashes.iterator() == raw_block_data.begin() + 80 + 4 + serial_block.transactions.size() * hash_digest_size); data_chunk raw_height = uncast_type(height); hash_digest block_hash = hash_block_header(serial_block.header); // Write block header batch.block.Put(slice(raw_height), slice(raw_block_data)); batch.block_hash.Put(slice_block_hash(block_hash), slice(raw_height)); // Execute batches. db_.write(batch); // Sync stealth database. db_stealth_->sync(height); return true; }