Skip to content
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8f3a7b8
Introduce typed overlay peer identity
metaphorics Oct 24, 2026
1330e41
Add Tor and I2P overlay transports
metaphorics Oct 25, 2026
5e2500b
Record bounded overlay interoperability runs
metaphorics Oct 25, 2026
30bf633
Isolate SAM fixtures from unrelated probes
metaphorics Oct 25, 2026
042ae72
Run overlay checks on isolated pinned fixtures
metaphorics Oct 26, 2026
e86b4b6
Refuse local DNS under privacy routes
metaphorics Oct 27, 2026
f31ae21
Negotiate BIP434 peer features
metaphorics Oct 25, 2026
c5822a0
Relay negotiated stale chain tips
metaphorics Oct 25, 2026
0fe7730
Retry initial stale tips until send acknowledgement
metaphorics Oct 26, 2026
f8c0fac
Add negotiated BIP331 package relay
metaphorics Oct 25, 2026
7f84741
Solicit packages for negotiated orphan peers
metaphorics Oct 25, 2026
a0a30ba
Relay-policy lane: preserve orphan fallback, inbound cadence, retire …
metaphorics Oct 27, 2026
854a0ab
Review fixes for the peer-resolution lane: soft-blocked scan, probe-r…
metaphorics Oct 27, 2026
f8e9a60
Route stale-tip batches through identified peer with minimum-work hol…
metaphorics Oct 27, 2026
c224590
Strengthen stale-tip regressions to drive the drain
metaphorics Oct 27, 2026
5b59792
Remove unused package submission result types
metaphorics Oct 27, 2026
89901a4
Resolve protocol review test lint findings
metaphorics Oct 27, 2026
f987444
Remove stale RPC line-count expectation
metaphorics Oct 27, 2026
c31411e
Document opt-in BIP332 negotiation
metaphorics Oct 27, 2026
c6becf8
Request held orphan parents by package or legacy path, never both
metaphorics Oct 27, 2026
549d228
Ignore notfound answers to questions nobody asked
metaphorics Oct 27, 2026
d9f5053
Document implemented BIP331 negotiation
metaphorics Oct 27, 2026
151a566
Deduplicate chain tip and relay predicates
metaphorics Oct 27, 2026
347a8b5
Enable RPC protocol test seams
metaphorics Oct 27, 2026
612de0c
Update peer test-seam documentation
metaphorics Oct 27, 2026
4107f13
Complete addrv2 rotation and package parent fallback
metaphorics Oct 27, 2026
ffeb1b8
Align config and addrman restart compatibility tests
metaphorics Oct 27, 2026
08da46b
Order unsorted BIP331 ancestor packages before admission
gormes-agent[bot] Oct 28, 2026
59b0993
Fall back to held orphan parents when a package claim dies
gormes-agent[bot] Oct 28, 2026
f58daa5
Fix anonymous peer serving and route prefiltering
metaphorics Oct 28, 2026
dcfce42
Merge main into stack/07-protocol
metaphorics Oct 28, 2026
67ffcbe
Merge main into stack/07-protocol
metaphorics Oct 28, 2026
fcc3fe1
Fix p2p test-only endpoint-identity type errors
metaphorics Oct 28, 2026
87cd648
Fix workspace merge-resolution errors at root
metaphorics Oct 28, 2026
4a02d52
Merge origin/main into stack/07-protocol: resolve wire/payload and co…
metaphorics Oct 28, 2026
62729a5
Fix workspace merge-resolution errors: close validate_overlay, port p…
metaphorics Oct 28, 2026
0312ecc
p2p(listener): publish negotiated package-relay bits before ready
metaphorics Oct 28, 2026
b6f02d5
p2p(service): retain overlay workers for rollback and join
metaphorics Oct 28, 2026
efaadc0
p2p(peer_info): support AnonymousTor inbound metadata
metaphorics Oct 28, 2026
149c29b
p2p(service): capture restart anchors before cancelling workers
metaphorics Oct 28, 2026
b98fa4c
Merge origin/main 8a222c32f into stack/07-protocol
metaphorics Oct 28, 2026
6693c7e
Fix duplicate submit_package_attempt after main merge
metaphorics Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ secp256k1 = { version = ">=0.29.1, <0.30", default-features = false, features =

# sha2 0.11: default features are alloc+oid; no std/asm feature is exposed.
sha2 = { version = ">=0.11, <0.12", default-features = false }
sha3 = { version = ">=0.11, <0.12", default-features = false }
bitcoin_hashes = { version = ">=0.14, <0.15", default-features = false, features = [
"alloc", "std",
] }
Expand Down
131 changes: 131 additions & 0 deletions bin/bitcoin-rs/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,26 @@ impl CoreValue for Option<PathBuf> {
}
}

impl CoreValue for Option<SocketAddr> {
fn apply(value: &str, slot: &mut Self) {
if let Ok(addr) = value.parse() {
*slot = Some(addr);
}
}
}

