Skip to content

Commit d5de816

Browse files
committed
renamed to Murmel
1 parent 190c41c commit d5de816

20 files changed

+216
-201
lines changed

Cargo.toml

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
[package]
2-
name = "bitcoin-spv"
2+
name = "murmel"
33
version = "0.1.0"
44
authors = ["Tamas Blummer <[email protected]>"]
55
license = "Apache-2.0"
6-
homepage = "https://github.com/rust-bitcoin/rust-bitcoin-spv/"
7-
repository = "https://github.com/rust-bitcoin/rust-bitcoin-spv/"
8-
documentation = "https://github.com/rust-bitcoin/rust-bitcoin-spv/"
9-
description = "SPV client for Bitcoin"
10-
keywords = [ "bitcoin", "SPV" ]
6+
homepage = "https://github.com/rust-bitcoin/murmel/"
7+
repository = "https://github.com/rust-bitcoin/murmel/"
8+
documentation = "https://github.com/rust-bitcoin/murmel/"
9+
description = "Murmel Bitcoin node"
10+
keywords = [ "bitcoin" ]
1111
readme = "README.md"
1212

1313
[lib]
14-
name = "bitcoin_spv"
14+
name = "murmel"
1515
path = "src/lib.rs"
1616

1717
[dependencies]

NOTICE

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Murmel - Bitcoin Node written by Tamas Blummer 2018-2019

README.md

+28-12
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,41 @@
1-
# Bitcoin SPV in Rust
2-
This is an implementation of Bitcoin's Simplified Payment Verification mode. The SPV mode is suitable for lightweight nodes, such as a mobile phone. An SPV node verifies proof-of-work of a block but does not validate included transactions. It will follow the chain with most work.
1+
# Murmel
2+
Murmel is a lightweight Bitcoin node. Its intended use is to serve a lightning network stack with a settlement layer.
3+
Its resource requirements are marginal if compared to a Bitcoin Core node.
34

4-
An SPV node needs to connect full nodes to work. It does not offer any services to other nodes.
5+
Murmel filters blocks on client side implementing [BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki).
6+
Since Bitcoin Core does not yet support BIP157, Murmel may also be operated as filter server to serve a
7+
lightweight instance of itself.
58

6-
This implementation is tailored to serve a Lightning Network node on a resource and bandwidth limited device. It does not feature a memory pool of transactions, as payments are assumed to use the Lightning layer and otherwise only confirmed transactions are of interest.
9+
A Murmel client determines the chain with most work on its own and is capable of doing further checks. Its
10+
security guarantee is at least as defined in the Simplified Payment Verification (SPV) section of Satoshi's white paper.
711

