Skip to content

Commit cd84757

Browse files
authored
Merge pull request #2891 from TheBlueMatt/2024-02-no-ahash
Drop the `ahash` dependency
2 parents 6fa1cb2 + eecd2cd commit cd84757

File tree

19 files changed

+264
-171
lines changed

19 files changed

+264
-171
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ jobs:
110110
run: |
111111
cd lightning
112112
RUSTFLAGS="--cfg=require_route_graph_test" cargo test
113-
RUSTFLAGS="--cfg=require_route_graph_test" cargo test --features hashbrown,ahash
113+
RUSTFLAGS="--cfg=require_route_graph_test" cargo test --features hashbrown
114114
cd ..
115115
- name: Run benchmarks on Rust ${{ matrix.toolchain }}
116116
run: |

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ members = [
1111
"lightning-rapid-gossip-sync",
1212
"lightning-custom-message",
1313
"lightning-transaction-sync",
14+
"possiblyrandom",
1415
]
1516

1617
exclude = [
@@ -38,3 +39,6 @@ lto = "off"
3839
opt-level = 3
3940
lto = true
4041
panic = "abort"
42+
43+
[patch.crates-io.possiblyrandom]
44+
path = "possiblyrandom"

bench/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ name = "bench"
99
harness = false
1010

1111
[features]
12-
hashbrown = ["lightning/hashbrown", "lightning/ahash"]
12+
hashbrown = ["lightning/hashbrown"]
1313

1414
[dependencies]
1515
lightning = { path = "../lightning", features = ["_test_utils", "criterion"] }

ci/check-cfg-flags.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ def check_feature(feature):
1313
pass
1414
elif feature == "no-std":
1515
pass
16-
elif feature == "ahash":
16+
elif feature == "possiblyrandom":
17+
pass
18+
elif feature == "getrandom":
1719
pass
1820
elif feature == "hashbrown":
1921
pass

fuzz/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ lightning = { path = "../lightning", features = ["regex", "hashbrown", "_test_ut
2222
lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync" }
2323
bitcoin = { version = "0.30.2", features = ["secp-lowmemory"] }
2424
hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
25-
hashbrown = "0.13"
2625

2726
afl = { version = "0.12", optional = true }
2827
honggfuzz = { version = "0.5", optional = true, default-features = false }

fuzz/src/chanmon_consistency.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use lightning::offers::invoice_request::UnsignedInvoiceRequest;
5151
use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath};
5252
use lightning::util::test_channel_signer::{TestChannelSigner, EnforcementState};
5353
use lightning::util::errors::APIError;
54+
use lightning::util::hash_tables::*;
5455
use lightning::util::logger::Logger;
5556
use lightning::util::config::UserConfig;
5657
use lightning::util::ser::{Readable, ReadableArgs, Writeable, Writer};
@@ -66,7 +67,6 @@ use bitcoin::secp256k1::schnorr;
6667

6768
use std::mem;
6869
use std::cmp::{self, Ordering};
69-
use hashbrown::{HashSet, hash_map, HashMap};
7070
use std::sync::{Arc,Mutex};
7171
use std::sync::atomic;
7272
use std::io::Cursor;
@@ -157,7 +157,7 @@ impl TestChainMonitor {
157157
logger,
158158
keys,
159159
persister,
160-
latest_monitors: Mutex::new(HashMap::new()),
160+
latest_monitors: Mutex::new(new_hash_map()),
161161
}
162162
}
163163
}
@@ -173,16 +173,13 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
173173

174174
fn update_channel(&self, funding_txo: OutPoint, update: &channelmonitor::ChannelMonitorUpdate) -> chain::ChannelMonitorUpdateStatus {
175175
let mut map_lock = self.latest_monitors.lock().unwrap();
176-
let mut map_entry = match map_lock.entry(funding_txo) {
177-
hash_map::Entry::Occupied(entry) => entry,
178-
hash_map::Entry::Vacant(_) => panic!("Didn't have monitor on update call"),
179-
};
176+
let map_entry = map_lock.get_mut(&funding_txo).expect("Didn't have monitor on update call");
180177
let deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::
181-
read(&mut Cursor::new(&map_entry.get().1), (&*self.keys, &*self.keys)).unwrap().1;
178+
read(&mut Cursor::new(&map_entry.1), (&*self.keys, &*self.keys)).unwrap().1;
182179
deserialized_monitor.update_monitor(update, &&TestBroadcaster{}, &&FuzzEstimator { ret_val: atomic::AtomicU32::new(253) }, &self.logger).unwrap();
183180
let mut ser = VecWriter(Vec::new());
184181
deserialized_monitor.write(&mut ser).unwrap();
185-
map_entry.insert((update.update_id, ser.0));
182+
*map_entry = (update.update_id, ser.0);
186183
self.chain_monitor.update_channel(funding_txo, update)
187184
}
188185