impl CoreValue for Option<Vec<bitcoin_rs_node::options::NetworkLabel>> {
fn apply(value: &str, slot: &mut Self) {
let entries = slot.get_or_insert_with(Vec::new);
for item in value.split(',') {
if let Ok(label) = bitcoin_rs_node::options::parse_network_label(item.trim()) {
if !entries.contains(&label) {
entries.push(label);
}
}
}
}
}
/// Sets the one Core key that no table row can express: `listen` is a boolean
/// switch over the bind list, not an address, and only its false value is an
/// override. Returns whether it consumed `key`.
Expand Down Expand Up @@ -400,6 +420,7 @@ mod compat_tests {
use anyhow::Result;
use bitcoin_rs_node::{Auth, Network, NodeConfig, resolve};
use std::fs;
use std::net::SocketAddr;

fn load_conf(text: &str, network: Network) -> Result<NodeConfig> {
let temp = tempfile::tempdir()?;
Expand Down Expand Up @@ -431,6 +452,50 @@ mod compat_tests {
assert_eq!(config.p2p.listen, []);
assert!(config.indexes.txindex);
assert_eq!(config.storage.dbcache_mb, 768);

let conf_with_overlays = load_conf(
r"
proxy=127.0.0.1:9050
onion=127.0.0.1:9051
dnsseed=0
proxyrandomize=1
torcontrol=127.0.0.1:9052
torpassword=secret
i2psam=127.0.0.1:7656
i2pacceptincoming=1
onlynet=onion,i2p
",
Network::Mainnet,
)?;
assert_eq!(
conf_with_overlays.p2p.overlay.proxy,
Some(SocketAddr::from(([127, 0, 0, 1], 9050)))
);
assert_eq!(
conf_with_overlays.p2p.overlay.onion,
Some(SocketAddr::from(([127, 0, 0, 1], 9051)))
);
assert!(conf_with_overlays.p2p.overlay.proxy_randomize_credentials);
assert_eq!(
conf_with_overlays.p2p.overlay.tor_control.as_deref(),
Some("127.0.0.1:9052")
);
assert_eq!(
conf_with_overlays.p2p.overlay.tor_password.as_deref(),
Some("secret")
);
assert_eq!(
conf_with_overlays.p2p.overlay.i2p_sam,
Some(SocketAddr::from(([127, 0, 0, 1], 7656)))
);
assert!(conf_with_overlays.p2p.overlay.i2p_accept_incoming);
assert_eq!(
conf_with_overlays.p2p.overlay.onlynet,
vec![
bitcoin_rs_node::options::NetworkLabel::Onion,
bitcoin_rs_node::options::NetworkLabel::I2p
]
);
Ok(())
}

Expand Down Expand Up @@ -501,3 +566,69 @@ assumevalid=0000000000000000000000000000000000000000000000000000000000000000
}
}
}

#[cfg(test)]
mod feature_option_tests {
use std::ffi::OsString;

use anyhow::Result;
use bitcoin_rs_node::NodeConfig;
use clap::Parser as _;

use super::{CliArgs, resolve};

fn load(args: &[&str], vars: &[(&str, &str)]) -> Result<NodeConfig> {
let argv = std::iter::once("bitcoin-rs").chain(args.iter().copied());
let cli = CliArgs::try_parse_from(argv)?;
resolve(
cli,
vars.iter()
.map(|(key, value)| (OsString::from(*key), OsString::from(*value))),
)
}

fn refusal(args: &[&str], vars: &[(&str, &str)]) -> String {
match load(args, vars) {
Ok(_) => panic!("configuration must be refused"),
Err(error) => error.to_string(),
}
}

#[test]
fn relay_switches_are_bare_cli_flags_and_the_command_line_beats_environment() -> Result<()> {
let off = load(&[], &[])?.p2p;
assert!(
!off.relay_offers.package_relay
&& !off.relay_offers.stale_tip_relay
&& !off.relay_offers.stale_tip_prefers_blocks
);

let on = load(
&[
"--p2p-package-relay",
"--p2p-stale-tip-relay",
"--p2p-stale-tip-prefers-blocks",
],
&[],
)?
.p2p;
assert!(
on.relay_offers.package_relay
&& on.relay_offers.stale_tip_relay
&& on.relay_offers.stale_tip_prefers_blocks
);

let env_on = load(&[], &[("BITCOIN_RS_P2P_PACKAGE_RELAY", "true")])?.p2p;
assert!(env_on.relay_offers.package_relay);
let cli_off = load(
&["--p2p-package-relay=false"],
&[("BITCOIN_RS_P2P_PACKAGE_RELAY", "true")],
)?
.p2p;
assert!(!cli_off.relay_offers.package_relay);

let dangling = refusal(&["--p2p-stale-tip-prefers-blocks"], &[]);
assert!(dangling.contains("--p2p-stale-tip-relay"));
Ok(())
}
}
2 changes: 1 addition & 1 deletion bin/bitcoin-rs/tests/addrman_restart_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ fn restart_reconnects(
let datadir = learner.stop_keep_datadir()?;
let bytes = std::fs::read(datadir.path().join("node/peers-fabfb5da.dat"))?;
let book: serde_json::Value = serde_json::from_slice(&bytes[..bytes.len() - 32])?;
assert_eq!(book["version"], 8);
assert_eq!(book["version"], 9);
assert_eq!(
book["asmap_id"],
json!(expected_map),
Expand Down
1 change: 1 addition & 0 deletions crates/chain/src/deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ mod tests {
// prev_blockhash and the by_hash key pointing at a discarded hash.
let node_id = if height == activation_height {
tree.insert_header_with_hash(header, expected_hash, NodeStatus::HeaderValid)?
.id
} else {
tree.insert_header(header, NodeStatus::HeaderValid)?
};
Expand Down
Loading
Loading