#区块链 #比特币 #持久化 #存储 #数据库 #API

hammersbald

汉默斯巴尔德 - 用于区块链的快速持久化存储

19 个稳定版本

使用旧版 Rust 2015

3.0.1 2021 年 2 月 5 日
2.4.0 2019 年 10 月 3 日
2.2.0 2019 年 8 月 24 日
2.0.7 2019 年 7 月 10 日
0.2.3 2018 年 11 月 11 日

#1814神奇豆子

Download history 8/week @ 2024-03-14 66/week @ 2024-03-28 10/week @ 2024-04-04

117 每月下载次数
2 个包中使用(通过 murmel

Apache-2.0

110KB
2.5K SLoC

Safety Dance

汉默斯巴尔德

一个快速的嵌入式区块链数据库。

动机

通用的数据库和键值存储提供了比存储和处理区块链所需的功能多得多的功能。对于区块链而言,多余的功能在速度上付出了高昂的代价。

名称

汉默斯巴尔德是德语中“Haben wir es bald?”的俚语,相当于英语中的“Will we have it soon?”,常用来表达不耐烦。汉默斯巴尔德是那些不耐烦者的区块链数据库。汉默斯巴尔德听起来也像某些古老北欧神的名字。

状态

它能工作。

设计

参见 medium 上的 汉默斯巴尔德

API

这个库实现了最小限度的操作

  • 使用键插入数据
  • 使用键查找数据
  • 插入可以由其他数据引用但没有键的数据。
  • 使用已知偏移量查找数据。
  • 开始批处理,同时结束当前批处理

没有删除操作。使用相同键的插入将使先前的插入不可访问。键没有排序,也不能迭代。

插入必须分组到批处理中。批处理中的所有插入都将被存储,或者在插入批处理时进程死亡的情况下,没有任何一个被存储。

在关闭批处理之前可以检索批处理中插入的数据。

最简单的使用方法

use hammersbald::{
        persistent,
        HammersbaldAPI
        };

// read cache size in 4k pages
const CACHED_PAGES:usize = 100;
// average re-use of a hash table entry
const BUCKET_FILL_TARGET:usize = 2;

let mut db = persistent("dbname", CACHED_PAGES, BUCKET_FILL_TARGET).unwrap();

db.put_keyed(b"some key", b"some data").unwrap();

db.batch().unwrap();

if let Some((pos, data)) = db.get_keyed(b"some key").unwrap() {
    assert_eq!(data, b"some data".to_vec());
}
else {
    panic!("can not find inserted data");
}


db.shutdown();

可选的比特币 API

如果使用 bitcoin_support future 编译,则可用比特币适配器。示例用法

        // create a transient hammersbald
        let db = transient(1).unwrap();
        // promote to a bitcoin adapter
        let mut bdb = BitcoinAdaptor::new(db);

        // example transaction
        let tx = decode::<Transaction> (hex::decode("02000000000101ed30ca30ee83f13579da294e15c9d339b35d33c5e76d2fda68990107d30ff00700000000006db7b08002360b0000000000001600148154619cb0e7513fcdb1eb90cc9f86f3793b9d8ec382ff000000000022002027a5000c7917f785d8fc6e5a55adfca8717ecb973ebb7743849ff956d896a7ed04004730440220503890e657773607fb05c9ef4c4e73b0ab847497ee67b3b8cefb3688a73333180220066db0ca943a5932f309ac9d4f191300711a5fc206d7c3babd85f025eac30bca01473044022055f05c3072dfd389104af1f5ccd56fb5433efc602694f1f384aab703c77ac78002203c1133981d66dc48183e72a19cc0974b93002d35ad7d6ee4278d46b4e96f871a0147522102989711912d88acf5a4a18081104f99c2f8680a7de23f829f28db31fdb45b7a7a2102f0406fa1b49a9bb10c191fd83e2359867ecdace5ea990ce63d11478ed5877f1852ae81534220").unwrap()).unwrap();

        // store the transaction without associating a key
        let txref = bdb.put_encodable(&tx).unwrap();
        // retrieve by direct reference
        let (key, tx2) = bdb.get_decodable::<Transaction>(txref).unwrap();
        assert_eq!(tx, tx2);
        assert_eq!(key, tx.bitcoin_hash()[..].to_vec());

        // store the transaction with its hash as key
        let txref2 = bdb.put_hash_keyed(&tx).unwrap();
        // retrieve by hash
        if let Some((pref, tx3)) = bdb.get_hash_keyed::<Transaction>(&tx.bitcoin_hash()).unwrap() {
            assert_eq!(pref, txref2);
            assert_eq!(tx3, tx);
        }
        else {
            panic!("can not find tx");
        }
        bdb.batch().unwrap();

实现

持久化存储应该只由一个进程打开。

存储是一个使用 线性散列 的持久化哈希表。

限制

由于使用了6字节持久指针,数据存储大小限制为2^48(256TiB)。数据元素长度不能超过2^24(16MiB)。密钥长度限制为255字节。

发行说明

2.3.0所有比特币对象使用CBOR序列化

2.2.0将CBOR序列化对象存储添加到bitcoin_adaptor

2.1.0升级到rust-bitcoin 0.20,使用bitcoin_hashes代替siphasher

2.0.0文件格式更改,节省了一些空间

1.7.0组合后续的读取和写入,升级到rust-bitcoin 0.18

1.6.0升级到rust-bitcoin 0.17

1.5.1添加API may_have_key

1.5升级到bitcoin 0.16

依赖关系

~0.8–2.2MB
~34K SLoC