Bitcoin slices
ZERO allocations parse library for Bitcoin data structures.
Data is accessed by providing visitor structs for the data the user is interested in.
Data structures are read-only and parsed data must be in memory, no streaming API.
Tradeoffs
Check the CONS before using this library, use rust-bitcoin if they are too restrictive for your case.
Pros
- Deserialization is amazingly fast, since no allocation is made during parsing.
- Serialization is incredibly fast, since a slice of the serialized data is kept in the structure.
- hashing a little faster because slice are ready without the need of re-serializing data.
- No mandatory dependency.
- No standard.
- Calculate txid and block hash via optional dep
bitcoin_hashes
orsha2
. - Visitor pattern to visit just what you are interested in.
Cons
- Full data must be in memory, there is no streaming (Read/Write) API.
- Data structure are read-only, cannot be modified.
- Visitor pattern requires user-built data structure for visiting.
Test
Bench
RUSTFLAGS='--cfg=bench'
)
)
)
)
)
)
)
)
)
)
)
)
)
)
- benches ending with
_bitcoin
userust-bitcoin
- benches ending with
_sha2
usesha2
lib instead ofbitcoin_hashes
Comparison against rust-bitcoin
block_deserialize
is almost 10 times faster then block_deserialize_bitcoin
. It may see unfair
comparison since you can't for example iterate transactions from the resulted object in case of
block_deserialize
, but looking at the sum_outputs
example where a visitor is used to access
every outputs in a block we se there isn't noticeable difference.
Hashing
block_hash
and block_hash_bitcoin
use the same code to hash, however bitcoin_slice is about 7%
faster because use a slice already available instead of serializing back data.
Similar results apply between txid
and txid_bitcoin
.
The performance increase is more notable (30%) between hash_block_txs
and hash_block_txs_bitcoin
.
*_sha2
are not really representative on virtual CI machines since they are not hardware-accellerated.
Fuzz
Use cargo fuzz Run fuzzing with transaction as target.
Other target available in fuzz/fuzz_targets
Miniminze corpus:
cargo +nightly fuzz cmin transaction
Previous work and credits
- Bitiodine use similar visitor pattern (parser credited to Mathias Svensson)
- Some previous work on the idea to parse while reducing allocations in this PR
- Matt Corallo mentioned something like this in a comment in that PR
TODO
- create rotating buffer that consume and produce keeping a linear memory (rotate back when it can't append), this would overcome a bit the absence of streaming API
- implements network types
- add limited time fuzzing in CI