Skip to content

Commit 671ab17

Browse files
committed
feat(rpc): getnetworkinfo.localservices advertises NETWORK+WITNESS+COMPACT_FILTERS
Op: extend
1 parent 2cd5697 commit 671ab17

1 file changed

Lines changed: 45 additions & 3 deletions

File tree

crates/rpc/src/handlers/network.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ use crate::context::Context;
66
use crate::error::RpcError;
77
use crate::handlers::{ensure_no_params, params_array, required_str};
88

9+
// Local service flags this node advertises:
10+
// - NODE_NETWORK (1 << 0) = 1 — full block serving.
11+
// - NODE_WITNESS (1 << 3) = 8 — segwit data.
12+
// - NODE_COMPACT_FILTERS (1 << 6) = 64 — BIP157 filters.
13+
// Sum = 73 = 0x49.
14+
const LOCAL_SERVICES_FLAGS: u64 = (1_u64 << 0) | (1_u64 << 3) | (1_u64 << 6);
15+
const LOCAL_SERVICES_HEX: &str = "0000000000000049";
16+
const LOCAL_SERVICES_NAMES: &[&str] = &["NETWORK", "WITNESS", "COMPACT_FILTERS"];
17+
18+
const _: () = assert!(LOCAL_SERVICES_FLAGS == 0x49);
19+
920
const DEFAULT_RELAY_FEE_BTC_PER_KVB: f64 = 0.00001;
1021
const DEFAULT_INCREMENTAL_FEE_BTC_PER_KVB: f64 = 0.00001;
1122

@@ -19,8 +30,11 @@ pub(crate) fn getnetworkinfo(ctx: &Arc<Context>, params: &Value) -> Result<Value
1930
"version": 10000,
2031
"subversion": "/bitcoin-rs:0.1.0/",
2132
"protocolversion": 70016_i64,
22-
"localservices": "0000000000000000",
23-
"localservicesnames": Vec::<String>::new(),
33+
"localservices": LOCAL_SERVICES_HEX,
34+
"localservicesnames": LOCAL_SERVICES_NAMES
35+
.iter()
36+
.map(|&s| s.to_owned())
37+
.collect::<Vec<_>>(),
2438
"localrelay": true,
2539
"timeoffset": 0,
2640
"networkactive": true,
@@ -226,7 +240,7 @@ pub(crate) fn getnettotals(ctx: &Arc<Context>, params: &Value) -> Result<Value,
226240
mod tests {
227241
use super::*;
228242
use alloc::sync::Arc;
229-
use sonic_rs::JsonValueTrait;
243+
use sonic_rs::{JsonContainerTrait as _, JsonValueTrait};
230244

231245
#[test]
232246
fn getnetworkinfo_reports_zero_connections_on_fresh_context() {
@@ -261,6 +275,34 @@ mod tests {
261275
"expected ~0.00001, got {relayfee}"
262276
);
263277
}
278+
279+
#[test]
280+
fn getnetworkinfo_localservices_advertises_network_witness_filters() {
281+
let ctx = Arc::new(Context::new());
282+
let result = getnetworkinfo(&ctx, &json!(null))
283+
.unwrap_or_else(|err| panic!("getnetworkinfo failed: {err}"));
284+
assert_eq!(
285+
result.get("localservices").and_then(|v| v.as_str()),
286+
Some("0000000000000049")
287+
);
288+
let names: Vec<String> = result
289+
.get("localservicesnames")
290+
.and_then(|v| v.as_array())
291+
.map(|arr| {
292+
arr.iter()
293+
.filter_map(|n| n.as_str().map(str::to_owned))
294+
.collect()
295+
})
296+
.unwrap_or_default();
297+
assert!(names.contains(&"NETWORK".to_owned()));
298+
assert!(names.contains(&"WITNESS".to_owned()));
299+
assert!(names.contains(&"COMPACT_FILTERS".to_owned()));
300+
}
301+
302+
#[test]
303+
fn local_services_flags_hex_matches_bitmask() {
304+
assert_eq!(format!("{LOCAL_SERVICES_FLAGS:016x}"), LOCAL_SERVICES_HEX);
305+
}
264306
}
265307
#[cfg(test)]
266308
mod ping_tests {

0 commit comments

Comments
 (0)