Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2011 The LevelDB Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file. See the AUTHORS file for names of contributors.5#include "leveldb/c.h"7#include <cstdint>8#include <cstdlib>10#include "leveldb/cache.h"11#include "leveldb/comparator.h"12#include "leveldb/db.h"13#include "leveldb/env.h"14#include "leveldb/filter_policy.h"15#include "leveldb/iterator.h"16#include "leveldb/options.h"17#include "leveldb/status.h"18#include "leveldb/write_batch.h"20using leveldb::Cache;21using leveldb::Comparator;22using leveldb::CompressionType;23using leveldb::DB;24using leveldb::Env;25using leveldb::FileLock;26using leveldb::FilterPolicy;27using leveldb::Iterator;28using leveldb::kMajorVersion;29using leveldb::kMinorVersion;30using leveldb::Logger;31using leveldb::NewBloomFilterPolicy;32using leveldb::NewLRUCache;33using leveldb::Options;34using leveldb::RandomAccessFile;35using leveldb::Range;36using leveldb::ReadOptions;37using leveldb::SequentialFile;38using leveldb::Slice;39using leveldb::Snapshot;40using leveldb::Status;41using leveldb::WritableFile;42using leveldb::WriteBatch;43using leveldb::WriteOptions;45extern "C" {47struct leveldb_t {48DB* rep;49};50struct leveldb_iterator_t {51Iterator* rep;52};53struct leveldb_writebatch_t {54WriteBatch rep;55};56struct leveldb_snapshot_t {57const Snapshot* rep;58};59struct leveldb_readoptions_t {60ReadOptions rep;61};62struct leveldb_writeoptions_t {63WriteOptions rep;64};65struct leveldb_options_t {66Options rep;67};68struct leveldb_cache_t {69Cache* rep;70};71struct leveldb_seqfile_t {72SequentialFile* rep;73};74struct leveldb_randomfile_t {75RandomAccessFile* rep;76};77struct leveldb_writablefile_t {78WritableFile* rep;79};80struct leveldb_logger_t {81Logger* rep;82};83struct leveldb_filelock_t {84FileLock* rep;85};87struct leveldb_comparator_t : public Comparator {88~leveldb_comparator_t() override { (*destructor_)(state_); }90int Compare(const Slice& a, const Slice& b) const override {91return (*compare_)(state_, a.data(), a.size(), b.data(), b.size());92}94const char* Name() const override { return (*name_)(state_); }96// No-ops since the C binding does not support key shortening methods.97void FindShortestSeparator(std::string*, const Slice&) const override {}98void FindShortSuccessor(std::string* key) const override {}100void* state_;101void (*destructor_)(void*);102int (*compare_)(void*, const char* a, size_t alen, const char* b,103size_t blen);104const char* (*name_)(void*);105};107struct leveldb_filterpolicy_t : public FilterPolicy {108~leveldb_filterpolicy_t() override { (*destructor_)(state_); }110const char* Name() const override { return (*name_)(state_); }112void CreateFilter(const Slice* keys, int n, std::string* dst) const override {113std::vector<const char*> key_pointers(n);114std::vector<size_t> key_sizes(n);115for (int i = 0; i < n; i++) {116key_pointers[i] = keys[i].data();117key_sizes[i] = keys[i].size();118}119size_t len;120char* filter = (*create_)(state_, &key_pointers[0], &key_sizes[0], n, &len);121dst->append(filter, len);122free(filter);123}125bool KeyMayMatch(const Slice& key, const Slice& filter) const override {126return (*key_match_)(state_, key.data(), key.size(), filter.data(),127filter.size());128}130void* state_;131void (*destructor_)(void*);132const char* (*name_)(void*);133char* (*create_)(void*, const char* const* key_array,134const size_t* key_length_array, int num_keys,135size_t* filter_length);136uint8_t (*key_match_)(void*, const char* key, size_t length,137const char* filter, size_t filter_length);138};140struct leveldb_env_t {141Env* rep;142bool is_default;143};145static bool SaveError(char** errptr, const Status& s) {146assert(errptr != nullptr);147if (s.ok()) {148return false;149} else if (*errptr == nullptr) {150*errptr = strdup(s.ToString().c_str());151} else {152// TODO(sanjay): Merge with existing error?153free(*errptr);154*errptr = strdup(s.ToString().c_str());155}156return true;157}159static char* CopyString(const std::string& str) {160char* result = reinterpret_cast<char*>(malloc(sizeof(char) * str.size()));161memcpy(result, str.data(), sizeof(char) * str.size());162return result;163}165leveldb_t* leveldb_open(const leveldb_options_t* options, const char* name,166char** errptr) {167DB* db;168if (SaveError(errptr, DB::Open(options->rep, std::string(name), &db))) {169return nullptr;170}171leveldb_t* result = new leveldb_t;172result->rep = db;173return result;174}176void leveldb_close(leveldb_t* db) {177delete db->rep;178delete db;179}181void leveldb_put(leveldb_t* db, const leveldb_writeoptions_t* options,182const char* key, size_t keylen, const char* val, size_t vallen,183char** errptr) {184SaveError(errptr,185db->rep->Put(options->rep, Slice(key, keylen), Slice(val, vallen)));186}188void leveldb_delete(leveldb_t* db, const leveldb_writeoptions_t* options,189const char* key, size_t keylen, char** errptr) {190SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen)));191}193void leveldb_write(leveldb_t* db, const leveldb_writeoptions_t* options,194leveldb_writebatch_t* batch, char** errptr) {195SaveError(errptr, db->rep->Write(options->rep, &batch->rep));196}198char* leveldb_get(leveldb_t* db, const leveldb_readoptions_t* options,199const char* key, size_t keylen, size_t* vallen,200char** errptr) {201char* result = nullptr;202std::string tmp;203Status s = db->rep->Get(options->rep, Slice(key, keylen), &tmp);204if (s.ok()) {205*vallen = tmp.size();206result = CopyString(tmp);207} else {208*vallen = 0;209if (!s.IsNotFound()) {210SaveError(errptr, s);211}212}213return result;214}216leveldb_iterator_t* leveldb_create_iterator(217leveldb_t* db, const leveldb_readoptions_t* options) {218leveldb_iterator_t* result = new leveldb_iterator_t;219result->rep = db->rep->NewIterator(options->rep);220return result;221}223const leveldb_snapshot_t* leveldb_create_snapshot(leveldb_t* db) {224leveldb_snapshot_t* result = new leveldb_snapshot_t;225result->rep = db->rep->GetSnapshot();226return result;227}229void leveldb_release_snapshot(leveldb_t* db,230const leveldb_snapshot_t* snapshot) {231db->rep->ReleaseSnapshot(snapshot->rep);232delete snapshot;233}235char* leveldb_property_value(leveldb_t* db, const char* propname) {236std::string tmp;237if (db->rep->GetProperty(Slice(propname), &tmp)) {238// We use strdup() since we expect human readable output.239return strdup(tmp.c_str());240} else {241return nullptr;242}243}245void leveldb_approximate_sizes(leveldb_t* db, int num_ranges,246const char* const* range_start_key,247const size_t* range_start_key_len,248const char* const* range_limit_key,249const size_t* range_limit_key_len,250uint64_t* sizes) {
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.