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.2Use of this source code is governed by a BSD-style license that can be3found in the LICENSE file. See the AUTHORS file for names of contributors. */5#include "leveldb/c.h"7#include <stddef.h>8#include <stdio.h>9#include <stdlib.h>10#include <string.h>12const char* phase = "";14static void StartPhase(const char* name) {15fprintf(stderr, "=== Test %s\n", name);16phase = name;17}19#define CheckNoError(err) \20if ((err) != NULL) { \21fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, (err)); \22abort(); \23}25#define CheckCondition(cond) \26if (!(cond)) { \27fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, #cond); \28abort(); \29}31static void CheckEqual(const char* expected, const char* v, size_t n) {32if (expected == NULL && v == NULL) {33// ok34} else if (expected != NULL && v != NULL && n == strlen(expected) &&35memcmp(expected, v, n) == 0) {36// ok37return;38} else {39fprintf(stderr, "%s: expected '%s', got '%s'\n",40phase,41(expected ? expected : "(null)"),42(v ? v : "(null"));43abort();44}45}47static void Free(char** ptr) {48if (*ptr) {49free(*ptr);50*ptr = NULL;51}52}54static void CheckGet(55leveldb_t* db,56const leveldb_readoptions_t* options,57const char* key,58const char* expected) {59char* err = NULL;60size_t val_len;61char* val;62val = leveldb_get(db, options, key, strlen(key), &val_len, &err);63CheckNoError(err);64CheckEqual(expected, val, val_len);65Free(&val);66}68static void CheckIter(leveldb_iterator_t* iter,69const char* key, const char* val) {70size_t len;71const char* str;72str = leveldb_iter_key(iter, &len);73CheckEqual(key, str, len);74str = leveldb_iter_value(iter, &len);75CheckEqual(val, str, len);76}78// Callback from leveldb_writebatch_iterate()79static void CheckPut(void* ptr,80const char* k, size_t klen,81const char* v, size_t vlen) {82int* state = (int*) ptr;83CheckCondition(*state < 2);84switch (*state) {85case 0:86CheckEqual("bar", k, klen);87CheckEqual("b", v, vlen);88break;89case 1:90CheckEqual("box", k, klen);91CheckEqual("c", v, vlen);92break;93}94(*state)++;95}97// Callback from leveldb_writebatch_iterate()98static void CheckDel(void* ptr, const char* k, size_t klen) {99int* state = (int*) ptr;100CheckCondition(*state == 2);101CheckEqual("bar", k, klen);102(*state)++;103}105static void CmpDestroy(void* arg) { }107static int CmpCompare(void* arg, const char* a, size_t alen,108const char* b, size_t blen) {109int n = (alen < blen) ? alen : blen;110int r = memcmp(a, b, n);111if (r == 0) {112if (alen < blen) r = -1;113else if (alen > blen) r = +1;114}115return r;116}118static const char* CmpName(void* arg) {119return "foo";120}122// Custom filter policy123static uint8_t fake_filter_result = 1;124static void FilterDestroy(void* arg) { }125static const char* FilterName(void* arg) {126return "TestFilter";127}128static char* FilterCreate(129void* arg,130const char* const* key_array, const size_t* key_length_array,131int num_keys,132size_t* filter_length) {133*filter_length = 4;134char* result = malloc(4);135memcpy(result, "fake", 4);136return result;137}138uint8_t FilterKeyMatch(void* arg, const char* key, size_t length,139const char* filter, size_t filter_length) {140CheckCondition(filter_length == 4);141CheckCondition(memcmp(filter, "fake", 4) == 0);142return fake_filter_result;143}145int main(int argc, char** argv) {146leveldb_t* db;147leveldb_comparator_t* cmp;148leveldb_cache_t* cache;149leveldb_env_t* env;150leveldb_options_t* options;151leveldb_readoptions_t* roptions;152leveldb_writeoptions_t* woptions;153char* dbname;154char* err = NULL;155int run = -1;157CheckCondition(leveldb_major_version() >= 1);158CheckCondition(leveldb_minor_version() >= 1);160StartPhase("create_objects");161cmp = leveldb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName);162env = leveldb_create_default_env();163cache = leveldb_cache_create_lru(100000);164dbname = leveldb_env_get_test_directory(env);165CheckCondition(dbname != NULL);167options = leveldb_options_create();168leveldb_options_set_comparator(options, cmp);169leveldb_options_set_error_if_exists(options, 1);170leveldb_options_set_cache(options, cache);171leveldb_options_set_env(options, env);172leveldb_options_set_info_log(options, NULL);173leveldb_options_set_write_buffer_size(options, 100000);174leveldb_options_set_paranoid_checks(options, 1);175leveldb_options_set_max_open_files(options, 10);176leveldb_options_set_block_size(options, 1024);177leveldb_options_set_block_restart_interval(options, 8);178leveldb_options_set_max_file_size(options, 3 << 20);179leveldb_options_set_compression(options, leveldb_no_compression);181roptions = leveldb_readoptions_create();182leveldb_readoptions_set_verify_checksums(roptions, 1);183leveldb_readoptions_set_fill_cache(roptions, 0);185woptions = leveldb_writeoptions_create();186leveldb_writeoptions_set_sync(woptions, 1);188StartPhase("destroy");189leveldb_destroy_db(options, dbname, &err);190Free(&err);192StartPhase("open_error");193db = leveldb_open(options, dbname, &err);194CheckCondition(err != NULL);195Free(&err);197StartPhase("leveldb_free");198db = leveldb_open(options, dbname, &err);199CheckCondition(err != NULL);200leveldb_free(err);201err = NULL;203StartPhase("open");204leveldb_options_set_create_if_missing(options, 1);205db = leveldb_open(options, dbname, &err);206CheckNoError(err);207CheckGet(db, roptions, "foo", NULL);209StartPhase("put");210leveldb_put(db, woptions, "foo", 3, "hello", 5, &err);211CheckNoError(err);212CheckGet(db, roptions, "foo", "hello");214StartPhase("compactall");215leveldb_compact_range(db, NULL, 0, NULL, 0);216CheckGet(db, roptions, "foo", "hello");218StartPhase("compactrange");219leveldb_compact_range(db, "a", 1, "z", 1);220CheckGet(db, roptions, "foo", "hello");222StartPhase("writebatch");223{224leveldb_writebatch_t* wb = leveldb_writebatch_create();225leveldb_writebatch_put(wb, "foo", 3, "a", 1);226leveldb_writebatch_clear(wb);227leveldb_writebatch_put(wb, "bar", 3, "b", 1);228leveldb_writebatch_put(wb, "box", 3, "c", 1);230leveldb_writebatch_t* wb2 = leveldb_writebatch_create();231leveldb_writebatch_delete(wb2, "bar", 3);232leveldb_writebatch_append(wb, wb2);233leveldb_writebatch_destroy(wb2);235leveldb_write(db, woptions, wb, &err);236CheckNoError(err);237CheckGet(db, roptions, "foo", "hello");238CheckGet(db, roptions, "bar", NULL);239CheckGet(db, roptions, "box", "c");241int pos = 0;242leveldb_writebatch_iterate(wb, &pos, CheckPut, CheckDel);243CheckCondition(pos == 3);244leveldb_writebatch_destroy(wb);245}247StartPhase("iter");248{249leveldb_iterator_t* iter = leveldb_create_iterator(db, roptions);250CheckCondition(!leveldb_iter_valid(iter));
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.