1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
//! # Update 2021-03-25 - Moved to Zebra BTC //! //! As of March 2021, we're exploring building Bitcoin Warp from a fork of Zcash Zebra. For now, you can follow our progress [here](https://github.com/preston-evans98/zebra-btc). The original docs for Bitcoin warp are visible below //! //! # Welcome to Bitcoin Warp //! //! Bitcoin Warp is an ongoing implementation of a new [Bitcoin](http://www.bitcoinwarp.com/bitcoin.pdf) client in Rust. You can track our progress on [Github](https://github.com/preston-evans98/bitcoin-warp) or view our docs at [bitcoinwarp.com](bitcoinwarp.com). //! //! Bitcoin Warp is a work in progress. It is developed as a collection of //! libraries implementing the different components of a Bitcoin node (such as networking, cryptography, shared primitives, etc.), and a `warpd` binary which uses them. Expect the structure of this project to change very frequently up until the 1.0 release. //! //! Almost all of our work so far has gone into `networking`, an implementation of the Bitcoin Wire Protocol //! inspired by [Zcash Zebra's](https://doc.zebra.zfnd.org) new networking stack. However, many of the core components of the `shared` library have also begun to stabilize. //! //! ## Why Another Bitcoin Implementation? //! //! There are at least seven separate implementations of the Bitcoin protocol. Why do we need another one? //! //! ### 1. Bitcoin Core has about 98% Market Share //! //! Core has earned its place at the top. It's battle-tested, actively maintained, and blazing fast. But too much concentration isn't a good thing. //! //! 1. **It places an undue burden on the core devs.** Since a bug in Core could effectively bring down the entire Bitcoin network, the devs have to be perfect. They've done remarkably well so far, but its unreasonable to expect that they'll keep it up forever. //! 1. **It slows innovation.** In Ethereum, both Geth and Parity (and now Nethermind) can try out new features. If a feature doesn't work out and part of the network crashes, it's bad but not catastrophic. Bitcoin Core doesn't have that luxury. They need to maintain 100% uptime, or Bitcoin dies. In addition, potential contributors need to be advanced C++ programmers willing to dive into a highly complex codebase. Obviously, this somewhat limits the pool of contributors. //! 1. **It leaves us vulnerable to supply chain attacks**. As Bitcoin grows to trillion dollar market cap and beyond, it may very well be targeted by national intelligence services. Expect to see a variety of attacks on Bitcoin Core's supply chain - from tampering with dev machines to stealing release keys. Heck, someone might even try to mess with C++ compilers. In any case, _Vires in Numeris._ //! //! ### 2. There is no Viable Alternative Client //! //! 1. **Sync times for the next best client are [3x longer](https://blog.lopp.net/bitcoin-node-performance-sync-tests/) than Bitcoin Core.** Syncing Core is already painful enough. //! 1. **Most Alt-Clients are vulnerable to supply chain attacks**. The best performing Alt-Client (Bcoin) is written in Node JS. With NPM. Yikes. The next best (GoCoin) is also vulnerable (lock files anyone?). This is a common pattern. Most languages don't take supply chain attacks seriously, and it shows. //! 1. **Alt-Clients have restrictive licenses**. GoCoin, Parity - I'm looking at you. //! //! ## What Will Make Bitcoin Warp Different? //! //! 1. **Performance.**. Unlike clients written in Go (or C#, or JS, or Python, or...) there's no reason Bitcoin Warp needs to be slower than Bitcoin Core. Hopefully, it will be even faster. //! 1. **Security.** Bitcoin Warp will be (almost) completely immune to memory safety bugs. It will have a secure supply chain. //! 1. **Simplicity.** We expect Bitcoin Warp to be significantly smaller (in terms of SLOC) than Bitcoin Core. //! 1. **Free as in Freedom.** And Free as in Beer. Bitcoin Warp is open source and MIT licensed. //! //! How is all of that possible? Mostly, it comes down to writing in Rust. In case you're not familiar, Rust is a systems programming language that combines blazing speed with complete memory safety (assuming you don't need `unsafe` features). It doesn't have garbage collection, so it produces binaries that run just as fast as `C` programs, and don't take up any more space. It has a package manager that provides reasonable protections against supply chain attacks (lock files with hashes are a big plus). It also has a bunch of neat features like iterators, closures, generics, and macros. //! //! This means that if we do our job, Bitcoin Warp can be just as fast as a C/C++ Bitcoin implementation like Bitcoin Core (or even faster) and we can write a lot less code. That means easier maintenance, faster iteration, and (hopefully) more innovation. //! //! # Roadmap //! //! Implementation of Bitcoin Warp is split into several phases with accompanying milestones. //! //! ## Pre-Alpha //! //! ### 1. Basic Networking (Feature Complete - in QA) //! //! Implement the Bitcoin wire protocol. Allows messages to be exchanged with nodes running Bitcoin Core to allow fetching blocks etc. during development. Does not include peer management, mempool, etc. //! //! ### 2. Basic Validation (Implementation In Progress) //! //! Implement the basic logic to validate blocks and transactions. This includes things like checking signatures and block hashes. Partially dependent on 3. This implementation will be unoptimized, and may not include changes introduced into Bitcoin via soft fork. These changes will be added in the next phase. //! //! ### 3. Basic Database //! //! Implement a minimum viable database layer to store blocks and UTXOs. Likely LevelDB initially. //! //! ### 4. Basic Interface //! //! Implement config files and simple CLI. //! //! ### 5. Advanced Networking (Implementation in Progress) //! //! Implement a connection manager. Accomplishment of this milestone marks the client ready for Alpha Launch. //! //! ## Alpha //! //! ### Advanced Validation //! //! Implement soft-fork features like SegWit and TapRoot. Optimize. //! //! ### Advanced Database (Optional) //! //! Optimize the database. Explore alternatives to LevelDB, including potentially designing a Bitcoin-specific DB engine. //! //! ### Production Level Integration Testing //! //! 'Nuff Said. //! //! ## Beta //! //! ### Advanced Interface //! //! Electron + Typescript = Better UX. //! //! ### State of the Art Networking //! //! Explore using libP2p, or implementing a new networking protocol based on more recent academic literature. This might be unnecessary. It might also be fun. In any case, we definitely need authenticated messaging. //! //! ... //! //! That seems like more than enough to get started. If we make it this far, we should be able to get funding for an audit and launch this thing for real. //! //! **N.B.** There's nothing about wallet functionality on the roadmap. That's intentional. **_You shouldn't store BTC on a hot device unless you really know what you're doing_**, so having a wallet on your node is asking for trouble. We won't add this feature unless there's a very compelling need to do so. //! //! # Getting Started //! //! 1. [Install the Rust Compiler](https://www.rust-lang.org/tools/install) //! 1. Clone our git repository `git clone https://github.com/preston-evans98/bitcoin-warp.git` //! 1. `cd bitcoin-warp` //! 1. Run `cargo test --all` to build the client and run all unit tests. //! 1. (Optional) `cargo run` to see the experimental warp shell in action. This shell lets you connect to any other client running Bitcoin and send and receive messages from the command line. Note: This is very much a work in progress. It depends on some functionality from the connection manager, which won't be fully implemented until the end of the Alpha stage. // //! ![BitcoinWarp Logo](/Users/prestonevans/Downloads/BitcoinWarpLogoMock.png) mod shell; use config::Config; use networking::{Peer, PeerError}; pub use shell::shell::run_shell; use std::net::SocketAddr; use std::sync::Arc; /// The Bitcoin Warp Daemon #[derive(Debug)] pub struct Warpd { pub config: Config, conn_man: ConnectionManager, } /// An initial pass at a connection manager. Soon to be deprecated. Its replacement will live in the `networking` crate. #[derive(Debug)] pub struct ConnectionManager { peers: Vec<Peer>, } impl ConnectionManager { pub fn new() -> ConnectionManager { ConnectionManager { peers: Vec::new() } } pub async fn add(&mut self, addr: SocketAddr, config: &Config) -> Result<(), PeerError> { let peer = Peer::at_address(addr, config.clone()).await?; self.peers.push(peer); Ok(()) } pub async fn accept(&mut self, port: &str, config: &Config) -> Result<(), PeerError> { let addr = format!("127.0.0.1:{}", port); let listener = tokio::net::TcpListener::bind(&addr) .await .expect(&format!("Could not create listener on {}", addr)); let (connection, _) = listener.accept().await?; let peer = Peer::from_connection(connection, config.clone()).await; self.peers.push(peer); Ok(()) } pub fn num_peers(&self) -> usize { self.peers.len() } } // #[derive(Debug)] // struct Peer { // ip_address: std::net::IpAddr, // services: u64, // } impl Warpd { pub fn new() -> Warpd { Warpd { config: Config::mainnet(), conn_man: ConnectionManager::new(), } } pub async fn add_peer(&mut self, addr: SocketAddr) -> Result<(), PeerError> { if self.conn_man.num_peers() >= self.config.max_peers() { unimplemented!() } self.conn_man.add(addr, &self.config).await } pub async fn accept_peer(&mut self, port: &str) -> Result<(), PeerError> { if self.conn_man.num_peers() >= self.config.max_peers() { unimplemented!() } self.conn_man.accept(port, &self.config).await } }