Skip to content

Commit

Permalink
Merge pull request #52 from rustaceanrob/doc-check
Browse files Browse the repository at this point in the history
multi: README, docs, bump rust-bitcoin
  • Loading branch information
rustaceanrob authored May 25, 2024
2 parents 4d6d9bc + 3094d51 commit 68f47ea
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 52 deletions.
90 changes: 57 additions & 33 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ alloc = []

[dependencies]
rand = { version = "0.8.0", default-features = false }
bitcoin = { version = "0.31.2", default-features = false, features = ["no-std"] }
bitcoin = { version = "0.32.0", default-features = false }

[dev-dependencies]
hex = { package = "hex-conservative", version = "0.2.0" }
Expand Down
2 changes: 1 addition & 1 deletion protocol/src/fschacha20poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const CHACHA_BLOCKS_USED: u32 = 3;
const REKEY_INTERVAL: u32 = 224;
const REKEY_INITIAL_NONCE: [u8; 4] = [0xFF, 0xFF, 0xFF, 0xFF];

/// Errors encrypting and decrypting with FSChaCha20Poly1305.
/// Errors encrypting and decrypting with [`FSChaCha20Poly1305`].
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Error {
Decryption(crate::chacha20poly1305::Error),
Expand Down
26 changes: 20 additions & 6 deletions protocol/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

//! BIP 324 encrypted transport for exchanging Bitcoin P2P messages. Read more about the [specification](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki).
//! BIP 324 encrypted transport for exchanging Bitcoin P2P messages. Much like TLS, a connection begins by exchanging ephimeral
//! elliptic curve public keys and performing a Diffie-Hellman handshake. Thereafter, each participant derives shared session secrets, and may
//! freely exchange encrypted messages. Under the new V2 specification, messages are encoded slightly differently than V1.
//! Read more about the [specification](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki).
#![no_std]

#[cfg(feature = "alloc")]
Expand Down Expand Up @@ -35,26 +38,35 @@ use fschacha20poly1305::{FSChaCha20, FSChaCha20Poly1305};
use hkdf::Hkdf;
use rand::Rng;

/// Number of bytes for the decoy flag on a packet.
// Number of bytes for the decoy flag on a packet.
const DECOY_BYTES: usize = 1;
/// Number of bytes for the authentication tag of a packet.
// Number of bytes for the authentication tag of a packet.
const TAG_BYTES: usize = 16;
/// Number of bytes for the length encoding prefix of a packet.
// Number of bytes for the length encoding prefix of a packet.
const LENGTH_BYTES: usize = 3;
/// Value for decoy flag.
// Value for decoy flag.
const DECOY: u8 = 128;
/// Version content is always empty for the current version of the protocol.
// Version content is always empty for the current version of the protocol.
const VERSION_CONTENT: [u8; 0] = [];

/// Errors encountered throughout the lifetime of a V2 connection.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Error {
/// The message decoded is smaller than expected
MessageLengthTooSmall,
/// There is a mismatch in the encoding of a message
IncompatableV1Message,
/// The message exceeded the maximum allowable length
MaxGarbageLength,
/// A handshake step was not completed in the proper order
HandshakeOutOfOrder,
/// A curve function could not be executed
SecretMaterialsGeneration(secp256k1::Error),
/// Deriving the shared secrets was unsuccessful
SecretExpansion,
/// The authentication data was not correct when decoding a message
Cipher(fschacha20poly1305::Error),
/// The internal counters of the ciphers are not in sync
OutOfSync,
}

Expand Down Expand Up @@ -160,6 +172,7 @@ impl ReceivedMessage {
}
}

/// Read packets off of a byte stream from a peer.
#[derive(Clone, Debug)]
pub struct PacketReader {
length_decoding_cipher: FSChaCha20,
Expand Down Expand Up @@ -245,6 +258,7 @@ impl PacketReader {
}
}