8-
## Status
9-
This is work in progress, far from production quality. It aims to serve parallel development of a Lightning Node.
12+
Murmel does not maintain a memory pool of transactions, as payments are assumed to use the Lightning Network layer and otherwise only confirmed transactions are of interest.
13+
14+
#### About the name
15+
Murmel is German for marble. Murmel is small, fast, hard and beautiful just like a marble.
16+
17+
## Design and Implementation notes
18+
Murmel implements a small and fast P2P engine using on [mio](https://crates.io/crates/mio). The network messages are routed
19+
to their respective processors and back through message queues. Processors of logically distinct tasks are otherwise
20+
de-coupled and run in their own thread.
1021

11-
The code currently has a lot of dependencies as I wanted to progress quickly towards the stuff that is really new. Most dependencies will be removed later. Networking and Database code is carefully isolated from the logic of the node, so their implementations can be replaced.
22+
The blockchain data is persisted in a [Hammersbald](https://github.com/rust-bitcoin/hammersbald) database.
23+
The calculated [BIP157](https://github.com/bitcoin/bips/blob/master/bip-0157.mediawiki) filters for scripts and also for
24+
spent outpoints allow checking the UTXO based on its immutable store. In contrast to Bitcoin Core, Murmel does not have
25+
to re-compute anything on a re-org (switch of fork with most work) and optionally able to verify spent coins and
26+
block reward. These additional checks to that required by SPV allows Murmel to have a security guarantee higher than
27+
any other light node, but certainly still sub-par to a Bitcoin Core node.
1228

13-
I plan to implement BIP157 and BIP158 as soon as they are available in Bitcoin. Until that the node will download full blocks. I do not want to waste time implementing BIP37 that hurts privacy.
1429

15-
## Contributions and Vision
16-
The current plan is to create a small footprint, low bandwidth, stable and secure Lightning Network node combining with the below projects:
30+
## Status
31+
Not yet for serious use. Marble is able to support it's own and Lightning Node development.
32+
33+
## Uses
34+
Marble uses and supports below projects:
1735

1836
* [Rust language bindings for Bitcoin secp256k1 library.](https://github.com/rust-bitcoin/rust-secp256k1)
1937
* [Rust Bitcoin library](https://github.com/rust-bitcoin/rust-bitcoin)
2038
* [Bitcoin's libbitcoinconsenus.a with Rust binding.](https://github.com/rust-bitcoin/rust-bitcoinconsensus)
21-
* [Bitcoin SPV in Rust](https://github.com/rust-bitcoin/bitcoin-spv)
2239
* [Rust-Lightning, not Rusty's Lightning](https://github.com/rust-bitcoin/rust-lightning)
2340
* [Hammersbald](https://github.com/rust-bitcoin/hammersbald)
2441

25-
Send in your PRs if aligned with above vision.

src/bin/client.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,22 @@
1414
// limitations under the License.
1515
//
1616
extern crate bitcoin;
17-
extern crate bitcoin_spv;
17+
extern crate murmel;
1818
extern crate log;
1919
extern crate rand;
2020
extern crate simple_logger;
2121

2222
use std::env::args;
2323

2424
use bitcoin::network::constants::Network;
25-
use bitcoin_spv::constructor::Constructor;
25+
use murmel::constructor::Constructor;
2626
use log::Level;
2727
use std::net::{SocketAddr,SocketAddrV4,Ipv4Addr};
2828
use std::path::Path;
2929

30-
/// simple test drive that connects to a local bitcoind
3130
pub fn main() {
3231
if find_opt("help") {
33-
println!("BIP157 Filter Client");
32+
println!("Murmel Client");
3433
println!("{} [--help] [--log trace|debug|info|warn|error] [--connections n] [--peer ip_address:port] [--db database_file] [--network main|test]", args().next().unwrap());
3534
println!("--log level: level is one of trace|debug|info|warn|error");
3635
println!("--connections n: maintain at least n connections");
@@ -85,7 +84,7 @@ pub fn main() {
8584
else {
8685
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new("client.db"), listen, false).unwrap();
8786
}
88-
spv.run(peers, connections, true).expect("can not start SPV");
87+
spv.run(peers, connections, true).expect("can not start node");
8988
}
9089

9190
use std::str::FromStr;

src/bin/server.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,22 @@
1414
// limitations under the License.
1515
//
1616
extern crate bitcoin;
17-
extern crate bitcoin_spv;
17+
extern crate murmel;
1818
extern crate log;
1919
extern crate rand;
2020
extern crate simple_logger;
2121

2222
use std::env::args;
2323

2424
use bitcoin::network::constants::Network;
25-
use bitcoin_spv::constructor::Constructor;
25+
use murmel::constructor::Constructor;
2626
use log::Level;
2727
use std::net::{SocketAddr,SocketAddrV4,Ipv4Addr};
2828
use std::path::Path;
2929

30-
/// simple test drive that connects to a local bitcoind
3130
pub fn main() {
3231
if find_opt("help") {
33-
println!("BIP157 Filter Server");
32+
println!("Murmel Server");
3433
println!("{} [--help] [--log trace|debug|info|warn|error] [--connections n] [--peer ip_address:port] [--db database_file] [--network main|test]", args().next().unwrap());
3534
println!("--log level: level is one of trace|debug|info|warn|error");
3635
println!("--connections n: maintain at least n connections");
@@ -87,7 +86,7 @@ pub fn main() {
8786
else {
8887
spv = Constructor::new("/https://github.com/rust-bitcoin/rust-bitcoin-spv/".to_string(), network, Path::new("server.db"), listen, true).unwrap();
8988
}
90-
spv.run(peers, connections, find_opt("nodns")).expect("can not start SPV");
89+
spv.run(peers, connections, find_opt("nodns")).expect("can not start node");
9190
}
9291

9392
use std::str::FromStr;

src/blockfilter.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
//! that minimizes filter size by using Golomb-Rice coding for compression.
2222
//!
2323
24-
use error::SPVError;
24+
use error::MurmelError;
2525
use chaindb::ScriptAccessor;
2626

2727
use bitcoin::{
@@ -59,7 +59,7 @@ pub struct BlockFilter {
5959

6060
impl BlockFilter {
6161

62-
pub fn compute_script_filter(block: &Block, height: u32, script_accessor: impl ScriptAccessor) -> Result<BlockFilter, SPVError> {
62+
pub fn compute_script_filter(block: &Block, height: u32, script_accessor: impl ScriptAccessor) -> Result<BlockFilter, MurmelError> {
6363
let mut bytes = Vec::new();
6464
let mut out = Cursor::new(&mut bytes);
6565
{
@@ -70,7 +70,7 @@ impl BlockFilter {
7070
Ok(BlockFilter{block: block.bitcoin_hash(), filter_type: SCRIPT_FILTER, content: out.into_inner().to_vec()})
7171
}
7272

73-
pub fn compute_coin_filter(block: &Block) -> Result<BlockFilter, SPVError> {
73+
pub fn compute_coin_filter(block: &Block) -> Result<BlockFilter, MurmelError> {
7474
let mut bytes = Vec::new();
7575
let mut out = Cursor::new(&mut bytes);
7676
{
@@ -108,7 +108,7 @@ impl <'a> BlockFilterWriter<'a> {
108108
}
109109

110110
/// Add consumed output scripts of a block to filter
111-
fn add_consumed_scripts (&mut self, height: u32, tx_accessor: impl ScriptAccessor) -> Result<(), SPVError> {
111+
fn add_consumed_scripts (&mut self, height: u32, tx_accessor: impl ScriptAccessor) -> Result<(), MurmelError> {
112112
let mut coins = Vec::new();
113113
for transaction in &self.block.txdata {
114114
if !transaction.is_coin_base() {
@@ -124,13 +124,13 @@ impl <'a> BlockFilterWriter<'a> {
124124
}
125125

126126
/// compile a filter useful for wallets
127-
pub fn script_filter(&mut self, height: u32, tx_accessor: impl ScriptAccessor) -> Result<(), SPVError> {
127+
pub fn script_filter(&mut self, height: u32, tx_accessor: impl ScriptAccessor) -> Result<(), MurmelError> {
128128
self.add_output_scripts();
129129
self.add_consumed_scripts(height, tx_accessor)
130130
}
131131

132132
/// compile a filter useful to find spent outputs
133-
pub fn coin_filter(&mut self) -> Result<(), SPVError> {
133+
pub fn coin_filter(&mut self) -> Result<(), MurmelError> {
134134
let mut buf = Vec::with_capacity(40);
135135
for tx in &self.block.txdata {
136136
let txid = tx.txid();
@@ -409,7 +409,7 @@ mod test {
409409
use bitcoin::blockdata::script::Script;
410410
use bitcoin::blockdata::transaction::OutPoint;
411411

412-
use error::SPVError;
412+
use error::MurmelError;
413413
use blockfilter::test::rustc_serialize::json::Json;
414414
use rand;
415415
use rand::RngCore;
@@ -432,7 +432,7 @@ mod test {
432432
}
433433

434434
impl ScriptAccessor for HashMap<OutPoint, Script> {
435-
fn get_scripts(&self, _: u32, coins: Vec<OutPoint>) -> Result<Vec<Script>, SPVError> {
435+
fn get_scripts(&self, _: u32, coins: Vec<OutPoint>) -> Result<Vec<Script>, MurmelError> {
436436
let mut result = Vec::new();
437437
for coin in coins {
438438
if let Some(ux) = self.get(&coin) {

src/blockserver.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use bitcoin::{
2828
use blockfilter::{COIN_FILTER, SCRIPT_FILTER};
2929
use chaindb::SharedChainDB;
3030
use chaindb::StoredFilter;
31-
use error::SPVError;
31+
use error::MurmelError;
3232
use p2p::{P2PControl, P2PControlSender, PeerId, PeerMessage, PeerMessageReceiver, PeerMessageSender};
3333
use std::{
3434
sync::mpsc,
@@ -70,7 +70,7 @@ impl BlockServer {
7070
panic!("Block server thread failed.");
7171
}
7272

73-
fn get_headers(&self, peer: PeerId, get: GetHeadersMessage) -> Result<(), SPVError> {
73+
fn get_headers(&self, peer: PeerId, get: GetHeadersMessage) -> Result<(), MurmelError> {
7474
let chaindb = self.chaindb.read().unwrap();
7575
for locator in get.locator_hashes.iter () {
7676
if let Some(pos) = chaindb.pos_on_trunk(locator) {
@@ -85,7 +85,7 @@ impl BlockServer {
8585
Ok(())
8686
}
8787

88-
fn get_blocks(&self, peer: PeerId, get: GetBlocksMessage) -> Result<(), SPVError> {
88+
fn get_blocks(&self, peer: PeerId, get: GetBlocksMessage) -> Result<(), MurmelError> {
8989
let chaindb = self.chaindb.read().unwrap();
9090
for locator in get.locator_hashes.iter () {
9191
if let Some(pos) = chaindb.pos_on_trunk(locator) {
@@ -100,7 +100,7 @@ impl BlockServer {
100100
Ok(())
101101
}
102102

103-
fn get_data(&self, peer: PeerId, get: Vec<Inventory>) -> Result<(), SPVError> {
103+
fn get_data(&self, peer: PeerId, get: Vec<Inventory>) -> Result<(), MurmelError> {
104104
let chaindb = self.chaindb.read().unwrap();
105105
for inv in get {
106106
if inv.inv_type == InvType::WitnessBlock {

0 commit comments

Comments
 (0)