int main() { // block : current block, block_prev: previous block header block_type block; block_header block_prev; //va chercher le prvious block header dans la db export_bloc("../database",&block_prev); //rempli le block avec les info du header precedent block.version=block_prev.version; // test pour le 2eme bloc // block.timestamp=1231469665; // hash_digest merkl{0x0e,0x3e,0x23,0x57,0xe8,0x06,0xb6,0xcd,0xb1,0xf7,0x0b,0x54,0xc3,0xa3,0xa1,0x7b,0x67,0x14,0xee,0x1f,0x0e,0x68,0xbe,0xbb,0x44,0xa7,0x4b,0x1e,0xfd,0x51,0x20,0x98}; // block.nonce=2573394688; // block.merkle=merkl; block.previous_block_hash = calcul_hash(block_prev); // Ici calcul_hash va etre la fonction couteuse en temps de calcul block.merkle=generate_sha256_hash(uncast_type(block.previous_block_hash)); block.timestamp=block_prev.timestamp; block.bits=block_prev.bits; block.nonce=0; // une fois toutes les info prisent, on peut inserer le block dans la db return addblock("../database", block); }
bool leveldb_chain_keeper::end_slice(size_t slice_begin_index, block_detail_list& sliced_blocks) { leveldb_transaction_batch batch; leveldb_iterator it(db_.block->NewIterator(leveldb::ReadOptions())); data_chunk raw_depth = uncast_type(slice_begin_index); for (it->Seek(slice(raw_depth)); it->Valid(); it->Next()) { block_detail_ptr sliced_block = reconstruct_block(common_, it->value().ToString()); if (!sliced_block) return false; // Add to list of sliced blocks sliced_blocks.push_back(sliced_block); // Make sure to delete hash secondary index too. const hash_digest& block_hash = sliced_block->hash(); // Delete block header... batch.block.Delete(it->key()); // And it's secondary index. batch.block_hash.Delete(slice_block_hash(block_hash)); // Remove txs + spends + addresses too const auto& transactions = sliced_block->actual().transactions; for (const transaction_type& block_tx: transactions) if (!clear_transaction_data(batch, block_tx)) return false; } leveldb::WriteOptions options; // Execute batches. db_.write(batch); return true; }
hash_digest hash_transaction_impl(const message::transaction& tx, uint32_t* hash_type_code) { data_chunk serialized_tx(satoshi_raw_size(tx)); satoshi_save(tx, serialized_tx.begin()); if (hash_type_code != nullptr) extend_data(serialized_tx, uncast_type(*hash_type_code)); return generate_sha256_hash(serialized_tx); }
std::string payment_address::encoded(uint8_t version_byte) const { data_chunk unencoded_address; BITCOIN_ASSERT( type_ == payment_type::pubkey_hash || type_ == payment_type::script_hash); // Type, Hash, Checksum doth make thy address unencoded_address.push_back(version_byte); extend_data(unencoded_address, hash_); uint32_t checksum = generate_sha256_checksum(unencoded_address); extend_data(unencoded_address, uncast_type(checksum)); BITCOIN_ASSERT(unencoded_address.size() == 25); return encode_base58(unencoded_address); }
big_number leveldb_chain_keeper::end_slice_difficulty(size_t slice_begin_index) { big_number total_work = 0; leveldb_iterator it(db_blocks_->NewIterator(leveldb::ReadOptions())); data_chunk raw_depth = uncast_type(slice_begin_index); for (it->Seek(slice(raw_depth)); it->Valid(); it->Next()) { std::stringstream ss; ss.str(it->value().ToString()); protobuf::Block proto_block; proto_block.ParseFromIstream(&ss); total_work += block_work(proto_block.bits()); } return total_work; }
big_number leveldb_chain_keeper::end_slice_difficulty(size_t slice_begin_index) { big_number total_work = 0; leveldb_iterator it(db_.block->NewIterator(leveldb::ReadOptions())); data_chunk raw_depth = uncast_type(slice_begin_index); for (it->Seek(slice(raw_depth)); it->Valid(); it->Next()) { constexpr size_t bits_offset = 4 + 2 * hash_digest_size + 4; BITCOIN_ASSERT(it->value().size() >= 84); // Deserialize only the bits field of block header. std::string raw_bits(it->value().data(), 4); auto deserial = make_deserializer(raw_bits.begin(), raw_bits.end()); uint32_t bits = deserial.read_4_bytes(); // Accumulate the total work. total_work += block_work(bits); } return total_work; }
bool leveldb_common::get_block(leveldb_block_info& blk_info, uint32_t height, bool read_header, bool read_tx_hashes) { // First we try to read the bytes from the database. data_chunk raw_height = uncast_type(height); std::string value; leveldb::Status status = db_.block->Get( leveldb::ReadOptions(), slice(raw_height), &value); if (status.IsNotFound()) return false; else if (!status.ok()) { log_fatal(LOG_BLOCKCHAIN) << "fetch_proto_block(" << height << "): " << status.ToString(); return false; } return deserialize_block(blk_info, value, read_header, read_tx_hashes); }
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; }
bool leveldb_chain_keeper::end_slice(size_t slice_begin_index, block_detail_list& sliced_blocks) { leveldb::WriteBatch blk_batch, blk_hash_batch; leveldb_transaction_batch tx_batch; leveldb_iterator it(db_blocks_->NewIterator(leveldb::ReadOptions())); data_chunk raw_depth = uncast_type(slice_begin_index); for (it->Seek(slice(raw_depth)); it->Valid(); it->Next()) { std::stringstream ss; ss.str(it->value().ToString()); protobuf::Block proto_block; proto_block.ParseFromIstream(&ss); // Convert protobuf block header into actual block block_type sliced_block; if (!reconstruct_block(common_, proto_block, sliced_block)) return false; // Add to list of sliced blocks block_detail_ptr sliced_detail = std::make_shared<block_detail>(sliced_block); sliced_blocks.push_back(sliced_detail); // Make sure to delete hash secondary index too. hash_digest block_hash = hash_block_header(sliced_block); // Delete block header... blk_batch.Delete(it->key()); // And it's secondary index. blk_hash_batch.Delete(slice_block_hash(block_hash)); // Remove txs + spends + addresses too for (const transaction_type& block_tx: sliced_block.transactions) if (!clear_transaction_data(tx_batch, block_tx)) return false; } leveldb::WriteOptions options; // Execute batches. db_blocks_->Write(options, &blk_batch); db_blocks_hash_->Write(options, &blk_hash_batch); db_txs_->Write(options, &tx_batch.tx_batch); db_spends_->Write(options, &tx_batch.spends_batch); db_address_->Write(options, &tx_batch.address_batch); return true; }
void write_network_address(network_address_type addr) { write_8_bytes(addr.services); write_data(addr.ip); write_data(uncast_type(addr.port, true)); }
void write_data_impl(T value) { write_data(uncast_type(value)); }
void readable_data_type::set(uint32_t value) { data_buffer_ = uncast_type(value); prepare(); }