/// Prepare messages to be sent over a byte stream.
#[derive(Clone, Debug)]
pub struct PacketWriter {
length_encoding_cipher: FSChaCha20,
Expand Down
15 changes: 8 additions & 7 deletions protocol/src/serde.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

//! A subset of commands are represented with a single byte in V2 instead of the 12-byte ASCII encoding like V1.
//! Serialize and deserialize V2 messages over the wire.
//!
//! ID mappings defined in [BIP324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki#user-content-v2_Bitcoin_P2P_message_structure).
//! A subset of commands are represented with a single byte in V2 instead of the 12-byte ASCII encoding like V1. Message ID mappings are defined in [BIP324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki#user-content-v2_Bitcoin_P2P_message_structure).
use core::fmt;
use std::io;

use alloc::vec::Vec;
use bitcoin::{
block,
consensus::{encode, Decodable, Encodable},
p2p::message::{CommandString, NetworkMessage},
io::BufRead,
VarInt,
};

pub use bitcoin::p2p::message::{CommandString, NetworkMessage};

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Error {
Serialize,
Expand All @@ -40,7 +41,7 @@ impl std::error::Error for Error {
}
}

/// Serialize message in v2 format to buffer.
/// Serialize a [`NetworkMessage`] into a buffer.
pub fn serialize(msg: NetworkMessage) -> Result<Vec<u8>, Error> {
let mut buffer = Vec::new();
match &msg {
Expand Down Expand Up @@ -159,7 +160,7 @@ pub fn serialize(msg: NetworkMessage) -> Result<Vec<u8>, Error> {
Ok(buffer)
}

/// Deserialize v2 message into NetworkMessage.
/// Deserialize v2 message into [`NetworkMessage`].
pub fn deserialize(buffer: &[u8]) -> Result<NetworkMessage, Error> {
let short_id = buffer[0];
let mut payload_buffer = &buffer[1..];
Expand Down Expand Up @@ -295,7 +296,7 @@ struct HeaderDeserializationWrapper(Vec<block::Header>);

impl Decodable for HeaderDeserializationWrapper {
#[inline]
fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(
fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
r: &mut R,
) -> Result<Self, encode::Error> {
let len = VarInt::consensus_decode(r)?.0;
Expand Down
2 changes: 1 addition & 1 deletion proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ readme = "README.md"
rust-version = "1.56.1"

[dependencies]
bitcoin = { version = "0.31.2" }
bitcoin = { version = "0.32.0" }
tokio = { version = "1.37.0", features = ["full"] }
bytes = "1.6.0"
hex = { package = "hex-conservative", version = "0.2.0" }
Expand Down
26 changes: 25 additions & 1 deletion proxy/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# Proxy
# V2 Proxy

A proxy process which allows V1-only clients to communicate over a V2 protocol. The process listens on port `1324` for V1 connections and requires the V1 client to send along the remote peer's IP address in the `addr_recv` field.

## Running the Proxy

`cargo run --bin async`

## Testing with Nakamoto

[Nakamoto](https://github.com/cloudhead/nakamoto) is a BIP-157/BIP-158 Light Client that communicates over the Bitcoin P2P network. With a single change, Nakamoto may be modified to use the proxy.

```diff
diff --git a/net/poll/src/reactor.rs b/net/poll/src/reactor.rs

--- a/net/poll/src/reactor.rs
+++ b/net/poll/src/reactor.rs
@@ -468,7 +468,7 @@ fn dial(addr: &net::SocketAddr) -> Result<net::TcpStream, io::Error> {
sock.set_write_timeout(Some(WRITE_TIMEOUT))?;
sock.set_nonblocking(true)?;

- match sock.connect(&(*addr).into()) {
+ match sock.connect(&net::SocketAddr::from(([127, 0, 0, 1], 1324)).into()) {
Ok(()) => {}
Err(e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
Err(e) if e.raw_os_error() == Some(libc::EALREADY) => {
```
File renamed without changes.
3 changes: 1 addition & 2 deletions proxy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Helper functions for bitcoin p2p proxies.
//!
//! The V1 and V2 p2p protocols have different header encodings, so a proxy has to do
//! a little more work than just encrypt/decrypt. The [NetworkMessage](bitcoin::p2p::message::NetworkMessage)
//! a little more work than just encrypt/decrypt. The [`NetworkMessage`]
//! type is the intermediate state for messages. The V1 side can use the RawNetworkMessage wrapper, but the V2 side
//! cannot since things like the checksum are not relevant (those responsibilites are pushed
//! onto the transport in V2).
Expand Down Expand Up @@ -124,7 +124,6 @@ pub async fn read_v1<T: AsyncRead + Unpin>(input: &mut T) -> Result<NetworkMessa
input.read_exact(payload_bytes).await?;

let message = RawNetworkMessage::consensus_decode(&mut &full_bytes[..]).expect("decode v1");

// todo: drop this clone?
Ok(message.payload().clone())
}
Expand Down

0 comments on commit 68f47ea

Please sign in to comment.