@@ -467,7 +464,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
467464
($node_id: expr, $fee_estimator: expr) => { {
468465
let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
469466
let node_secret = SecretKey::from_slice(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, $node_id]).unwrap();
470-
let keys_manager = Arc::new(KeyProvider { node_secret, rand_bytes_id: atomic::AtomicU32::new(0), enforcement_states: Mutex::new(HashMap::new()) });
467+
let keys_manager = Arc::new(KeyProvider { node_secret, rand_bytes_id: atomic::AtomicU32::new(0), enforcement_states: Mutex::new(new_hash_map()) });
471468
let monitor = Arc::new(TestChainMonitor::new(broadcast.clone(), logger.clone(), $fee_estimator.clone(),
472469
Arc::new(TestPersister {
473470
update_ret: Mutex::new(ChannelMonitorUpdateStatus::Completed)
@@ -508,13 +505,13 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
508505
config.manually_accept_inbound_channels = true;
509506
}
510507

511-
let mut monitors = HashMap::new();
508+
let mut monitors = new_hash_map();
512509
let mut old_monitors = $old_monitors.latest_monitors.lock().unwrap();
513510
for (outpoint, (update_id, monitor_ser)) in old_monitors.drain() {
514511
monitors.insert(outpoint, <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(&mut Cursor::new(&monitor_ser), (&*$keys_manager, &*$keys_manager)).expect("Failed to read monitor").1);
515512
chain_monitor.latest_monitors.lock().unwrap().insert(outpoint, (update_id, monitor_ser));
516513
}
517-
let mut monitor_refs = HashMap::new();
514+
let mut monitor_refs = new_hash_map();
518515
for (outpoint, monitor) in monitors.iter_mut() {
519516
monitor_refs.insert(*outpoint, monitor);
520517
}
@@ -981,7 +978,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
981978
// In case we get 256 payments we may have a hash collision, resulting in the
982979
// second claim/fail call not finding the duplicate-hash HTLC, so we have to
983980
// deduplicate the calls here.
984-
let mut claim_set = HashSet::new();
981+
let mut claim_set = new_hash_map();
985982
let mut events = nodes[$node].get_and_clear_pending_events();
986983
// Sort events so that PendingHTLCsForwardable get processed last. This avoids a
987984
// case where we first process a PendingHTLCsForwardable, then claim/fail on a
@@ -1003,7 +1000,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
10031000
for event in events.drain(..) {
10041001
match event {
10051002
events::Event::PaymentClaimable { payment_hash, .. } => {
1006-
if claim_set.insert(payment_hash.0) {
1003+
if claim_set.insert(payment_hash.0, ()).is_none() {
10071004
if $fail {
10081005
nodes[$node].fail_htlc_backwards(&payment_hash);
10091006
} else {

fuzz/src/full_stack.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use lightning::routing::gossip::{P2PGossipSync, NetworkGraph};
4949
use lightning::routing::utxo::UtxoLookup;
5050
use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router};
5151
use lightning::util::config::{ChannelConfig, UserConfig};
52+
use lightning::util::hash_tables::*;
5253
use lightning::util::errors::APIError;
5354
use lightning::util::test_channel_signer::{TestChannelSigner, EnforcementState};
5455
use lightning::util::logger::Logger;
@@ -63,7 +64,6 @@ use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
6364
use bitcoin::secp256k1::schnorr;
6465

6566
use std::cell::RefCell;
66-
use hashbrown::{HashMap, hash_map};
6767
use std::convert::TryInto;
6868
use std::cmp;
6969
use std::sync::{Arc, Mutex};
@@ -229,7 +229,7 @@ impl<'a> MoneyLossDetector<'a> {
229229

230230
peers,
231231
funding_txn: Vec::new(),
232-
txids_confirmed: HashMap::new(),
232+
txids_confirmed: new_hash_map(),
233233
header_hashes: vec![(genesis_block(Network::Bitcoin).block_hash(), 0)],
234234
height: 0,
235235
max_height: 0,
@@ -241,13 +241,10 @@ impl<'a> MoneyLossDetector<'a> {
241241
let mut txdata = Vec::with_capacity(all_txn.len());
242242
for (idx, tx) in all_txn.iter().enumerate() {
243243
let txid = tx.txid();
244-
match self.txids_confirmed.entry(txid) {
245-
hash_map::Entry::Vacant(e) => {
246-
e.insert(self.height);
247-
txdata.push((idx + 1, tx));
248-
},
249-
_ => {},
250-
}
244+
self.txids_confirmed.entry(txid).or_insert_with(|| {
245+
txdata.push((idx + 1, tx));
246+
self.height
247+
});
251248
}
252249

253250
self.blocks_connected += 1;
@@ -489,7 +486,7 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
489486
node_secret: our_network_key.clone(),
490487
inbound_payment_key: KeyMaterial(inbound_payment_key.try_into().unwrap()),
491488
counter: AtomicU64::new(0),
492-
signer_state: RefCell::new(HashMap::new())
489+
signer_state: RefCell::new(new_hash_map())
493490
});
494491
let network = Network::Bitcoin;
495492
let best_block_timestamp = genesis_block(network).header.time;
@@ -518,7 +515,7 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
518515
let mut intercepted_htlcs: Vec<InterceptId> = Vec::new();
519516
let mut payments_sent: u16 = 0;
520517
let mut pending_funding_generation: Vec<(ChannelId, PublicKey, u64, ScriptBuf)> = Vec::new();
521-
let mut pending_funding_signatures = HashMap::new();
518+
let mut pending_funding_signatures = new_hash_map();
522519

523520
loop {
524521
match get_slice!(1)[0] {

fuzz/src/indexedmap.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
use lightning::util::indexed_map::{IndexedMap, self};
1111
use std::collections::{BTreeMap, btree_map};
12-
use hashbrown::HashSet;
12+
use lightning::util::hash_tables::*;
1313

1414
use crate::utils::test_logger;
1515

@@ -80,23 +80,23 @@ fn check_eq(btree: &BTreeMap<u8, u8>, mut indexed: IndexedMap<u8, u8>) {
8080
}
8181
}
8282

83-
let mut key_set = HashSet::with_capacity(256);
83+
let mut key_set = hash_map_with_capacity(1024);
8484
for k in indexed.unordered_keys() {
85-
assert!(key_set.insert(*k));
85+
assert!(key_set.insert(*k, ()).is_none());
8686
assert!(btree.contains_key(k));
8787
}
8888
assert_eq!(key_set.len(), btree.len());
8989

9090
key_set.clear();
9191
for (k, v) in indexed.unordered_iter() {
92-
assert!(key_set.insert(*k));
92+
assert!(key_set.insert(*k, ()).is_none());
9393
assert_eq!(btree.get(k).unwrap(), v);
9494
}
9595
assert_eq!(key_set.len(), btree.len());
9696

9797
key_set.clear();
9898
for (k, v) in indexed_clone.unordered_iter_mut() {
99-
assert!(key_set.insert(*k));
99+
assert!(key_set.insert(*k, ()).is_none());
100100
assert_eq!(btree.get(k).unwrap(), v);
101101
}
102102
assert_eq!(key_set.len(), btree.len());

fuzz/src/router.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use lightning::routing::utxo::{UtxoFuture, UtxoLookup, UtxoLookupError, UtxoResu
2323
use lightning::routing::router::{find_route, PaymentParameters, RouteHint, RouteHintHop, RouteParameters};
2424
use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters, ProbabilisticScoringDecayParameters};
2525
use lightning::util::config::UserConfig;
26+
use lightning::util::hash_tables::*;
2627
use lightning::util::ser::Readable;
2728

2829
use bitcoin::hashes::Hash;
@@ -32,7 +33,6 @@ use bitcoin::network::constants::Network;
3233
use crate::utils::test_logger;
3334

3435
use std::convert::TryInto;
35-
use hashbrown::HashSet;
3636
use std::sync::Arc;
3737
use std::sync::atomic::{AtomicUsize, Ordering};
3838

@@ -198,7 +198,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
198198
net_graph: &net_graph,
199199
};
200200

201-
let mut node_pks = HashSet::new();
201+
let mut node_pks = new_hash_map();
202202
let mut scid = 42;
203203

204204
macro_rules! first_hops {
@@ -208,7 +208,8 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
208208
count => {
209209
for _ in 0..count {
210210
scid += 1;
211-
let rnid = node_pks.iter().skip(u16::from_be_bytes(get_slice!(2).try_into().unwrap()) as usize % node_pks.len()).next().unwrap();
211+
let (rnid, _) =
212+
node_pks.iter().skip(u16::from_be_bytes(get_slice!(2).try_into().unwrap()) as usize % node_pks.len()).next().unwrap();
212213
let capacity = u64::from_be_bytes(get_slice!(8).try_into().unwrap());
213214
$first_hops_vec.push(ChannelDetails {
214215
channel_id: ChannelId::new_zero(),
@@ -257,7 +258,8 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
257258
let count = get_slice!(1)[0];
258259
for _ in 0..count {
259260
scid += 1;
260-
let rnid = node_pks.iter().skip(slice_to_be16(get_slice!(2))as usize % node_pks.len()).next().unwrap();
261+
let (rnid, _) =
262+
node_pks.iter().skip(slice_to_be16(get_slice!(2)) as usize % node_pks.len()).next().unwrap();
261263
$last_hops.push(RouteHint(vec![RouteHintHop {
262264
src_node_id: *rnid,
263265
short_channel_id: scid,
@@ -277,7 +279,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
277279
($first_hops: expr, $node_pks: expr, $route_params: expr) => {
278280
let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &net_graph, &logger);
279281
let random_seed_bytes: [u8; 32] = [get_slice!(1)[0]; 32];
280-
for target in $node_pks {
282+
for (target, ()) in $node_pks {
281283
let final_value_msat = slice_to_be64(get_slice!(8));
282284
let final_cltv_expiry_delta = slice_to_be32(get_slice!(4));
283285
let route_params = $route_params(final_value_msat, final_cltv_expiry_delta, target);
@@ -297,20 +299,20 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
297299
return;
298300
}
299301
let msg = decode_msg_with_len16!(msgs::UnsignedNodeAnnouncement, 288);
300-
node_pks.insert(get_pubkey_from_node_id!(msg.node_id));
302+
node_pks.insert(get_pubkey_from_node_id!(msg.node_id), ());
301303
let _ = net_graph.update_node_from_unsigned_announcement(&msg);
302304
},
303305
1 => {
304306
let msg = decode_msg_with_len16!(msgs::UnsignedChannelAnnouncement, 32+8+33*4);
305-
node_pks.insert(get_pubkey_from_node_id!(msg.node_id_1));
306-
node_pks.insert(get_pubkey_from_node_id!(msg.node_id_2));
307+
node_pks.insert(get_pubkey_from_node_id!(msg.node_id_1), ());
308+
node_pks.insert(get_pubkey_from_node_id!(msg.node_id_2), ());
307309
let _ = net_graph.update_channel_from_unsigned_announcement::
308310
<&FuzzChainSource<'_, '_, Out>>(&msg, &None);
309311
},
310312
2 => {
311313
let msg = decode_msg_with_len16!(msgs::UnsignedChannelAnnouncement, 32+8+33*4);
312-
node_pks.insert(get_pubkey_from_node_id!(msg.node_id_1));
313-
node_pks.insert(get_pubkey_from_node_id!(msg.node_id_2));
314+
node_pks.insert(get_pubkey_from_node_id!(msg.node_id_1), ());
315+
node_pks.insert(get_pubkey_from_node_id!(msg.node_id_2), ());
314316
let _ = net_graph.update_channel_from_unsigned_announcement(&msg, &Some(&chain_source));
315317
},
316318
3 => {
@@ -367,7 +369,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
367369
}).collect();
368370
let mut features = Bolt12InvoiceFeatures::empty();
369371
features.set_basic_mpp_optional();
370-
find_routes!(first_hops, vec![dummy_pk].iter(), |final_amt, _, _| {
372+
find_routes!(first_hops, [(dummy_pk, ())].iter(), |final_amt, _, _| {
371373
RouteParameters::from_payment_params_and_value(PaymentParameters::blinded(last_hops.clone())
372374
.with_bolt12_features(features.clone()).unwrap(),
373375
final_amt)

lightning-invoice/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ rustdoc-args = ["--cfg", "docsrs"]
1616

1717
[features]
1818
default = ["std"]
19-
no-std = ["hashbrown", "lightning/no-std"]
19+
no-std = ["lightning/no-std"]
2020
std = ["bitcoin/std", "num-traits/std", "lightning/std", "bech32/std"]
2121

2222
[dependencies]
2323
bech32 = { version = "0.9.0", default-features = false }
2424
lightning = { version = "0.0.121", path = "../lightning", default-features = false }
2525
secp256k1 = { version = "0.27.0", default-features = false, features = ["recovery", "alloc"] }
2626
num-traits = { version = "0.2.8", default-features = false }
27-
hashbrown = { version = "0.13", optional = true }
2827
serde = { version = "1.0.118", optional = true }
2928
bitcoin = { version = "0.30.2", default-features = false }
3029

3130
[dev-dependencies]
3231
lightning = { version = "0.0.121", path = "../lightning", default-features = false, features = ["_test_utils"] }
3332
hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
3433
serde_json = { version = "1"}
34+
hashbrown = { version = "0.13", default-features = false }

lightning-invoice/src/lib.rs

-7
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,7 @@ mod tb;
7979

8080
#[allow(unused_imports)]
8181
mod prelude {
82-
#[cfg(feature = "hashbrown")]
83-
extern crate hashbrown;
84-
8582
pub use alloc::{vec, vec::Vec, string::String};
86-
#[cfg(not(feature = "hashbrown"))]
87-
pub use std::collections::{HashMap, hash_map};
88-
#[cfg(feature = "hashbrown")]
89-
pub use self::hashbrown::{HashMap, HashSet, hash_map};
9083

9184
pub use alloc::string::ToString;
9285
}

lightning-invoice/src/utils.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use lightning::routing::gossip::RoutingFees;
1616
use lightning::routing::router::{RouteHint, RouteHintHop, Router};
1717
use lightning::util::logger::{Logger, Record};
1818
use secp256k1::PublicKey;
19+
use alloc::collections::{btree_map, BTreeMap};
1920
use core::ops::Deref;
2021
use core::time::Duration;
2122
use core::iter::Iterator;
@@ -603,7 +604,7 @@ fn sort_and_filter_channels<L: Deref>(
603604
where
604605
L::Target: Logger,
605606
{
606-
let mut filtered_channels: HashMap<PublicKey, ChannelDetails> = HashMap::new();
607+
let mut filtered_channels: BTreeMap<PublicKey, ChannelDetails> = BTreeMap::new();
607608
let min_inbound_capacity = min_inbound_capacity_msat.unwrap_or(0);
608609
let mut min_capacity_channel_exists = false;
609610
let mut online_channel_exists = false;
@@ -664,7 +665,7 @@ where
664665
}
665666

666667
match filtered_channels.entry(channel.counterparty.node_id) {
667-
hash_map::Entry::Occupied(mut entry) => {
668+
btree_map::Entry::Occupied(mut entry) => {
668669
let current_max_capacity = entry.get().inbound_capacity_msat;
669670
// If this channel is public and the previous channel is not, ensure we replace the
670671
// previous channel to avoid announcing non-public channels.
@@ -697,7 +698,7 @@ where
697698
channel.inbound_capacity_msat);
698699
}
699700
}
700-
hash_map::Entry::Vacant(entry) => {
701+
btree_map::Entry::Vacant(entry) => {
701702
entry.insert(channel);
702703
}
703704
}

0 commit comments

Comments
 (0)