run: |
cd lightning
RUSTFLAGS="--cfg=require_route_graph_test" cargo test
- RUSTFLAGS="--cfg=require_route_graph_test" cargo test --features hashbrown
+ RUSTFLAGS="--cfg=require_route_graph_test" cargo test --features hashbrown,ahash
cd ..
- name: Run benchmarks on Rust ${{ matrix.toolchain }}
run: |
fuzz:
runs-on: ubuntu-latest
env:
- TOOLCHAIN: 1.58
+ TOOLCHAIN: 1.63
steps:
- name: Checkout source code
uses: actions/checkout@v3
run: |
sudo apt-get update
sudo apt-get -y install build-essential binutils-dev libunwind-dev
+ - name: Pin the regex dependency
+ run: |
+ cd fuzz && cargo update -p regex --precise "1.9.6" --verbose && cd ..
+ cd lightning-invoice/fuzz && cargo update -p regex --precise "1.9.6" --verbose
- name: Sanity check fuzz targets on Rust ${{ env.TOOLCHAIN }}
run: cd fuzz && RUSTFLAGS="--cfg=fuzzing" cargo test --verbose --color always
- name: Run fuzzers
harness = false
[features]
-hashbrown = ["lightning/hashbrown"]
+hashbrown = ["lightning/hashbrown", "lightning/ahash"]
[dependencies]
lightning = { path = "../lightning", features = ["_test_utils", "criterion"] }
pass
elif feature == "no-std":
pass
+ elif feature == "ahash":
+ pass
elif feature == "hashbrown":
pass
elif feature == "backtrace":
lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync" }
bitcoin = { version = "0.30.2", features = ["secp-lowmemory"] }
hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
-hashbrown = "0.8"
+hashbrown = "0.13"
afl = { version = "0.12", optional = true }
honggfuzz = { version = "0.5", optional = true, default-features = false }
})
}
- fn create_blinded_payment_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
+ fn create_blinded_payment_paths<T: secp256k1::Signing + secp256k1::Verification>(
&self, _recipient: PublicKey, _first_hops: Vec<ChannelDetails>, _tlvs: ReceiveTlvs,
- _amount_msats: u64, _entropy_source: &ES, _secp_ctx: &Secp256k1<T>
+ _amount_msats: u64, _secp_ctx: &Secp256k1<T>,
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
unreachable!()
}
unreachable!()
}
- fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
- &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES,
- _secp_ctx: &Secp256k1<T>
+ fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
+ &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
unreachable!()
}
use lightning::routing::gossip::{P2PGossipSync, NetworkGraph};
use lightning::routing::utxo::UtxoLookup;
use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router};
-use lightning::util::config::{UserConfig, MaxDustHTLCExposure};
+use lightning::util::config::UserConfig;
use lightning::util::errors::APIError;
use lightning::util::test_channel_signer::{TestChannelSigner, EnforcementState};
use lightning::util::logger::Logger;
-use lightning::util::ser::{ReadableArgs, Writeable};
+use lightning::util::ser::{Readable, ReadableArgs, Writeable};
use crate::utils::test_logger;
use crate::utils::test_persister::TestPersister;
})
}
- fn create_blinded_payment_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
+ fn create_blinded_payment_paths<T: secp256k1::Signing + secp256k1::Verification>(
&self, _recipient: PublicKey, _first_hops: Vec<ChannelDetails>, _tlvs: ReceiveTlvs,
- _amount_msats: u64, _entropy_source: &ES, _secp_ctx: &Secp256k1<T>
+ _amount_msats: u64, _secp_ctx: &Secp256k1<T>,
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
unreachable!()
}
unreachable!()
}
- fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
- &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES,
- _secp_ctx: &Secp256k1<T>
+ fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
+ &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
unreachable!()
}
}
#[inline]
-pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
+pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
+ if data.len() < 32 { return; }
+
+ let our_network_key = match SecretKey::from_slice(&data[..32]) {
+ Ok(key) => key,
+ Err(e) => return,
+ };
+ data = &data[32..];
+
+ let config: UserConfig = if let Ok(config) = Readable::read(&mut data) { config } else { return; };
+
let input = Arc::new(InputData {
data: data.to_vec(),
read_pos: AtomicUsize::new(0),
}
}
- let our_network_key = match SecretKey::from_slice(get_slice!(32)) {
- Ok(key) => key,
- Err(_) => return,
- };
let inbound_payment_key = [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, 0, 42];
counter: AtomicU64::new(0),
signer_state: RefCell::new(HashMap::new())
});
- let mut config = UserConfig::default();
- config.channel_config.forwarding_fee_proportional_millionths = slice_to_be32(get_slice!(4));
- config.channel_config.max_dust_htlc_exposure = MaxDustHTLCExposure::FeeRateMultiplier(5_000_000 / 253);
- config.channel_handshake_config.announced_channel = get_slice!(1)[0] != 0;
let network = Network::Bitcoin;
let best_block_timestamp = genesis_block(network).header.time;
let params = ChainParameters {
// Writing new code generating transactions and see a new failure ? Don't forget to add input for the FuzzEstimator !
// 0100000000000000000000000000000000000000000000000000000000000000 - our network key
- // 00000000 - fee_proportional_millionths
- // 01 - announce_channels_publicly
+ // 0000000000900000000000000000640001000000000001ffff0000000000000000ffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff000000ffffffff00ffff1a000400010000020400000000040200000a08ffffffffffffffff0001000000 - config
//
// 00 - new outbound connection with id 0
// 030000000000000000000000000000000000000000000000000000000000000002 - peer's pubkey
// 030012 - inbound read from peer id 0 of len 18
// 0010 03000000000000000000000000000000 - message header indicating message length 16
// 030020 - inbound read from peer id 0 of len 32
- // 0010 00021aaa 0008aaaaaaaaaaaa9aaa 03000000000000000000000000000000 - init message (type 16) with static_remotekey required and other bits optional and mac
+ // 0010 00021aaa 0008aaa20aaa2a0a9aaa 03000000000000000000000000000000 - init message (type 16) with static_remotekey required, no channel_type/anchors/taproot, and other bits optional and mac
//
// 030012 - inbound read from peer id 0 of len 18
// 0147 03000000000000000000000000000000 - message header indicating message length 327
// 030112 - inbound read from peer id 1 of len 18
// 0010 01000000000000000000000000000000 - message header indicating message length 16
// 030120 - inbound read from peer id 1 of len 32
- // 0010 00021aaa 0008aaaaaaaaaaaa9aaa 01000000000000000000000000000000 - init message (type 16) with static_remotekey required and other bits optional and mac
+ // 0010 00021aaa 0008aaa20aaa2a0a9aaa 01000000000000000000000000000000 - init message (type 16) with static_remotekey required, no channel_type/anchors/taproot, and other bits optional and mac
//
// 05 01 030200000000000000000000000000000000000000000000000000000000000000 00c350 0003e8 - create outbound channel to peer 1 for 50k sat
// 00fd - One feerate requests (all returning min feerate) (gonna be ingested by FuzzEstimator)
//
// 0a - create the funding transaction (client should send funding_created now)
//
- // 00fd00fd - Two feerate requests (calculating max dust exposure) (all returning min feerate) (gonna be ingested by FuzzEstimator)
- //
// 030112 - inbound read from peer id 1 of len 18
// 0062 01000000000000000000000000000000 - message header indicating message length 98
// 030172 - inbound read from peer id 1 of len 114
// 0300c1 - inbound read from peer id 0 of len 193
// ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ab00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
//
- // 00fd - One feerate request (calculating max dust exposure) (all returning min feerate) (gonna be ingested by FuzzEstimator)
- //
// 030012 - inbound read from peer id 0 of len 18
// 0064 03000000000000000000000000000000 - message header indicating message length 100
// 030074 - inbound read from peer id 0 of len 116
// 07 - process the now-pending HTLC forward
// - client now sends id 1 update_add_htlc and commitment_signed (CHECK 7: UpdateHTLCs event for node 03020000 with 1 HTLCs for channel 3f000000)
//
- // 00fd00fd - Two feerate requests (calculating max dust exposure) (all returning min feerate) (gonna be ingested by FuzzEstimator)
- //
// - we respond with commitment_signed then revoke_and_ack (a weird, but valid, order)
// 030112 - inbound read from peer id 1 of len 18
// 0064 01000000000000000000000000000000 - message header indicating message length 100
// 0300c1 - inbound read from peer id 0 of len 193
// ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ab00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
//
- // 00fd - One feerate request (calculating max dust exposure) (all returning min feerate) (gonna be ingested by FuzzEstimator)
- //
// - now respond to the update_fulfill_htlc+commitment_signed messages the client sent to peer 0
// 030012 - inbound read from peer id 0 of len 18
// 0063 03000000000000000000000000000000 - message header indicating message length 99
// - client now sends id 1 update_add_htlc and commitment_signed (CHECK 7 duplicate)
// - we respond with revoke_and_ack, then commitment_signed, then update_fail_htlc
//
- // 00fd00fd - Two feerate requests (calculating max dust exposure) (all returning min feerate) (gonna be ingested by FuzzEstimator)
- //
// 030112 - inbound read from peer id 1 of len 18
// 0064 01000000000000000000000000000000 - message header indicating message length 100
// 030174 - inbound read from peer id 1 of len 116
// 0300c1 - inbound read from peer id 0 of len 193
// ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 5300000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
//
- // 00fd - One feerate request (calculating max dust exposure) (all returning min feerate) (gonna be ingested by FuzzEstimator)
- //
// 030012 - inbound read from peer id 0 of len 18
// 00a4 03000000000000000000000000000000 - message header indicating message length 164
// 0300b4 - inbound read from peer id 0 of len 180
// 07 - process the now-pending HTLC forward
// - client now sends id 1 update_add_htlc and commitment_signed (CHECK 7 duplicate)
//
- // 00fd00fd - Two feerate requests (calculating max dust exposure) (all returning min feerate) (gonna be ingested by FuzzEstimator)
- //
// 0c007d - connect a block with one transaction of len 125
// 02000000013a000000000000000000000000000000000000000000000000000000000000000000000000000000800258020000000000002200204b0000000000000000000000000000000000000000000000000000000000000014c0000000000000160014280000000000000000000000000000000000000005000020 - the commitment transaction for channel 3f00000000000000000000000000000000000000000000000000000000000000
//
// - client now fails the HTLC backwards as it was unable to extract the payment preimage (CHECK 9 duplicate and CHECK 10)
let logger = Arc::new(TrackingLogger { lines: Mutex::new(HashMap::new()) });
- super::do_test(&<Vec<u8>>::from_hex("01000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000020300320003000000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000030012001003000000000000000000000000000000030020001000021aaa0008aaaaaaaaaaaa9aaa030000000000000000000000000000000300120147030000000000000000000000000000000300fe00206fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000162ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030059030000000000000000000000000000000000000000000000000000000000000005020900000000000000000000000000000000000000000000000000000000000000010000010210000300000000000000000000000000000000fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d0000000000000000000000000000000000000000000000000000000000000002080000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000010301320003000000000000000000000000000000000000000000000000000000000000000703000000000000000000000000000000030142000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000030112001001000000000000000000000000000000030120001000021aaa0008aaaaaaaaaaaa9aaa01000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd0301120112010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e05000000000000016200000000004c4b4000000000000003e800000000000003e80000000203f000050300000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000002000300000000000000000000000000000000000000000000000000000000000003000300000000000000000000000000000000000000000000000000000000000004000300000000000000000000000000000000000000000000000000000000000005000266000000000000000000000000000003012300000000000000000000000000000000000000010000000000000000000000000000000a00fd00fd03011200620100000000000000000000000000000003017200233a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c0001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000b03011200430100000000000000000000000000000003015300243a000000000000000000000000000000000000000000000000000000000000000267000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f00003000000000000000000000000000000000000000000000000000000000000055511020203e80401a0060800000e00000100000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffab000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000020b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000700fd00fd03011200640100000000000000000000000000000003017400843a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000002640000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a00823a000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000000265000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f00003000000000000000000000000000000000000000000000000000000000000055511020203e80401a0060800000e00000100000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffab000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000020a000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c3010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000020d00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000700fd00fd03011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833a00000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020c000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005551202030927c00401a0060800000e00000100000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff53000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007501000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006705000000000000000000000000000000000000000000000000000000000000060300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000020f00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000700fd00fd0c007d02000000013a000000000000000000000000000000000000000000000000000000000000000000000000000000800258020000000000002200204b0000000000000000000000000000000000000000000000000000000000000014c00000000000001600142800000000000000000000000000000000000000050000200c005e0200000001730000000000000000000000000000000000000000000000000000000000000000000000000000000001a701000000000000220020b200000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc<dyn Logger>));
+ super::do_test(&<Vec<u8>>::from_hex("01000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000640001000000000001ffff0000000000000000ffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff000000ffffffff00ffff1a000400010000020400000000040200000a08ffffffffffffffff0001000000000300000000000000000000000000000000000000000000000000000000000000020300320003000000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000030012001003000000000000000000000000000000030020001000021aaa0008aaa20aaa2a0a9aaa030000000000000000000000000000000300120147030000000000000000000000000000000300fe00206fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000162ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030059030000000000000000000000000000000000000000000000000000000000000005020900000000000000000000000000000000000000000000000000000000000000010000010210000300000000000000000000000000000000fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d0000000000000000000000000000000000000000000000000000000000000002080000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000010301320003000000000000000000000000000000000000000000000000000000000000000703000000000000000000000000000000030142000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000030112001001000000000000000000000000000000030120001000021aaa0008aaa20aaa2a0a9aaa01000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd0301120112010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e05000000000000016200000000004c4b4000000000000003e800000000000003e80000000203f000050300000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000002000300000000000000000000000000000000000000000000000000000000000003000300000000000000000000000000000000000000000000000000000000000004000300000000000000000000000000000000000000000000000000000000000005000266000000000000000000000000000003012300000000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c0001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000b03011200430100000000000000000000000000000003015300243a000000000000000000000000000000000000000000000000000000000000000267000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f00003000000000000000000000000000000000000000000000000000000000000055511020203e80401a0060800000e00000100000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffab000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000020b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000002640000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a00823a000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000000265000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f00003000000000000000000000000000000000000000000000000000000000000055511020203e80401a0060800000e00000100000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffab000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000020a000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c3010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000020d00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833a00000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020c000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005551202030927c00401a0060800000e00000100000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff53000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007501000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006705000000000000000000000000000000000000000000000000000000000000060300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000020f0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013a000000000000000000000000000000000000000000000000000000000000000000000000000000800258020000000000002200204b0000000000000000000000000000000000000000000000000000000000000014c00000000000001600142800000000000000000000000000000000000000050000200c005e0200000001730000000000000000000000000000000000000000000000000000000000000000000000000000000001a701000000000000220020b200000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc<dyn Logger>));
let log_entries = logger.lines.lock().unwrap();
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendAcceptChannel event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 for channel ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679".to_string())), Some(&1)); // 1
})
}
- fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
- &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES,
- _secp_ctx: &Secp256k1<T>
+ fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
+ &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
unreachable!()
}
Ok(len) => len,
Err(_) => return,
};
- buf.copy_from_slice(&get_slice!(len as usize + 16));
+ buf[..len as usize + 16].copy_from_slice(&get_slice!(len as usize + 16));
match crypter.decrypt_message(&mut buf[..len as usize + 16]) {
Ok(_) => {},
Err(_) => return,
Arc<DefaultRouter<
Arc<NetworkGraph<Arc<test_utils::TestLogger>>>,
Arc<test_utils::TestLogger>,
+ Arc<KeysManager>,
Arc<LockingWrapper<TestScorer>>,
(),
TestScorer>
let genesis_block = genesis_block(network);
let network_graph = Arc::new(NetworkGraph::new(network, logger.clone()));
let scorer = Arc::new(LockingWrapper::new(TestScorer::new()));
+ let now = Duration::from_secs(genesis_block.header.time as u64);
let seed = [i as u8; 32];
- let router = Arc::new(DefaultRouter::new(network_graph.clone(), logger.clone(), seed, scorer.clone(), Default::default()));
+ let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_nanos()));
+ let router = Arc::new(DefaultRouter::new(network_graph.clone(), logger.clone(), Arc::clone(&keys_manager), scorer.clone(), Default::default()));
let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Bitcoin));
let kv_store = Arc::new(FilesystemStore::new(format!("{}_persister_{}", &persist_dir, i).into()));
- let now = Duration::from_secs(genesis_block.header.time as u64);
- let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_nanos()));
let chain_monitor = Arc::new(chainmonitor::ChainMonitor::new(Some(chain_source.clone()), tx_broadcaster.clone(), logger.clone(), fee_estimator.clone(), kv_store.clone()));
let best_block = BestBlock::from_network(network);
let params = ChainParameters { network, best_block };
lightning = { version = "0.0.121", path = "../lightning", default-features = false }
secp256k1 = { version = "0.27.0", default-features = false, features = ["recovery", "alloc"] }
num-traits = { version = "0.2.8", default-features = false }
-hashbrown = { version = "0.8", optional = true }
+hashbrown = { version = "0.13", optional = true }
serde = { version = "1.0.118", optional = true }
bitcoin = { version = "0.30.2", default-features = false }
+++ /dev/null
-use core::fmt::Debug;
-use core::fmt::Formatter;
-use lightning::ln::msgs::{DecodeError, LightningError};
-
-/// All-encompassing standard error type that processing can return
-pub enum GraphSyncError {
- /// Error trying to read the update data, typically due to an erroneous data length indication
- /// that is greater than the actual amount of data provided
- DecodeError(DecodeError),
- /// Error applying the patch to the network graph, usually the result of updates that are too
- /// old or missing prerequisite data to the application of updates out of order
- LightningError(LightningError),
-}
-
-impl From<lightning::io::Error> for GraphSyncError {
- fn from(error: lightning::io::Error) -> Self {
- Self::DecodeError(DecodeError::Io(error.kind()))
- }
-}
-
-impl From<DecodeError> for GraphSyncError {
- fn from(error: DecodeError) -> Self {
- Self::DecodeError(error)
- }
-}
-
-impl From<LightningError> for GraphSyncError {
- fn from(error: LightningError) -> Self {
- Self::LightningError(error)
- }
-}
-
-impl Debug for GraphSyncError {
- fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
- match self {
- GraphSyncError::DecodeError(e) => f.write_fmt(format_args!("DecodeError: {:?}", e)),
- GraphSyncError::LightningError(e) => f.write_fmt(format_args!("LightningError: {:?}", e))
- }
- }
-}
use core::sync::atomic::{AtomicBool, Ordering};
use lightning::io;
+use lightning::ln::msgs::{DecodeError, LightningError};
use lightning::routing::gossip::NetworkGraph;
use lightning::util::logger::Logger;
-pub use crate::error::GraphSyncError;
-
-/// Error types that these functions can return
-mod error;
-
/// Core functionality of this crate
mod processing;
+/// All-encompassing standard error type that processing can return
+#[derive(Debug)]
+pub enum GraphSyncError {
+ /// Error trying to read the update data, typically due to an erroneous data length indication
+ /// that is greater than the actual amount of data provided
+ DecodeError(DecodeError),
+ /// Error applying the patch to the network graph, usually the result of updates that are too
+ /// old or missing prerequisite data to the application of updates out of order
+ LightningError(LightningError),
+}
+
+impl From<lightning::io::Error> for GraphSyncError {
+ fn from(error: lightning::io::Error) -> Self {
+ Self::DecodeError(DecodeError::Io(error.kind()))
+ }
+}
+
+impl From<DecodeError> for GraphSyncError {
+ fn from(error: DecodeError) -> Self {
+ Self::DecodeError(error)
+ }
+}
+
+impl From<LightningError> for GraphSyncError {
+ fn from(error: LightningError) -> Self {
+ Self::LightningError(error)
+ }
+}
+
/// The main Rapid Gossip Sync object.
///
/// See [crate-level documentation] for usage.
use lightning::ln::msgs::DecodeError;
use lightning::routing::gossip::NetworkGraph;
use lightning::util::test_utils::TestLogger;
- use crate::RapidGossipSync;
+ use crate::{GraphSyncError, RapidGossipSync};
#[test]
fn test_sync_from_file() {
let start = std::time::Instant::now();
let sync_result = rapid_sync
.sync_network_graph_with_file_path("./res/full_graph.lngossip");
- if let Err(crate::error::GraphSyncError::DecodeError(DecodeError::Io(io_error))) = &sync_result {
+ if let Err(GraphSyncError::DecodeError(DecodeError::Io(io_error))) = &sync_result {
let error_string = format!("Input file lightning-rapid-gossip-sync/res/full_graph.lngossip is missing! Download it from https://bitcoin.ninja/ldk-compressed_graph-285cb27df79-2022-07-21.bin\n\n{:?}", io_error);
#[cfg(not(require_route_graph_test))]
{
use lightning::util::ser::{BigSize, Readable};
use lightning::io;
-use crate::error::GraphSyncError;
-use crate::RapidGossipSync;
+use crate::{GraphSyncError, RapidGossipSync};
#[cfg(all(feature = "std", not(test)))]
use std::time::{SystemTime, UNIX_EPOCH};
use lightning::routing::gossip::NetworkGraph;
use lightning::util::test_utils::TestLogger;
- use crate::error::GraphSyncError;
use crate::processing::STALE_RGS_UPDATE_AGE_LIMIT_SECS;
- use crate::RapidGossipSync;
+ use crate::{GraphSyncError, RapidGossipSync};
const VALID_RGS_BINARY: [u8; 300] = [
76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
# Override signing to not include randomness when generating signatures for test vectors.
_test_vectors = []
-no-std = ["hashbrown", "bitcoin/no-std", "core2/alloc", "libm"]
+no-std = ["hashbrown", "ahash", "bitcoin/no-std", "core2/alloc", "libm"]
std = ["bitcoin/std"]
# Generates low-r bitcoin signatures, which saves 1 byte in 50% of the cases
[dependencies]
bitcoin = { version = "0.30.2", default-features = false, features = ["secp-recovery"] }
-hashbrown = { version = "0.8", optional = true }
+hashbrown = { version = "0.13", optional = true }
+ahash = { version = "0.8", optional = true, default-features = false }
hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
regex = { version = "1.5.6", optional = true }
backtrace = { version = "0.3", optional = true }
core2 = { version = "0.3.0", optional = true, default-features = false }
libm = { version = "0.2", optional = true, default-features = false }
+# Because ahash no longer (kinda poorly) does it for us, (roughly) list out the targets that
+# getrandom supports and turn on ahash's `runtime-rng` feature for them.
+[target.'cfg(not(any(target_os = "unknown", target_os = "none")))'.dependencies]
+ahash = { version = "0.8", optional = true, default-features = false, features = ["runtime-rng"] }
+
+# Not sure what target_os gets set to for sgx, so to be safe always enable runtime-rng for x86_64
+# platforms (assuming LDK isn't being used on embedded x86-64 running directly on metal).
+[target.'cfg(target_arch = "x86_64")'.dependencies]
+ahash = { version = "0.8", optional = true, default-features = false, features = ["runtime-rng"] }
+
[dev-dependencies]
regex = "1.5.6"
use crate::prelude::*;
use crate::sync::{RwLock, RwLockReadGuard, Mutex, MutexGuard};
-use core::iter::FromIterator;
use core::ops::Deref;
use core::sync::atomic::{AtomicUsize, Ordering};
use bitcoin::secp256k1::PublicKey;
FN: Fn(&ChannelMonitor<ChannelSigner>, &TransactionData) -> Vec<TransactionOutputs>
{
let err_str = "ChannelMonitor[Update] persistence failed unrecoverably. This indicates we cannot continue normal operation and must shut down.";
- let funding_outpoints: HashSet<OutPoint> = HashSet::from_iter(self.monitors.read().unwrap().keys().cloned());
+ let funding_outpoints = hash_set_from_iter(self.monitors.read().unwrap().keys().cloned());
for funding_outpoint in funding_outpoints.iter() {
let monitor_lock = self.monitors.read().unwrap();
if let Some(monitor_state) = monitor_lock.get(funding_outpoint) {
/// transactions relevant to the watched channels.
pub fn new(chain_source: Option<C>, broadcaster: T, logger: L, feeest: F, persister: P) -> Self {
Self {
- monitors: RwLock::new(HashMap::new()),
+ monitors: RwLock::new(new_hash_map()),
sync_persistence_id: AtomicCounter::new(),
chain_source,
broadcaster,
#[cfg(not(c_bindings))]
/// Lists the pending updates for each [`ChannelMonitor`] (by `OutPoint` being monitored).
pub fn list_pending_monitor_updates(&self) -> HashMap<OutPoint, Vec<MonitorUpdateId>> {
- self.monitors.read().unwrap().iter().map(|(outpoint, holder)| {
+ hash_map_from_iter(self.monitors.read().unwrap().iter().map(|(outpoint, holder)| {
(*outpoint, holder.pending_monitor_updates.lock().unwrap().clone())
- }).collect()
+ }))
}
#[cfg(c_bindings)]
channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx
);
- let mut outputs_to_watch = HashMap::new();
+ let mut outputs_to_watch = new_hash_map();
outputs_to_watch.insert(funding_info.0.txid, vec![(funding_info.0.index as u32, funding_info.1.clone())]);
Self::from_impl(ChannelMonitorImpl {
on_holder_tx_csv: counterparty_channel_parameters.selected_contest_delay,
commitment_secrets: CounterpartyCommitmentSecrets::new(),
- counterparty_claimable_outpoints: HashMap::new(),
- counterparty_commitment_txn_on_chain: HashMap::new(),
- counterparty_hash_commitment_number: HashMap::new(),
- counterparty_fulfilled_htlcs: HashMap::new(),
+ counterparty_claimable_outpoints: new_hash_map(),
+ counterparty_commitment_txn_on_chain: new_hash_map(),
+ counterparty_hash_commitment_number: new_hash_map(),
+ counterparty_fulfilled_htlcs: new_hash_map(),
prev_holder_signed_commitment_tx: None,
current_holder_commitment_tx: holder_commitment_tx,
current_counterparty_commitment_number: 1 << 48,
current_holder_commitment_number,
- payment_preimages: HashMap::new(),
+ payment_preimages: new_hash_map(),
pending_monitor_events: Vec::new(),
pending_events: Vec::new(),
is_processing_pending_events: false,
/// HTLCs which were resolved on-chain (i.e. where the final HTLC resolution was done by an
/// event from this `ChannelMonitor`).
pub(crate) fn get_all_current_outbound_htlcs(&self) -> HashMap<HTLCSource, (HTLCOutputInCommitment, Option<PaymentPreimage>)> {
- let mut res = HashMap::new();
+ let mut res = new_hash_map();
// Just examine the available counterparty commitment transactions. See docs on
// `fail_unbroadcast_htlcs`, below, for justification.
let us = self.inner.lock().unwrap();
return self.get_all_current_outbound_htlcs();
}
- let mut res = HashMap::new();
+ let mut res = new_hash_map();
macro_rules! walk_htlcs {
($holder_commitment: expr, $htlc_iter: expr) => {
for (htlc, source) in $htlc_iter {
(htlc, htlc_source.as_ref().map(|htlc_source| htlc_source.as_ref()))
), logger);
} else {
- debug_assert!(false, "We should have per-commitment option for any recognized old commitment txn");
+ // Our fuzzers aren't contrained by pesky things like valid signatures, so can
+ // spend our funding output with a transaction which doesn't match our past
+ // commitment transactions. Thus, we can only debug-assert here when not
+ // fuzzing.
+ debug_assert!(cfg!(fuzzing), "We should have per-commitment option for any recognized old commitment txn");
fail_unbroadcast_htlcs!(self, "revoked counterparty", commitment_txid, tx, height,
block_hash, [].iter().map(|reference| *reference), logger);
}
claimable_outpoints.append(&mut new_outpoints);
if new_outpoints.is_empty() {
if let Some((mut new_outpoints, new_outputs)) = self.check_spend_holder_transaction(&tx, height, &block_hash, &logger) {
+ #[cfg(not(fuzzing))]
debug_assert!(commitment_tx_to_counterparty_output.is_none(),
"A commitment transaction matched as both a counterparty and local commitment tx?");
if !new_outputs.1.is_empty() {
/// Filters a block's `txdata` for transactions spending watched outputs or for any child
/// transactions thereof.
fn filter_block<'a>(&self, txdata: &TransactionData<'a>) -> Vec<&'a Transaction> {
- let mut matched_txn = HashSet::new();
+ let mut matched_txn = new_hash_set();
txdata.iter().filter(|&&(_, tx)| {
let mut matches = self.spends_watched_output(tx);
for input in tx.input.iter() {
}
let counterparty_claimable_outpoints_len: u64 = Readable::read(reader)?;
- let mut counterparty_claimable_outpoints = HashMap::with_capacity(cmp::min(counterparty_claimable_outpoints_len as usize, MAX_ALLOC_SIZE / 64));
+ let mut counterparty_claimable_outpoints = hash_map_with_capacity(cmp::min(counterparty_claimable_outpoints_len as usize, MAX_ALLOC_SIZE / 64));
for _ in 0..counterparty_claimable_outpoints_len {
let txid: Txid = Readable::read(reader)?;
let htlcs_count: u64 = Readable::read(reader)?;
}
let counterparty_commitment_txn_on_chain_len: u64 = Readable::read(reader)?;
- let mut counterparty_commitment_txn_on_chain = HashMap::with_capacity(cmp::min(counterparty_commitment_txn_on_chain_len as usize, MAX_ALLOC_SIZE / 32));
+ let mut counterparty_commitment_txn_on_chain = hash_map_with_capacity(cmp::min(counterparty_commitment_txn_on_chain_len as usize, MAX_ALLOC_SIZE / 32));
for _ in 0..counterparty_commitment_txn_on_chain_len {
let txid: Txid = Readable::read(reader)?;
let commitment_number = <U48 as Readable>::read(reader)?.0;
}
let counterparty_hash_commitment_number_len: u64 = Readable::read(reader)?;
- let mut counterparty_hash_commitment_number = HashMap::with_capacity(cmp::min(counterparty_hash_commitment_number_len as usize, MAX_ALLOC_SIZE / 32));
+ let mut counterparty_hash_commitment_number = hash_map_with_capacity(cmp::min(counterparty_hash_commitment_number_len as usize, MAX_ALLOC_SIZE / 32));
for _ in 0..counterparty_hash_commitment_number_len {
let payment_hash: PaymentHash = Readable::read(reader)?;
let commitment_number = <U48 as Readable>::read(reader)?.0;
let current_holder_commitment_number = <U48 as Readable>::read(reader)?.0;
let payment_preimages_len: u64 = Readable::read(reader)?;
- let mut payment_preimages = HashMap::with_capacity(cmp::min(payment_preimages_len as usize, MAX_ALLOC_SIZE / 32));
+ let mut payment_preimages = hash_map_with_capacity(cmp::min(payment_preimages_len as usize, MAX_ALLOC_SIZE / 32));
for _ in 0..payment_preimages_len {
let preimage: PaymentPreimage = Readable::read(reader)?;
let hash = PaymentHash(Sha256::hash(&preimage.0[..]).to_byte_array());
}
let outputs_to_watch_len: u64 = Readable::read(reader)?;
- let mut outputs_to_watch = HashMap::with_capacity(cmp::min(outputs_to_watch_len as usize, MAX_ALLOC_SIZE / (mem::size_of::<Txid>() + mem::size_of::<u32>() + mem::size_of::<Vec<ScriptBuf>>())));
+ let mut outputs_to_watch = hash_map_with_capacity(cmp::min(outputs_to_watch_len as usize, MAX_ALLOC_SIZE / (mem::size_of::<Txid>() + mem::size_of::<u32>() + mem::size_of::<Vec<ScriptBuf>>())));
for _ in 0..outputs_to_watch_len {
let txid = Readable::read(reader)?;
let outputs_len: u64 = Readable::read(reader)?;
let mut counterparty_node_id = None;
let mut confirmed_commitment_tx_counterparty_output = None;
let mut spendable_txids_confirmed = Some(Vec::new());
- let mut counterparty_fulfilled_htlcs = Some(HashMap::new());
+ let mut counterparty_fulfilled_htlcs = Some(new_hash_map());
let mut initial_counterparty_commitment_info = None;
let mut channel_id = None;
read_tlv_fields!(reader, {
signer.provide_channel_parameters(&channel_parameters);
let pending_claim_requests_len: u64 = Readable::read(reader)?;
- let mut pending_claim_requests = HashMap::with_capacity(cmp::min(pending_claim_requests_len as usize, MAX_ALLOC_SIZE / 128));
+ let mut pending_claim_requests = hash_map_with_capacity(cmp::min(pending_claim_requests_len as usize, MAX_ALLOC_SIZE / 128));
for _ in 0..pending_claim_requests_len {
pending_claim_requests.insert(Readable::read(reader)?, Readable::read(reader)?);
}
let claimable_outpoints_len: u64 = Readable::read(reader)?;
- let mut claimable_outpoints = HashMap::with_capacity(cmp::min(pending_claim_requests_len as usize, MAX_ALLOC_SIZE / 128));
+ let mut claimable_outpoints = hash_map_with_capacity(cmp::min(pending_claim_requests_len as usize, MAX_ALLOC_SIZE / 128));
for _ in 0..claimable_outpoints_len {
let outpoint = Readable::read(reader)?;
let ancestor_claim_txid = Readable::read(reader)?;
prev_holder_commitment: None,
signer,
channel_transaction_parameters: channel_parameters,
- pending_claim_requests: HashMap::new(),
- claimable_outpoints: HashMap::new(),
+ pending_claim_requests: new_hash_map(),
+ claimable_outpoints: new_hash_map(),
locktimed_packages: BTreeMap::new(),
onchain_events_awaiting_threshold_conf: Vec::new(),
pending_claim_events: Vec::new(),
if let Some(claim_id) = claim_id {
if let Some(claim) = self.pending_claim_requests.remove(&claim_id) {
for outpoint in claim.outpoints() {
- self.claimable_outpoints.remove(&outpoint);
+ self.claimable_outpoints.remove(outpoint);
}
}
} else {
claim_id
},
};
- debug_assert!(self.pending_claim_requests.get(&claim_id).is_none());
+ // Because fuzzing can cause hash collisions, we can end up with conflicting claim
+ // ids here, so we only assert when not fuzzing.
+ debug_assert!(cfg!(fuzzing) || self.pending_claim_requests.get(&claim_id).is_none());
for k in req.outpoints() {
log_info!(logger, "Registering claiming request for {}:{}", k.txid, k.vout);
self.claimable_outpoints.insert(k.clone(), (claim_id, conf_height));
F::Target: FeeEstimator,
{
log_debug!(logger, "Updating claims view at height {} with {} matched transactions in block {}", cur_height, txn_matched.len(), conf_height);
- let mut bump_candidates = HashMap::new();
+ let mut bump_candidates = new_hash_map();
for tx in txn_matched {
// Scan all input to verify is one of the outpoint spent is of interest for us
let mut claimed_outputs_material = Vec::new();
where B::Target: BroadcasterInterface,
F::Target: FeeEstimator,
{
- let mut bump_candidates = HashMap::new();
+ let mut bump_candidates = new_hash_map();
let onchain_events_awaiting_threshold_conf =
self.onchain_events_awaiting_threshold_conf.drain(..).collect::<Vec<_>>();
for entry in onchain_events_awaiting_threshold_conf {
/// Returns a new instance backed by the given [`WalletSource`] that serves as an implementation
/// of [`CoinSelectionSource`].
pub fn new(source: W, logger: L) -> Self {
- Self { source, logger, locked_utxos: Mutex::new(HashMap::new()) }
+ Self { source, logger, locked_utxos: Mutex::new(new_hash_map()) }
}
/// Performs coin selection on the set of UTXOs obtained from
mod prelude {
#[cfg(feature = "hashbrown")]
extern crate hashbrown;
+ #[cfg(feature = "ahash")]
+ extern crate ahash;
pub use alloc::{vec, vec::Vec, string::String, collections::VecDeque, boxed::Box};
- #[cfg(not(feature = "hashbrown"))]
- pub use std::collections::{HashMap, HashSet, hash_map};
- #[cfg(feature = "hashbrown")]
- pub use self::hashbrown::{HashMap, HashSet, hash_map};
pub use alloc::borrow::ToOwned;
pub use alloc::string::ToString;
+
+ // For no-std builds, we need to use hashbrown, however, by default, it doesn't randomize the
+ // hashing and is vulnerable to HashDoS attacks. Thus, when not fuzzing, we use its default
+ // ahash hashing algorithm but randomize, opting to not randomize when fuzzing to avoid false
+ // positive branch coverage.
+
+ #[cfg(not(feature = "hashbrown"))]
+ mod std_hashtables {
+ pub(crate) use std::collections::{HashMap, HashSet, hash_map};
+
+ pub(crate) type OccupiedHashMapEntry<'a, K, V> =
+ std::collections::hash_map::OccupiedEntry<'a, K, V>;
+ pub(crate) type VacantHashMapEntry<'a, K, V> =
+ std::collections::hash_map::VacantEntry<'a, K, V>;
+ }
+ #[cfg(not(feature = "hashbrown"))]
+ pub(crate) use std_hashtables::*;
+
+ #[cfg(feature = "hashbrown")]
+ pub(crate) use self::hashbrown::hash_map;
+
+ #[cfg(all(feature = "hashbrown", fuzzing))]
+ mod nonrandomized_hashbrown {
+ pub(crate) use hashbrown::{HashMap, HashSet};
+
+ pub(crate) type OccupiedHashMapEntry<'a, K, V> =
+ hashbrown::hash_map::OccupiedEntry<'a, K, V, hashbrown::hash_map::DefaultHashBuilder>;
+ pub(crate) type VacantHashMapEntry<'a, K, V> =
+ hashbrown::hash_map::VacantEntry<'a, K, V, hashbrown::hash_map::DefaultHashBuilder>;
+ }
+ #[cfg(all(feature = "hashbrown", fuzzing))]
+ pub(crate) use nonrandomized_hashbrown::*;
+
+
+ #[cfg(all(feature = "hashbrown", not(fuzzing)))]
+ mod randomized_hashtables {
+ use super::*;
+ use ahash::RandomState;
+
+ pub(crate) type HashMap<K, V> = hashbrown::HashMap<K, V, RandomState>;
+ pub(crate) type HashSet<K> = hashbrown::HashSet<K, RandomState>;
+
+ pub(crate) type OccupiedHashMapEntry<'a, K, V> =
+ hashbrown::hash_map::OccupiedEntry<'a, K, V, RandomState>;
+ pub(crate) type VacantHashMapEntry<'a, K, V> =
+ hashbrown::hash_map::VacantEntry<'a, K, V, RandomState>;
+
+ pub(crate) fn new_hash_map<K, V>() -> HashMap<K, V> {
+ HashMap::with_hasher(RandomState::new())
+ }
+ pub(crate) fn hash_map_with_capacity<K, V>(cap: usize) -> HashMap<K, V> {
+ HashMap::with_capacity_and_hasher(cap, RandomState::new())
+ }
+ pub(crate) fn hash_map_from_iter<K: core::hash::Hash + Eq, V, I: IntoIterator<Item=(K, V)>>(iter: I) -> HashMap<K, V> {
+ let iter = iter.into_iter();
+ let min_size = iter.size_hint().0;
+ let mut res = HashMap::with_capacity_and_hasher(min_size, RandomState::new());
+ res.extend(iter);
+ res
+ }
+
+ pub(crate) fn new_hash_set<K>() -> HashSet<K> {
+ HashSet::with_hasher(RandomState::new())
+ }
+ pub(crate) fn hash_set_with_capacity<K>(cap: usize) -> HashSet<K> {
+ HashSet::with_capacity_and_hasher(cap, RandomState::new())
+ }
+ pub(crate) fn hash_set_from_iter<K: core::hash::Hash + Eq, I: IntoIterator<Item=K>>(iter: I) -> HashSet<K> {
+ let iter = iter.into_iter();
+ let min_size = iter.size_hint().0;
+ let mut res = HashSet::with_capacity_and_hasher(min_size, RandomState::new());
+ res.extend(iter);
+ res
+ }
+ }
+
+ #[cfg(any(not(feature = "hashbrown"), fuzzing))]
+ mod randomized_hashtables {
+ use super::*;
+
+ pub(crate) fn new_hash_map<K, V>() -> HashMap<K, V> { HashMap::new() }
+ pub(crate) fn hash_map_with_capacity<K, V>(cap: usize) -> HashMap<K, V> {
+ HashMap::with_capacity(cap)
+ }
+ pub(crate) fn hash_map_from_iter<K: core::hash::Hash + Eq, V, I: IntoIterator<Item=(K, V)>>(iter: I) -> HashMap<K, V> {
+ HashMap::from_iter(iter)
+ }
+
+ pub(crate) fn new_hash_set<K>() -> HashSet<K> { HashSet::new() }
+ pub(crate) fn hash_set_with_capacity<K>(cap: usize) -> HashSet<K> {
+ HashSet::with_capacity(cap)
+ }
+ pub(crate) fn hash_set_from_iter<K: core::hash::Hash + Eq, I: IntoIterator<Item=K>>(iter: I) -> HashSet<K> {
+ HashSet::from_iter(iter)
+ }
+ }
+
+ pub(crate) use randomized_hashtables::*;
}
#[cfg(all(not(ldk_bench), feature = "backtrace", feature = "std", test))]
let chan_upd_2_3 = create_announced_chan_between_nodes_with_value(&nodes, 2, 3, 1_000_000, 0).0.contents;
let chan_upd_3_4 = create_announced_chan_between_nodes_with_value(&nodes, 3, 4, 1_000_000, 0).0.contents;
+ // Get all our nodes onto the same height so payments don't fail for CLTV violations.
+ connect_blocks(&nodes[0], nodes[4].best_block_info().1 - nodes[0].best_block_info().1);
+ connect_blocks(&nodes[1], nodes[4].best_block_info().1 - nodes[1].best_block_info().1);
+ connect_blocks(&nodes[2], nodes[4].best_block_info().1 - nodes[2].best_block_info().1);
+ assert_eq!(nodes[4].best_block_info().1, nodes[3].best_block_info().1);
+
let amt_msat = 5000;
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[4], Some(amt_msat), None);
let route_params = get_blinded_route_parameters(amt_msat, payment_secret,
channel_ready_event_emitted: false,
#[cfg(any(test, fuzzing))]
- historical_inbound_htlc_fulfills: HashSet::new(),
+ historical_inbound_htlc_fulfills: new_hash_set(),
channel_type,
channel_keys_id,
channel_ready_event_emitted: false,
#[cfg(any(test, fuzzing))]
- historical_inbound_htlc_fulfills: HashSet::new(),
+ historical_inbound_htlc_fulfills: new_hash_set(),
channel_type,
channel_keys_id,
let channel_update_status = Readable::read(reader)?;
#[cfg(any(test, fuzzing))]
- let mut historical_inbound_htlc_fulfills = HashSet::new();
+ let mut historical_inbound_htlc_fulfills = new_hash_set();
#[cfg(any(test, fuzzing))]
{
let htlc_fulfills_len: u64 = Readable::read(reader)?;
Arc<DefaultRouter<
Arc<NetworkGraph<Arc<L>>>,
Arc<L>,
+ Arc<KeysManager>,
Arc<RwLock<ProbabilisticScorer<Arc<NetworkGraph<Arc<L>>>, Arc<L>>>>,
ProbabilisticScoringFeeParameters,
ProbabilisticScorer<Arc<NetworkGraph<Arc<L>>>, Arc<L>>,
&'e DefaultRouter<
&'f NetworkGraph<&'g L>,
&'g L,
+ &'c KeysManager,
&'h RwLock<ProbabilisticScorer<&'f NetworkGraph<&'g L>, &'g L>>,
ProbabilisticScoringFeeParameters,
ProbabilisticScorer<&'f NetworkGraph<&'g L>, &'g L>
best_block: RwLock::new(params.best_block),
- outbound_scid_aliases: Mutex::new(HashSet::new()),
- pending_inbound_payments: Mutex::new(HashMap::new()),
+ outbound_scid_aliases: Mutex::new(new_hash_set()),
+ pending_inbound_payments: Mutex::new(new_hash_map()),
pending_outbound_payments: OutboundPayments::new(),
- forward_htlcs: Mutex::new(HashMap::new()),
- claimable_payments: Mutex::new(ClaimablePayments { claimable_payments: HashMap::new(), pending_claiming_payments: HashMap::new() }),
- pending_intercepted_htlcs: Mutex::new(HashMap::new()),
- outpoint_to_peer: Mutex::new(HashMap::new()),
- short_to_chan_info: FairRwLock::new(HashMap::new()),
+ forward_htlcs: Mutex::new(new_hash_map()),
+ claimable_payments: Mutex::new(ClaimablePayments { claimable_payments: new_hash_map(), pending_claiming_payments: new_hash_map() }),
+ pending_intercepted_htlcs: Mutex::new(new_hash_map()),
+ outpoint_to_peer: Mutex::new(new_hash_map()),
+ short_to_chan_info: FairRwLock::new(new_hash_map()),
our_network_pubkey: node_signer.get_node_id(Recipient::Node).unwrap(),
secp_ctx,
highest_seen_timestamp: AtomicUsize::new(current_timestamp as usize),
- per_peer_state: FairRwLock::new(HashMap::new()),
+ per_peer_state: FairRwLock::new(new_hash_map()),
pending_events: Mutex::new(VecDeque::new()),
pending_events_processor: AtomicBool::new(false),
ProbeSendFailure::RouteNotFound
})?;
- let mut used_liquidity_map = HashMap::with_capacity(first_hops.len());
+ let mut used_liquidity_map = hash_map_with_capacity(first_hops.len());
let mut res = Vec::new();
let mut failed_forwards = Vec::new();
let mut phantom_receives: Vec<(u64, OutPoint, ChannelId, u128, Vec<(PendingHTLCInfo, u64)>)> = Vec::new();
{
- let mut forward_htlcs = HashMap::new();
+ let mut forward_htlcs = new_hash_map();
mem::swap(&mut forward_htlcs, &mut self.forward_htlcs.lock().unwrap());
for (short_chan_id, mut pending_forwards) in forward_htlcs {
// TODO: Once we can rely on the counterparty_node_id from the
// monitor event, this and the outpoint_to_peer map should be removed.
let outpoint_to_peer = self.outpoint_to_peer.lock().unwrap();
- match outpoint_to_peer.get(&funding_txo) {
+ match outpoint_to_peer.get(funding_txo) {
Some(cp_id) => cp_id.clone(),
None => return,
}
peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap();
let peer_state = &mut *peer_state_lock;
let channel =
- if let Some(ChannelPhase::Funded(chan)) = peer_state.channel_by_id.get_mut(&channel_id) {
+ if let Some(ChannelPhase::Funded(chan)) = peer_state.channel_by_id.get_mut(channel_id) {
chan
} else {
let update_actions = peer_state.monitor_update_blocked_actions
/// Errors if the `MessageRouter` errors or returns an empty `Vec`.
fn create_blinded_path(&self) -> Result<BlindedPath, ()> {
let recipient = self.get_our_node_id();
- let entropy_source = self.entropy_source.deref();
let secp_ctx = &self.secp_ctx;
let peers = self.per_peer_state.read().unwrap()
.collect::<Vec<_>>();
self.router
- .create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
+ .create_blinded_paths(recipient, peers, secp_ctx)
.and_then(|paths| paths.into_iter().next().ok_or(()))
}
fn create_blinded_payment_paths(
&self, amount_msats: u64, payment_secret: PaymentSecret
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
- let entropy_source = self.entropy_source.deref();
let secp_ctx = &self.secp_ctx;
let first_hops = self.list_usable_channels();
},
};
self.router.create_blinded_payment_paths(
- payee_node_id, first_hops, payee_tlvs, amount_msats, entropy_source, secp_ctx
+ payee_node_id, first_hops, payee_tlvs, amount_msats, secp_ctx
)
}
return NotifyOption::SkipPersistNoEvents;
}
e.insert(Mutex::new(PeerState {
- channel_by_id: HashMap::new(),
- inbound_channel_request_by_id: HashMap::new(),
+ channel_by_id: new_hash_map(),
+ inbound_channel_request_by_id: new_hash_map(),
latest_features: init_msg.features.clone(),
pending_msg_events: Vec::new(),
in_flight_monitor_updates: BTreeMap::new(),
}
// Encode without retry info for 0.0.101 compatibility.
- let mut pending_outbound_payments_no_retry: HashMap<PaymentId, HashSet<[u8; 32]>> = HashMap::new();
+ let mut pending_outbound_payments_no_retry: HashMap<PaymentId, HashSet<[u8; 32]>> = new_hash_map();
for (id, outbound) in pending_outbound_payments.iter() {
match outbound {
PendingOutboundPayment::Legacy { session_privs } |
for ((counterparty_id, _), peer_state) in per_peer_state.iter().zip(peer_states.iter()) {
for (funding_outpoint, updates) in peer_state.in_flight_monitor_updates.iter() {
if !updates.is_empty() {
- if in_flight_monitor_updates.is_none() { in_flight_monitor_updates = Some(HashMap::new()); }
+ if in_flight_monitor_updates.is_none() { in_flight_monitor_updates = Some(new_hash_map()); }
in_flight_monitor_updates.as_mut().unwrap().insert((counterparty_id, funding_outpoint), updates);
}
}
mut channel_monitors: Vec<&'a mut ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>>) -> Self {
Self {
entropy_source, node_signer, signer_provider, fee_estimator, chain_monitor, tx_broadcaster, router, logger, default_config,
- channel_monitors: channel_monitors.drain(..).map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect()
+ channel_monitors: hash_map_from_iter(
+ channel_monitors.drain(..).map(|monitor| { (monitor.get_funding_txo().0, monitor) })
+ ),
}
}
}
let mut failed_htlcs = Vec::new();
let channel_count: u64 = Readable::read(reader)?;
- let mut funding_txo_set = HashSet::with_capacity(cmp::min(channel_count as usize, 128));
- let mut funded_peer_channels: HashMap<PublicKey, HashMap<ChannelId, ChannelPhase<SP>>> = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
- let mut outpoint_to_peer = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
- let mut short_to_chan_info = HashMap::with_capacity(cmp::min(channel_count as usize, 128));
+ let mut funding_txo_set = hash_set_with_capacity(cmp::min(channel_count as usize, 128));
+ let mut funded_peer_channels: HashMap<PublicKey, HashMap<ChannelId, ChannelPhase<SP>>> = hash_map_with_capacity(cmp::min(channel_count as usize, 128));
+ let mut outpoint_to_peer = hash_map_with_capacity(cmp::min(channel_count as usize, 128));
+ let mut short_to_chan_info = hash_map_with_capacity(cmp::min(channel_count as usize, 128));
let mut channel_closures = VecDeque::new();
let mut close_background_events = Vec::new();
- let mut funding_txo_to_channel_id = HashMap::with_capacity(channel_count as usize);
+ let mut funding_txo_to_channel_id = hash_map_with_capacity(channel_count as usize);
for _ in 0..channel_count {
let mut channel: Channel<SP> = Channel::read(reader, (
&args.entropy_source, &args.signer_provider, best_block_height, &provided_channel_type_features(&args.default_config)
by_id_map.insert(channel.context.channel_id(), ChannelPhase::Funded(channel));
},
hash_map::Entry::Vacant(entry) => {
- let mut by_id_map = HashMap::new();
+ let mut by_id_map = new_hash_map();
by_id_map.insert(channel.context.channel_id(), ChannelPhase::Funded(channel));
entry.insert(by_id_map);
}
const MAX_ALLOC_SIZE: usize = 1024 * 64;
let forward_htlcs_count: u64 = Readable::read(reader)?;
- let mut forward_htlcs = HashMap::with_capacity(cmp::min(forward_htlcs_count as usize, 128));
+ let mut forward_htlcs = hash_map_with_capacity(cmp::min(forward_htlcs_count as usize, 128));
for _ in 0..forward_htlcs_count {
let short_channel_id = Readable::read(reader)?;
let pending_forwards_count: u64 = Readable::read(reader)?;
let peer_state_from_chans = |channel_by_id| {
PeerState {
channel_by_id,
- inbound_channel_request_by_id: HashMap::new(),
+ inbound_channel_request_by_id: new_hash_map(),
latest_features: InitFeatures::empty(),
pending_msg_events: Vec::new(),
in_flight_monitor_updates: BTreeMap::new(),
};
let peer_count: u64 = Readable::read(reader)?;
- let mut per_peer_state = HashMap::with_capacity(cmp::min(peer_count as usize, MAX_ALLOC_SIZE/mem::size_of::<(PublicKey, Mutex<PeerState<SP>>)>()));
+ let mut per_peer_state = hash_map_with_capacity(cmp::min(peer_count as usize, MAX_ALLOC_SIZE/mem::size_of::<(PublicKey, Mutex<PeerState<SP>>)>()));
for _ in 0..peer_count {
let peer_pubkey = Readable::read(reader)?;
- let peer_chans = funded_peer_channels.remove(&peer_pubkey).unwrap_or(HashMap::new());
+ let peer_chans = funded_peer_channels.remove(&peer_pubkey).unwrap_or(new_hash_map());
let mut peer_state = peer_state_from_chans(peer_chans);
peer_state.latest_features = Readable::read(reader)?;
per_peer_state.insert(peer_pubkey, Mutex::new(peer_state));
let highest_seen_timestamp: u32 = Readable::read(reader)?;
let pending_inbound_payment_count: u64 = Readable::read(reader)?;
- let mut pending_inbound_payments: HashMap<PaymentHash, PendingInboundPayment> = HashMap::with_capacity(cmp::min(pending_inbound_payment_count as usize, MAX_ALLOC_SIZE/(3*32)));
+ let mut pending_inbound_payments: HashMap<PaymentHash, PendingInboundPayment> = hash_map_with_capacity(cmp::min(pending_inbound_payment_count as usize, MAX_ALLOC_SIZE/(3*32)));
for _ in 0..pending_inbound_payment_count {
if pending_inbound_payments.insert(Readable::read(reader)?, Readable::read(reader)?).is_some() {
return Err(DecodeError::InvalidValue);
let pending_outbound_payments_count_compat: u64 = Readable::read(reader)?;
let mut pending_outbound_payments_compat: HashMap<PaymentId, PendingOutboundPayment> =
- HashMap::with_capacity(cmp::min(pending_outbound_payments_count_compat as usize, MAX_ALLOC_SIZE/32));
+ hash_map_with_capacity(cmp::min(pending_outbound_payments_count_compat as usize, MAX_ALLOC_SIZE/32));
for _ in 0..pending_outbound_payments_count_compat {
let session_priv = Readable::read(reader)?;
let payment = PendingOutboundPayment::Legacy {
- session_privs: [session_priv].iter().cloned().collect()
+ session_privs: hash_set_from_iter([session_priv]),
};
if pending_outbound_payments_compat.insert(PaymentId(session_priv), payment).is_some() {
return Err(DecodeError::InvalidValue)
// pending_outbound_payments_no_retry is for compatibility with 0.0.101 clients.
let mut pending_outbound_payments_no_retry: Option<HashMap<PaymentId, HashSet<[u8; 32]>>> = None;
let mut pending_outbound_payments = None;
- let mut pending_intercepted_htlcs: Option<HashMap<InterceptId, PendingAddHTLCInfo>> = Some(HashMap::new());
+ let mut pending_intercepted_htlcs: Option<HashMap<InterceptId, PendingAddHTLCInfo>> = Some(new_hash_map());
let mut received_network_pubkey: Option<PublicKey> = None;
let mut fake_scid_rand_bytes: Option<[u8; 32]> = None;
let mut probing_cookie_secret: Option<[u8; 32]> = None;
let mut claimable_htlc_purposes = None;
let mut claimable_htlc_onion_fields = None;
- let mut pending_claiming_payments = Some(HashMap::new());
+ let mut pending_claiming_payments = Some(new_hash_map());
let mut monitor_update_blocked_actions_per_peer: Option<Vec<(_, BTreeMap<_, Vec<_>>)>> = Some(Vec::new());
let mut events_override = None;
let mut in_flight_monitor_updates: Option<HashMap<(PublicKey, OutPoint), Vec<ChannelMonitorUpdate>>> = None;
if pending_outbound_payments.is_none() && pending_outbound_payments_no_retry.is_none() {
pending_outbound_payments = Some(pending_outbound_payments_compat);
} else if pending_outbound_payments.is_none() {
- let mut outbounds = HashMap::new();
+ let mut outbounds = new_hash_map();
for (id, session_privs) in pending_outbound_payments_no_retry.unwrap().drain() {
outbounds.insert(id, PendingOutboundPayment::Legacy { session_privs });
}
// still open, we need to replay any monitor updates that are for closed channels,
// creating the neccessary peer_state entries as we go.
let peer_state_mutex = per_peer_state.entry(counterparty_id).or_insert_with(|| {
- Mutex::new(peer_state_from_chans(HashMap::new()))
+ Mutex::new(peer_state_from_chans(new_hash_map()))
});
let mut peer_state = peer_state_mutex.lock().unwrap();
handle_in_flight_updates!(counterparty_id, chan_in_flight_updates,
retry_strategy: None,
attempts: PaymentAttempts::new(),
payment_params: None,
- session_privs: [session_priv_bytes].iter().map(|a| *a).collect(),
+ session_privs: hash_set_from_iter([session_priv_bytes]),
payment_hash: htlc.payment_hash,
payment_secret: None, // only used for retries, and we'll never retry on startup
payment_metadata: None, // only used for retries, and we'll never retry on startup
let inbound_pmt_key_material = args.node_signer.get_inbound_payment_key_material();
let expanded_inbound_key = inbound_payment::ExpandedKey::new(&inbound_pmt_key_material);
- let mut claimable_payments = HashMap::with_capacity(claimable_htlcs_list.len());
+ let mut claimable_payments = hash_map_with_capacity(claimable_htlcs_list.len());
if let Some(purposes) = claimable_htlc_purposes {
if purposes.len() != claimable_htlcs_list.len() {
return Err(DecodeError::InvalidValue);
}
}
- let mut outbound_scid_aliases = HashSet::new();
+ let mut outbound_scid_aliases = new_hash_set();
for (_peer_node_id, peer_state_mutex) in per_peer_state.iter_mut() {
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
let peer_state = &mut *peer_state_lock;
downstream_counterparty_and_funding_outpoint:
Some((blocked_node_id, _blocked_channel_outpoint, blocked_channel_id, blocking_action)), ..
} = action {
- if let Some(blocked_peer_state) = per_peer_state.get(&blocked_node_id) {
+ if let Some(blocked_peer_state) = per_peer_state.get(blocked_node_id) {
log_trace!(logger,
"Holding the next revoke_and_ack from {} until the preimage is durably persisted in the inbound edge's ChannelMonitor",
blocked_channel_id);
let (scid_1, scid_2) = (42, 43);
- let mut forward_htlcs = HashMap::new();
+ let mut forward_htlcs = new_hash_map();
forward_htlcs.insert(scid_1, dummy_htlcs_1.clone());
forward_htlcs.insert(scid_2, dummy_htlcs_2.clone());
// Before using all the new monitors to check the watch outpoints, use the full set of
// them to ensure we can write and reload our ChannelManager.
{
- let mut channel_monitors = HashMap::new();
+ let mut channel_monitors = new_hash_map();
for monitor in deserialized_monitors.iter_mut() {
channel_monitors.insert(monitor.get_funding_txo().0, monitor);
}
let mut node_read = &chanman_encoded[..];
let (_, node_deserialized) = {
- let mut channel_monitors = HashMap::new();
+ let mut channel_monitors = new_hash_map();
for monitor in monitors_read.iter_mut() {
assert!(channel_monitors.insert(monitor.get_funding_txo().0, monitor).is_none());
}
tx_broadcaster: &chanmon_cfgs[i].tx_broadcaster,
fee_estimator: &chanmon_cfgs[i].fee_estimator,
router: test_utils::TestRouter::new(network_graph.clone(), &chanmon_cfgs[i].logger, &chanmon_cfgs[i].scorer),
- message_router: test_utils::TestMessageRouter::new(network_graph.clone()),
+ message_router: test_utils::TestMessageRouter::new(network_graph.clone(), &chanmon_cfgs[i].keys_manager),
chain_monitor,
keys_manager: &chanmon_cfgs[i].keys_manager,
node_seed: seed,
/// also fail.
pub fn test_txn_broadcast<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, ChannelId, Transaction), commitment_tx: Option<Transaction>, has_htlc_tx: HTLCType) -> Vec<Transaction> {
let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
- let mut txn_seen = HashSet::new();
+ let mut txn_seen = new_hash_set();
node_txn.retain(|tx| txn_seen.insert(tx.txid()));
assert!(node_txn.len() >= if commitment_tx.is_some() { 0 } else { 1 } + if has_htlc_tx == HTLCType::NONE { 0 } else { 1 });
pub fn check_preimage_claim<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, prev_txn: &Vec<Transaction>) -> Vec<Transaction> {
let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
- let mut txn_seen = HashSet::new();
+ let mut txn_seen = new_hash_set();
node_txn.retain(|tx| txn_seen.insert(tx.txid()));
let mut found_prev = false;
macro_rules! get_chan_reestablish_msgs {
($src_node: expr, $dst_node: expr) => {
{
- let mut announcements = $crate::prelude::HashSet::new();
+ let mut announcements = $crate::prelude::new_hash_set();
let mut res = Vec::with_capacity(1);
for msg in $src_node.node.get_and_clear_pending_msg_events() {
if let MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } = msg {
// block connection just like the !deliver_bs_raa case
}
- let mut failed_htlcs = HashSet::new();
+ let mut failed_htlcs = new_hash_set();
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
mine_transaction(&nodes[1], &revoked_local_txn[0]);
let as_events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(as_events.len(), if announce_latest { 10 } else { 6 });
- let mut as_failds = HashSet::new();
+ let mut as_faileds = new_hash_set();
let mut as_updates = 0;
for event in as_events.iter() {
if let &Event::PaymentPathFailed { ref payment_hash, ref payment_failed_permanently, ref failure, .. } = event {
- assert!(as_failds.insert(*payment_hash));
+ assert!(as_faileds.insert(*payment_hash));
if *payment_hash != payment_hash_2 {
assert_eq!(*payment_failed_permanently, deliver_last_raa);
} else {
} else if let &Event::PaymentFailed { .. } = event {
} else { panic!("Unexpected event"); }
}
- assert!(as_failds.contains(&payment_hash_1));
- assert!(as_failds.contains(&payment_hash_2));
+ assert!(as_faileds.contains(&payment_hash_1));
+ assert!(as_faileds.contains(&payment_hash_2));
if announce_latest {
- assert!(as_failds.contains(&payment_hash_3));
- assert!(as_failds.contains(&payment_hash_5));
+ assert!(as_faileds.contains(&payment_hash_3));
+ assert!(as_faileds.contains(&payment_hash_5));
}
- assert!(as_failds.contains(&payment_hash_6));
+ assert!(as_faileds.contains(&payment_hash_6));
let bs_events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(bs_events.len(), if announce_latest { 8 } else { 6 });
- let mut bs_failds = HashSet::new();
+ let mut bs_faileds = new_hash_set();
let mut bs_updates = 0;
for event in bs_events.iter() {
if let &Event::PaymentPathFailed { ref payment_hash, ref payment_failed_permanently, ref failure, .. } = event {
- assert!(bs_failds.insert(*payment_hash));
+ assert!(bs_faileds.insert(*payment_hash));
if *payment_hash != payment_hash_1 && *payment_hash != payment_hash_5 {
assert_eq!(*payment_failed_permanently, deliver_last_raa);
} else {
} else if let &Event::PaymentFailed { .. } = event {
} else { panic!("Unexpected event"); }
}
- assert!(bs_failds.contains(&payment_hash_1));
- assert!(bs_failds.contains(&payment_hash_2));
+ assert!(bs_faileds.contains(&payment_hash_1));
+ assert!(bs_faileds.contains(&payment_hash_2));
if announce_latest {
- assert!(bs_failds.contains(&payment_hash_4));
+ assert!(bs_faileds.contains(&payment_hash_4));
}
- assert!(bs_failds.contains(&payment_hash_5));
+ assert!(bs_faileds.contains(&payment_hash_5));
// For each HTLC which was not failed-back by normal process (ie deliver_last_raa), we should
// get a NetworkUpdate. A should have gotten 4 HTLCs which were failed-back due to
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &chanmon_cfgs[0].logger));
let scorer = RwLock::new(test_utils::TestScorer::new());
let router = test_utils::TestRouter::new(network_graph.clone(), &chanmon_cfgs[0].logger, &scorer);
- let message_router = test_utils::TestMessageRouter::new(network_graph.clone());
+ let message_router = test_utils::TestMessageRouter::new(network_graph.clone(), &keys_manager);
let node = NodeCfg { chain_source: &chanmon_cfgs[0].chain_source, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, router, message_router, chain_monitor, keys_manager: &keys_manager, network_graph, node_seed: seed, override_init_features: alloc::rc::Rc::new(core::cell::RefCell::new(None)) };
let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
node_cfgs.remove(0);
}
let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(msg_events.len(), 3);
- let mut chans_disabled = HashMap::new();
+ let mut chans_disabled = new_hash_map();
for e in msg_events {
match e {
MessageSendEvent::BroadcastChannelUpdate { ref msg } => {
check_spends!(revoked_htlc_claim, htlc_tx);
}
- let mut revoked_claim_transaction_map = HashMap::new();
+ let mut revoked_claim_transaction_map = new_hash_map();
for current_tx in txn.into_iter() {
revoked_claim_transaction_map.insert(current_tx.txid(), current_tx);
}
}
fn mark_fulfilled(&mut self) {
- let mut session_privs = HashSet::new();
+ let mut session_privs = new_hash_set();
core::mem::swap(&mut session_privs, match self {
PendingOutboundPayment::Legacy { session_privs } |
PendingOutboundPayment::Retryable { session_privs, .. } |
fn mark_abandoned(&mut self, reason: PaymentFailureReason) {
if let PendingOutboundPayment::Retryable { session_privs, payment_hash, .. } = self {
- let mut our_session_privs = HashSet::new();
+ let mut our_session_privs = new_hash_set();
core::mem::swap(&mut our_session_privs, session_privs);
*self = PendingOutboundPayment::Abandoned {
session_privs: our_session_privs,
};
} else if let PendingOutboundPayment::InvoiceReceived { payment_hash, .. } = self {
*self = PendingOutboundPayment::Abandoned {
- session_privs: HashSet::new(),
+ session_privs: new_hash_set(),
payment_hash: *payment_hash,
reason: Some(reason)
};
impl OutboundPayments {
pub(super) fn new() -> Self {
Self {
- pending_outbound_payments: Mutex::new(HashMap::new()),
+ pending_outbound_payments: Mutex::new(new_hash_map()),
retry_lock: Mutex::new(()),
}
}
retry_strategy,
attempts: PaymentAttempts::new(),
payment_params,
- session_privs: HashSet::new(),
+ session_privs: new_hash_set(),
pending_amt_msat: 0,
pending_fee_msat: Some(0),
payment_hash,
PeerManager {
message_handler,
- peers: FairRwLock::new(HashMap::new()),
- node_id_to_descriptor: Mutex::new(HashMap::new()),
+ peers: FairRwLock::new(new_hash_map()),
+ node_id_to_descriptor: Mutex::new(new_hash_map()),
event_processing_state: AtomicI32::new(0),
ephemeral_key_midstate,
peer_counter: AtomicCounter::new(),
self.update_gossip_backlogged();
let flush_read_disabled = self.gossip_processing_backlog_lifted.swap(false, Ordering::Relaxed);
- let mut peers_to_disconnect = HashMap::new();
+ let mut peers_to_disconnect = new_hash_map();
{
let peers_lock = self.peers.read().unwrap();
use crate::events::{Event, EventsProvider};
use crate::ln::features::InitFeatures;
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler, SocketAddress};
-use crate::sign::{EntropySource, NodeSigner, Recipient};
+use crate::sign::{NodeSigner, Recipient};
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
use crate::util::test_utils;
use super::messenger::{CustomOnionMessageHandler, Destination, MessageRouter, OnionMessagePath, OnionMessenger, PendingOnionMessage, SendError};
}
fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
+ T: secp256k1::Signing + secp256k1::Verification
>(
- &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES,
- _secp_ctx: &Secp256k1<T>
+ &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
unreachable!()
}
/// # first_node_addresses: None,
/// # })
/// # }
-/// # fn create_blinded_paths<ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification>(
-/// # &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES, _secp_ctx: &Secp256k1<T>
+/// # fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
+/// # &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>
/// # ) -> Result<Vec<BlindedPath>, ()> {
/// # unreachable!()
/// # }
/// Creates [`BlindedPath`]s to the `recipient` node. The nodes in `peers` are assumed to be
/// direct peers with the `recipient`.
fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
+ T: secp256k1::Signing + secp256k1::Verification
>(
- &self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
- secp_ctx: &Secp256k1<T>
+ &self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()>;
}
/// A [`MessageRouter`] that can only route to a directly connected [`Destination`].
-pub struct DefaultMessageRouter<G: Deref<Target=NetworkGraph<L>>, L: Deref>
+pub struct DefaultMessageRouter<G: Deref<Target=NetworkGraph<L>>, L: Deref, ES: Deref>
where
L::Target: Logger,
+ ES::Target: EntropySource,
{
network_graph: G,
+ entropy_source: ES,
}
-impl<G: Deref<Target=NetworkGraph<L>>, L: Deref> DefaultMessageRouter<G, L>
+impl<G: Deref<Target=NetworkGraph<L>>, L: Deref, ES: Deref> DefaultMessageRouter<G, L, ES>
where
L::Target: Logger,
+ ES::Target: EntropySource,
{
/// Creates a [`DefaultMessageRouter`] using the given [`NetworkGraph`].
- pub fn new(network_graph: G) -> Self {
- Self { network_graph }
+ pub fn new(network_graph: G, entropy_source: ES) -> Self {
+ Self { network_graph, entropy_source }
}
}
-impl<G: Deref<Target=NetworkGraph<L>>, L: Deref> MessageRouter for DefaultMessageRouter<G, L>
+impl<G: Deref<Target=NetworkGraph<L>>, L: Deref, ES: Deref> MessageRouter for DefaultMessageRouter<G, L, ES>
where
L::Target: Logger,
+ ES::Target: EntropySource,
{
fn find_path(
&self, _sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
}
fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
+ T: secp256k1::Signing + secp256k1::Verification
>(
- &self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
- secp_ctx: &Secp256k1<T>
+ &self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
// Limit the number of blinded paths that are computed.
const MAX_PATHS: usize = 3;
.unwrap_or(false)
)
.map(|pubkey| vec![*pubkey, recipient])
- .map(|node_pks| BlindedPath::new_for_message(&node_pks, entropy_source, secp_ctx))
+ .map(|node_pks| BlindedPath::new_for_message(&node_pks, &*self.entropy_source, secp_ctx))
.take(MAX_PATHS)
.collect::<Result<Vec<_>, _>>();
Ok(paths) if !paths.is_empty() => Ok(paths),
_ => {
if network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient)) {
- BlindedPath::one_hop_for_message(recipient, entropy_source, secp_ctx)
+ BlindedPath::one_hop_for_message(recipient, &*self.entropy_source, secp_ctx)
.map(|path| vec![path])
} else {
Err(())
OnionMessenger {
entropy_source,
node_signer,
- message_recipients: Mutex::new(HashMap::new()),
+ message_recipients: Mutex::new(new_hash_map()),
secp_ctx,
logger,
message_router,
#[cfg(test)]
pub(super) fn release_pending_msgs(&self) -> HashMap<PublicKey, VecDeque<OnionMessage>> {
let mut message_recipients = self.message_recipients.lock().unwrap();
- let mut msgs = HashMap::new();
+ let mut msgs = new_hash_map();
// We don't want to disconnect the peers by removing them entirely from the original map, so we
// release the pending message buffers individually.
for (node_id, recipient) in &mut *message_recipients {
Arc<KeysManager>,
Arc<KeysManager>,
Arc<L>,
- Arc<DefaultMessageRouter<Arc<NetworkGraph<Arc<L>>>, Arc<L>>>,
+ Arc<DefaultMessageRouter<Arc<NetworkGraph<Arc<L>>>, Arc<L>, Arc<KeysManager>>>,
Arc<SimpleArcChannelManager<M, T, F, L>>,
IgnoringMessageHandler
>;
&'a KeysManager,
&'a KeysManager,
&'b L,
- &'i DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L>,
+ &'i DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L, &'a KeysManager>,
&'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L>,
IgnoringMessageHandler
>;
channels: RwLock::new(channels),
nodes: RwLock::new(nodes),
last_rapid_gossip_sync_timestamp: Mutex::new(last_rapid_gossip_sync_timestamp),
- removed_nodes: Mutex::new(HashMap::new()),
- removed_channels: Mutex::new(HashMap::new()),
+ removed_nodes: Mutex::new(new_hash_map()),
+ removed_channels: Mutex::new(new_hash_map()),
pending_checks: utxo::PendingChecks::new(),
})
}
channels: RwLock::new(IndexedMap::new()),
nodes: RwLock::new(IndexedMap::new()),
last_rapid_gossip_sync_timestamp: Mutex::new(None),
- removed_channels: Mutex::new(HashMap::new()),
- removed_nodes: Mutex::new(HashMap::new()),
+ removed_channels: Mutex::new(new_hash_map()),
+ removed_nodes: Mutex::new(new_hash_map()),
pending_checks: utxo::PendingChecks::new(),
}
}
//! The router finds paths within a [`NetworkGraph`] for a payment.
use bitcoin::secp256k1::{PublicKey, Secp256k1, self};
-use bitcoin::hashes::Hash;
-use bitcoin::hashes::sha256::Hash as Sha256;
use crate::blinded_path::{BlindedHop, BlindedPath};
use crate::blinded_path::payment::{ForwardNode, ForwardTlvs, PaymentConstraints, PaymentRelay, ReceiveTlvs};
use crate::io;
use crate::prelude::*;
-use crate::sync::Mutex;
use alloc::collections::BinaryHeap;
use core::{cmp, fmt};
use core::ops::Deref;
/// A [`Router`] implemented using [`find_route`].
-pub struct DefaultRouter<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> where
+pub struct DefaultRouter<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> where
L::Target: Logger,
S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>,
+ ES::Target: EntropySource,
{
network_graph: G,
logger: L,
- random_seed_bytes: Mutex<[u8; 32]>,
+ entropy_source: ES,
scorer: S,
score_params: SP,
- message_router: DefaultMessageRouter<G, L>,
+ message_router: DefaultMessageRouter<G, L, ES>,
}
-impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> DefaultRouter<G, L, S, SP, Sc> where
+impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref + Clone, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> DefaultRouter<G, L, ES, S, SP, Sc> where
L::Target: Logger,
S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>,
+ ES::Target: EntropySource,
{
/// Creates a new router.
- pub fn new(network_graph: G, logger: L, random_seed_bytes: [u8; 32], scorer: S, score_params: SP) -> Self {
- let random_seed_bytes = Mutex::new(random_seed_bytes);
- let message_router = DefaultMessageRouter::new(network_graph.clone());
- Self { network_graph, logger, random_seed_bytes, scorer, score_params, message_router }
+ pub fn new(network_graph: G, logger: L, entropy_source: ES, scorer: S, score_params: SP) -> Self {
+ let message_router = DefaultMessageRouter::new(network_graph.clone(), entropy_source.clone());
+ Self { network_graph, logger, entropy_source, scorer, score_params, message_router }
}
}
-impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> Router for DefaultRouter<G, L, S, SP, Sc> where
+impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> Router for DefaultRouter<G, L, ES, S, SP, Sc> where
L::Target: Logger,
S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>,
+ ES::Target: EntropySource,
{
fn find_route(
&self,
first_hops: Option<&[&ChannelDetails]>,
inflight_htlcs: InFlightHtlcs
) -> Result<Route, LightningError> {
- let random_seed_bytes = {
- let mut locked_random_seed_bytes = self.random_seed_bytes.lock().unwrap();
- *locked_random_seed_bytes = Sha256::hash(&*locked_random_seed_bytes).to_byte_array();
- *locked_random_seed_bytes
- };
+ let random_seed_bytes = self.entropy_source.get_secure_random_bytes();
find_route(
payer, params, &self.network_graph, first_hops, &*self.logger,
&ScorerAccountingForInFlightHtlcs::new(self.scorer.read_lock(), &inflight_htlcs),
}
fn create_blinded_payment_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
+ T: secp256k1::Signing + secp256k1::Verification
+ > (
&self, recipient: PublicKey, first_hops: Vec<ChannelDetails>, tlvs: ReceiveTlvs,
- amount_msats: u64, entropy_source: &ES, secp_ctx: &Secp256k1<T>
+ amount_msats: u64, secp_ctx: &Secp256k1<T>
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
// Limit the number of blinded paths that are computed.
const MAX_PAYMENT_PATHS: usize = 3;
})
.map(|forward_node| {
BlindedPath::new_for_payment(
- &[forward_node], recipient, tlvs.clone(), u64::MAX, entropy_source, secp_ctx
+ &[forward_node], recipient, tlvs.clone(), u64::MAX, &*self.entropy_source, secp_ctx
)
})
.take(MAX_PAYMENT_PATHS)
Ok(paths) if !paths.is_empty() => Ok(paths),
_ => {
if network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient)) {
- BlindedPath::one_hop_for_payment(recipient, tlvs, entropy_source, secp_ctx)
+ BlindedPath::one_hop_for_payment(recipient, tlvs, &*self.entropy_source, secp_ctx)
.map(|path| vec![path])
} else {
Err(())
}
}
-impl< G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> MessageRouter for DefaultRouter<G, L, S, SP, Sc> where
+impl< G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, ES: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> MessageRouter for DefaultRouter<G, L, ES, S, SP, Sc> where
L::Target: Logger,
S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>,
+ ES::Target: EntropySource,
{
fn find_path(
&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
}
fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
- &self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
- secp_ctx: &Secp256k1<T>
+ T: secp256k1::Signing + secp256k1::Verification
+ > (
+ &self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
- self.message_router.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
+ self.message_router.create_blinded_paths(recipient, peers, secp_ctx)
}
}
/// are assumed to be with the `recipient`'s peers. The payment secret and any constraints are
/// given in `tlvs`.
fn create_blinded_payment_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
+ T: secp256k1::Signing + secp256k1::Verification
+ > (
&self, recipient: PublicKey, first_hops: Vec<ChannelDetails>, tlvs: ReceiveTlvs,
- amount_msats: u64, entropy_source: &ES, secp_ctx: &Secp256k1<T>
+ amount_msats: u64, secp_ctx: &Secp256k1<T>
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()>;
}
impl InFlightHtlcs {
/// Constructs an empty `InFlightHtlcs`.
- pub fn new() -> Self { InFlightHtlcs(HashMap::new()) }
+ pub fn new() -> Self { InFlightHtlcs(new_hash_map()) }
/// Takes in a path with payer's node id and adds the path's details to `InFlightHtlcs`.
pub fn process_path(&mut self, path: &Path, payer_node_id: PublicKey) {
/// has been funded and is able to pay), and accessor methods may panic otherwise.
///
/// [`find_route`] validates this prior to constructing a [`CandidateRouteHop`].
+ ///
+ /// This is not exported to bindings users as lifetimes are not expressable in most languages.
pub details: &'a ChannelDetails,
/// The node id of the payer, which is also the source side of this candidate route hop.
+ ///
+ /// This is not exported to bindings users as lifetimes are not expressable in most languages.
pub payer_node_id: &'a NodeId,
}
pub struct PublicHopCandidate<'a> {
/// Information about the channel, including potentially its capacity and
/// direction-specific information.
+ ///
+ /// This is not exported to bindings users as lifetimes are not expressable in most languages.
pub info: DirectedChannelInfo<'a>,
/// The short channel ID of the channel, i.e. the identifier by which we refer to this
/// channel.
#[derive(Clone, Debug)]
pub struct PrivateHopCandidate<'a> {
/// Information about the private hop communicated via BOLT 11.
+ ///
+ /// This is not exported to bindings users as lifetimes are not expressable in most languages.
pub hint: &'a RouteHintHop,
/// Node id of the next hop in BOLT 11 route hint.
+ ///
+ /// This is not exported to bindings users as lifetimes are not expressable in most languages.
pub target_node_id: &'a NodeId
}
pub struct BlindedPathCandidate<'a> {
/// Information about the blinded path including the fee, HTLC amount limits, and
/// cryptographic material required to build an HTLC through the given path.
+ ///
+ /// This is not exported to bindings users as lifetimes are not expressable in most languages.
pub hint: &'a (BlindedPayInfo, BlindedPath),
/// Index of the hint in the original list of blinded hints.
///
/// cryptographic material required to build an HTLC terminating with the given path.
///
/// Note that the [`BlindedPayInfo`] is ignored here.
+ ///
+ /// This is not exported to bindings users as lifetimes are not expressable in most languages.
pub hint: &'a (BlindedPayInfo, BlindedPath),
/// Index of the hint in the original list of blinded hints.
///
// inserting first hops suggested by the caller as targets.
// Our search will then attempt to reach them while traversing from the payee node.
let mut first_hop_targets: HashMap<_, Vec<&ChannelDetails>> =
- HashMap::with_capacity(if first_hops.is_some() { first_hops.as_ref().unwrap().len() } else { 0 });
+ hash_map_with_capacity(if first_hops.is_some() { first_hops.as_ref().unwrap().len() } else { 0 });
if let Some(hops) = first_hops {
for chan in hops {
if chan.get_outbound_payment_scid().is_none() {
}
}
- let mut private_hop_key_cache = HashMap::with_capacity(
+ let mut private_hop_key_cache = hash_map_with_capacity(
payment_params.payee.unblinded_route_hints().iter().map(|path| path.0.len()).sum()
);
// Map from node_id to information about the best current path to that node, including feerate
// information.
- let mut dist: HashMap<NodeId, PathBuildingHop> = HashMap::with_capacity(network_nodes.len());
+ let mut dist: HashMap<NodeId, PathBuildingHop> = hash_map_with_capacity(network_nodes.len());
// During routing, if we ignore a path due to an htlc_minimum_msat limit, we set this,
// indicating that we may wish to try again with a higher value, potentially paying to meet an
// is used. Hence, liquidity used in one direction will not offset any used in the opposite
// direction.
let mut used_liquidities: HashMap<CandidateHopId, u64> =
- HashMap::with_capacity(network_nodes.len());
+ hash_map_with_capacity(network_nodes.len());
// Keeping track of how much value we already collected across other paths. Helps to decide
// when we want to stop looking for new paths.
let mut aggregate_path_contribution_msat = path_value_msat;
for (idx, (hop, prev_hop_id)) in hop_iter.zip(prev_hop_iter).enumerate() {
- let target = private_hop_key_cache.get(&prev_hop_id).unwrap();
+ let target = private_hop_key_cache.get(prev_hop_id).unwrap();
- if let Some(first_channels) = first_hop_targets.get(&target) {
+ if let Some(first_channels) = first_hop_targets.get(target) {
if first_channels.iter().any(|d| d.outbound_scid_alias == Some(hop.short_channel_id)) {
log_trace!(logger, "Ignoring route hint with SCID {} (and any previous) due to it being a direct channel of ours.",
hop.short_channel_id);
let candidate = network_channels
.get(&hop.short_channel_id)
- .and_then(|channel| channel.as_directed_to(&target))
+ .and_then(|channel| channel.as_directed_to(target))
.map(|(info, _)| CandidateRouteHop::PublicHop(PublicHopCandidate {
info,
short_channel_id: hop.short_channel_id,
.saturating_add(1);
// Searching for a direct channel between last checked hop and first_hop_targets
- if let Some(first_channels) = first_hop_targets.get_mut(&target) {
+ if let Some(first_channels) = first_hop_targets.get_mut(target) {
sort_first_hop_channels(first_channels, &used_liquidities,
recommended_value_msat, our_node_pubkey);
for details in first_channels {
base_penalty_amount_multiplier_msat: 8192,
liquidity_penalty_multiplier_msat: 30_000,
liquidity_penalty_amount_multiplier_msat: 192,
- manual_node_penalties: HashMap::new(),
+ manual_node_penalties: new_hash_map(),
anti_probing_penalty_msat: 250,
considered_impossible_penalty_msat: 1_0000_0000_000,
historical_liquidity_penalty_multiplier_msat: 10_000,
/// Clears the list of manual penalties that are applied during path finding.
pub fn clear_manual_penalties(&mut self) {
- self.manual_node_penalties = HashMap::new();
+ self.manual_node_penalties = new_hash_map();
}
}
liquidity_penalty_amount_multiplier_msat: 0,
historical_liquidity_penalty_multiplier_msat: 0,
historical_liquidity_penalty_amount_multiplier_msat: 0,
- manual_node_penalties: HashMap::new(),
+ manual_node_penalties: new_hash_map(),
anti_probing_penalty_msat: 0,
considered_impossible_penalty_msat: 0,
linear_success_probability: true,
decay_params,
network_graph,
logger,
- channel_liquidities: HashMap::new(),
+ channel_liquidities: new_hash_map(),
}
}
_ => return 0,
};
let source = candidate.source();
- if let Some(penalty) = score_params.manual_node_penalties.get(&target) {
+ if let Some(penalty) = score_params.manual_node_penalties.get(target) {
return *penalty;
}
let amount_msat = usage.amount_msat.saturating_add(usage.inflight_htlc_msat);
let capacity_msat = usage.effective_capacity.as_msat();
self.channel_liquidities
- .get(&scid)
+ .get(scid)
.unwrap_or(&ChannelLiquidity::new(Duration::ZERO))
.as_directed(&source, &target, capacity_msat)
.penalty_msat(amount_msat, score_params)
r: &mut R, args: (ProbabilisticScoringDecayParameters, G, L)
) -> Result<Self, DecodeError> {
let (decay_params, network_graph, logger) = args;
- let mut channel_liquidities = HashMap::new();
+ let mut channel_liquidities = new_hash_map();
read_tlv_fields!(r, {
(0, channel_liquidities, required),
});
impl PendingChecks {
pub(super) fn new() -> Self {
PendingChecks { internal: Mutex::new(PendingChecksContext {
- channels: HashMap::new(), nodes: HashMap::new(),
+ channels: new_hash_map(), nodes: new_hash_map(),
}) }
}
let mut input = Vec::with_capacity(descriptors.len());
let mut input_value = 0;
let mut witness_weight = 0;
- let mut output_set = HashSet::with_capacity(descriptors.len());
+ let mut output_set = hash_set_with_capacity(descriptors.len());
for outp in descriptors {
match outp {
SpendableOutputDescriptor::StaticPaymentOutput(descriptor) => {
pub use std::sync::WaitTimeoutResult;
-use crate::prelude::HashMap;
+use crate::prelude::*;
use super::{LockTestExt, LockHeldState};
thread_local! {
/// We track the set of locks currently held by a reference to their `LockMetadata`
- static LOCKS_HELD: RefCell<HashMap<u64, Arc<LockMetadata>>> = RefCell::new(HashMap::new());
+ static LOCKS_HELD: RefCell<HashMap<u64, Arc<LockMetadata>>> = RefCell::new(new_hash_map());
}
static LOCK_IDX: AtomicUsize = AtomicUsize::new(0);
let lock_idx = LOCK_IDX.fetch_add(1, Ordering::Relaxed) as u64;
let res = Arc::new(LockMetadata {
- locked_before: StdMutex::new(HashMap::new()),
+ locked_before: StdMutex::new(new_hash_map()),
lock_idx,
_lock_construction_bt: backtrace,
});
{
let (lock_constr_location, lock_constr_colno) =
locate_call_symbol(&res._lock_construction_bt);
- LOCKS_INIT.call_once(|| { unsafe { LOCKS = Some(StdMutex::new(HashMap::new())); } });
+ LOCKS_INIT.call_once(|| { unsafe { LOCKS = Some(StdMutex::new(new_hash_map())); } });
let mut locks = unsafe { LOCKS.as_ref() }.unwrap().lock().unwrap();
match locks.entry(lock_constr_location) {
hash_map::Entry::Occupied(e) => {
use crate::ln::channel::MAX_FUNDING_SATOSHIS_NO_WUMBO;
use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
+#[cfg(fuzzing)]
+use crate::util::ser::Readable;
+
/// Configuration we set when applicable.
///
/// Default::default() provides sane defaults.
}
}
+// When fuzzing, we want to allow the fuzzer to pick any configuration parameters. Thus, we
+// implement Readable here in a naive way (which is a bit easier for the fuzzer to handle). We
+// don't really want to ever expose this to users (if we did we'd want to use TLVs).
+#[cfg(fuzzing)]
+impl Readable for ChannelHandshakeConfig {
+ fn read<R: crate::io::Read>(reader: &mut R) -> Result<Self, crate::ln::msgs::DecodeError> {
+ Ok(Self {
+ minimum_depth: Readable::read(reader)?,
+ our_to_self_delay: Readable::read(reader)?,
+ our_htlc_minimum_msat: Readable::read(reader)?,
+ max_inbound_htlc_value_in_flight_percent_of_channel: Readable::read(reader)?,
+ negotiate_scid_privacy: Readable::read(reader)?,
+ announced_channel: Readable::read(reader)?,
+ commit_upfront_shutdown_pubkey: Readable::read(reader)?,
+ their_channel_reserve_proportional_millionths: Readable::read(reader)?,
+ negotiate_anchors_zero_fee_htlc_tx: Readable::read(reader)?,
+ our_max_accepted_htlcs: Readable::read(reader)?,
+ })
+ }
+}
+
/// Optional channel limits which are applied during channel creation.
///
/// These limits are only applied to our counterparty's limits, not our own.
}
}
+// When fuzzing, we want to allow the fuzzer to pick any configuration parameters. Thus, we
+// implement Readable here in a naive way (which is a bit easier for the fuzzer to handle). We
+// don't really want to ever expose this to users (if we did we'd want to use TLVs).
+#[cfg(fuzzing)]
+impl Readable for ChannelHandshakeLimits {
+ fn read<R: crate::io::Read>(reader: &mut R) -> Result<Self, crate::ln::msgs::DecodeError> {
+ Ok(Self {
+ min_funding_satoshis: Readable::read(reader)?,
+ max_funding_satoshis: Readable::read(reader)?,
+ max_htlc_minimum_msat: Readable::read(reader)?,
+ min_max_htlc_value_in_flight_msat: Readable::read(reader)?,
+ max_channel_reserve_satoshis: Readable::read(reader)?,
+ min_max_accepted_htlcs: Readable::read(reader)?,
+ trust_own_funding_0conf: Readable::read(reader)?,
+ max_minimum_depth: Readable::read(reader)?,
+ force_announced_channel_preference: Readable::read(reader)?,
+ their_to_self_delay: Readable::read(reader)?,
+ })
+ }
+}
+
/// Options for how to set the max dust HTLC exposure allowed on a channel. See
/// [`ChannelConfig::max_dust_htlc_exposure`] for details.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
}
}
}
+
+// When fuzzing, we want to allow the fuzzer to pick any configuration parameters. Thus, we
+// implement Readable here in a naive way (which is a bit easier for the fuzzer to handle). We
+// don't really want to ever expose this to users (if we did we'd want to use TLVs).
+#[cfg(fuzzing)]
+impl Readable for UserConfig {
+ fn read<R: crate::io::Read>(reader: &mut R) -> Result<Self, crate::ln::msgs::DecodeError> {
+ Ok(Self {
+ channel_handshake_config: Readable::read(reader)?,
+ channel_handshake_limits: Readable::read(reader)?,
+ channel_config: Readable::read(reader)?,
+ accept_forwards_to_priv_channels: Readable::read(reader)?,
+ accept_inbound_channels: Readable::read(reader)?,
+ manually_accept_inbound_channels: Readable::read(reader)?,
+ accept_intercept_htlcs: Readable::read(reader)?,
+ accept_mpp_keysend: Readable::read(reader)?,
+ })
+ }
+}
//! This module has a map which can be iterated in a deterministic order. See the [`IndexedMap`].
-use crate::prelude::{HashMap, hash_map};
+use crate::prelude::*;
use alloc::vec::Vec;
use alloc::slice::Iter;
use core::hash::Hash;
/// Constructs a new, empty map
pub fn new() -> Self {
Self {
- map: HashMap::new(),
+ map: new_hash_map(),
keys: Vec::new(),
}
}
/// Constructs a new, empty map with the given capacity pre-allocated
pub fn with_capacity(capacity: usize) -> Self {
Self {
- map: HashMap::with_capacity(capacity),
+ map: hash_map_with_capacity(capacity),
keys: Vec::with_capacity(capacity),
}
}
///
/// This is not exported to bindings users as bindings provide alternate accessors rather than exposing maps directly.
pub struct VacantEntry<'a, K: Hash + Ord, V> {
- #[cfg(feature = "hashbrown")]
- underlying_entry: hash_map::VacantEntry<'a, K, V, hash_map::DefaultHashBuilder>,
- #[cfg(not(feature = "hashbrown"))]
- underlying_entry: hash_map::VacantEntry<'a, K, V>,
+ underlying_entry: VacantHashMapEntry<'a, K, V>,
key: K,
keys: &'a mut Vec<K>,
}
///
/// This is not exported to bindings users as bindings provide alternate accessors rather than exposing maps directly.
pub struct OccupiedEntry<'a, K: Hash + Ord, V> {
- #[cfg(feature = "hashbrown")]
- underlying_entry: hash_map::OccupiedEntry<'a, K, V, hash_map::DefaultHashBuilder>,
- #[cfg(not(feature = "hashbrown"))]
- underlying_entry: hash_map::OccupiedEntry<'a, K, V>,
+ underlying_entry: OccupiedHashMapEntry<'a, K, V>,
keys: &'a mut Vec<K>,
}
}
}
+macro_rules! impl_record {
+ ($($args: lifetime)?, $($nonstruct_args: lifetime)?) => {
/// A Record, unit of logging output with Metadata to enable filtering
/// Module_path, file, line to inform on log's source
#[derive(Clone, Debug)]
-pub struct Record<'a> {
+pub struct Record<$($args)?> {
/// The verbosity level of the message.
pub level: Level,
/// The node id of the peer pertaining to the logged record.
pub file: &'static str,
/// The line containing the message.
pub line: u32,
-
- #[cfg(c_bindings)]
- /// We don't actually use the lifetime parameter in C bindings (as there is no good way to
- /// communicate a lifetime to a C, or worse, Java user).
- _phantom: core::marker::PhantomData<&'a ()>,
}
-impl<'a> Record<'a> {
+impl<$($args)?> Record<$($args)?> {
/// Returns a new Record.
///
/// This is not exported to bindings users as fmt can't be used in C
#[inline]
- pub fn new(
+ pub fn new<$($nonstruct_args)?>(
level: Level, peer_id: Option<PublicKey>, channel_id: Option<ChannelId>,
args: fmt::Arguments<'a>, module_path: &'static str, file: &'static str, line: u32
- ) -> Record<'a> {
+ ) -> Record<$($args)?> {
Record {
level,
peer_id,
module_path,
file,
line,
- #[cfg(c_bindings)]
- _phantom: core::marker::PhantomData,
}
}
}
+} }
+#[cfg(not(c_bindings))]
+impl_record!('a, );
+#[cfg(c_bindings)]
+impl_record!(, 'a);
/// A trait encapsulating the operations required of a logger.
pub trait Logger {
}
/// Adds relevant context to a [`Record`] before passing it to the wrapped [`Logger`].
+///
+/// This is not exported to bindings users as lifetimes are problematic and there's little reason
+/// for this to be used downstream anyway.
pub struct WithContext<'a, L: Deref> where L::Target: Logger {
/// The logger to delegate to after adding context to the record.
logger: &'a L,
}
impl_for_map!(BTreeMap, Ord, |_| BTreeMap::new());
-impl_for_map!(HashMap, Hash, |len| HashMap::with_capacity(len));
+impl_for_map!(HashMap, Hash, |len| hash_map_with_capacity(len));
// HashSet
impl<T> Writeable for HashSet<T>
#[inline]
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
let len: CollectionLength = Readable::read(r)?;
- let mut ret = HashSet::with_capacity(cmp::min(len.0 as usize, MAX_BUF_SIZE / core::mem::size_of::<T>()));
+ let mut ret = hash_set_with_capacity(cmp::min(len.0 as usize, MAX_BUF_SIZE / core::mem::size_of::<T>()));
for _ in 0..len.0 {
if !ret.insert(T::read(r)?) {
return Err(DecodeError::InvalidValue)
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use core::mem;
use bitcoin::bech32::u5;
-use crate::sign::{InMemorySigner, Recipient, EntropySource, NodeSigner, SignerProvider};
+use crate::sign::{InMemorySigner, RandomBytes, Recipient, EntropySource, NodeSigner, SignerProvider};
#[cfg(feature = "std")]
use std::time::{SystemTime, UNIX_EPOCH};
pub router: DefaultRouter<
Arc<NetworkGraph<&'a TestLogger>>,
&'a TestLogger,
+ Arc<RandomBytes>,
&'a RwLock<TestScorer>,
(),
TestScorer,
>,
+ //pub entropy_source: &'a RandomBytes,
pub network_graph: Arc<NetworkGraph<&'a TestLogger>>,
pub next_routes: Mutex<VecDeque<(RouteParameters, Result<Route, LightningError>)>>,
pub scorer: &'a RwLock<TestScorer>,
impl<'a> TestRouter<'a> {
pub fn new(
network_graph: Arc<NetworkGraph<&'a TestLogger>>, logger: &'a TestLogger,
- scorer: &'a RwLock<TestScorer>
+ scorer: &'a RwLock<TestScorer>,
) -> Self {
+ let entropy_source = Arc::new(RandomBytes::new([42; 32]));
Self {
- router: DefaultRouter::new(network_graph.clone(), logger, [42u8; 32], scorer, ()),
+ router: DefaultRouter::new(network_graph.clone(), logger, entropy_source, scorer, ()),
network_graph,
next_routes: Mutex::new(VecDeque::new()),
scorer,
details: first_hops[idx],
payer_node_id: &node_id,
});
- scorer.channel_penalty_msat(&candidate, usage, &());
+ scorer.channel_penalty_msat(&candidate, usage, &Default::default());
continue;
}
}
info: directed,
short_channel_id: hop.short_channel_id,
});
- scorer.channel_penalty_msat(&candidate, usage, &());
+ scorer.channel_penalty_msat(&candidate, usage, &Default::default());
} else {
let target_node_id = NodeId::from_pubkey(&hop.pubkey);
let route_hint = RouteHintHop {
hint: &route_hint,
target_node_id: &target_node_id,
});
- scorer.channel_penalty_msat(&candidate, usage, &());
+ scorer.channel_penalty_msat(&candidate, usage, &Default::default());
}
prev_hop_node = &hop.pubkey;
}
}
fn create_blinded_payment_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
+ T: secp256k1::Signing + secp256k1::Verification
>(
&self, recipient: PublicKey, first_hops: Vec<ChannelDetails>, tlvs: ReceiveTlvs,
- amount_msats: u64, entropy_source: &ES, secp_ctx: &Secp256k1<T>
+ amount_msats: u64, secp_ctx: &Secp256k1<T>,
) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
self.router.create_blinded_payment_paths(
- recipient, first_hops, tlvs, amount_msats, entropy_source, secp_ctx
+ recipient, first_hops, tlvs, amount_msats, secp_ctx
)
}
}
}
fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
+ T: secp256k1::Signing + secp256k1::Verification
>(
- &self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
- secp_ctx: &Secp256k1<T>
+ &self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
- self.router.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
+ self.router.create_blinded_paths(recipient, peers, secp_ctx)
}
}
}
pub struct TestMessageRouter<'a> {
- inner: DefaultMessageRouter<Arc<NetworkGraph<&'a TestLogger>>, &'a TestLogger>,
+ inner: DefaultMessageRouter<Arc<NetworkGraph<&'a TestLogger>>, &'a TestLogger, &'a TestKeysInterface>,
}
impl<'a> TestMessageRouter<'a> {
- pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>) -> Self {
- Self { inner: DefaultMessageRouter::new(network_graph) }
+ pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>, entropy_source: &'a TestKeysInterface) -> Self {
+ Self { inner: DefaultMessageRouter::new(network_graph, entropy_source) }
}
}
self.inner.find_path(sender, peers, destination)
}
- fn create_blinded_paths<
- ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
- >(
- &self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
- secp_ctx: &Secp256k1<T>
+ fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
+ &self, recipient: PublicKey, peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
) -> Result<Vec<BlindedPath>, ()> {
- self.inner.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
+ self.inner.create_blinded_paths(recipient, peers, secp_ctx)
}
}
pub fn new(chain_source: Option<&'a TestChainSource>, broadcaster: &'a dyn chaininterface::BroadcasterInterface, logger: &'a TestLogger, fee_estimator: &'a TestFeeEstimator, persister: &'a dyn chainmonitor::Persist<TestChannelSigner>, keys_manager: &'a TestKeysInterface) -> Self {
Self {
added_monitors: Mutex::new(Vec::new()),
- monitor_updates: Mutex::new(HashMap::new()),
- latest_monitor_update_id: Mutex::new(HashMap::new()),
+ monitor_updates: Mutex::new(new_hash_map()),
+ latest_monitor_update_id: Mutex::new(new_hash_map()),
chain_monitor: chainmonitor::ChainMonitor::new(chain_source, broadcaster, logger, fee_estimator, persister),
keys_manager,
expect_channel_force_closed: Mutex::new(None),
pub(crate) fn new(destination_script: ScriptBuf) -> Self {
WatchtowerPersister {
persister: TestPersister::new(),
- unsigned_justice_tx_data: Mutex::new(HashMap::new()),
- watchtower_state: Mutex::new(HashMap::new()),
+ unsigned_justice_tx_data: Mutex::new(new_hash_map()),
+ watchtower_state: Mutex::new(new_hash_map()),
destination_script,
}
}
assert!(self.unsigned_justice_tx_data.lock().unwrap()
.insert(funding_txo, VecDeque::new()).is_none());
assert!(self.watchtower_state.lock().unwrap()
- .insert(funding_txo, HashMap::new()).is_none());
+ .insert(funding_txo, new_hash_map()).is_none());
let initial_counterparty_commitment_tx = data.initial_counterparty_commitment_tx()
.expect("First and only call expects Some");
pub fn new() -> Self {
Self {
update_rets: Mutex::new(VecDeque::new()),
- chain_sync_monitor_persistences: Mutex::new(HashMap::new()),
- offchain_monitor_updates: Mutex::new(HashMap::new()),
+ chain_sync_monitor_persistences: Mutex::new(new_hash_map()),
+ offchain_monitor_updates: Mutex::new(new_hash_map()),
}
}
}
let is_chain_sync = if let UpdateOrigin::ChainSync(_) = update_id.contents { true } else { false };
if is_chain_sync {
- self.chain_sync_monitor_persistences.lock().unwrap().entry(funding_txo).or_insert(HashSet::new()).insert(update_id);
+ self.chain_sync_monitor_persistences.lock().unwrap().entry(funding_txo).or_insert(new_hash_set()).insert(update_id);
} else {
- self.offchain_monitor_updates.lock().unwrap().entry(funding_txo).or_insert(HashSet::new()).insert(update_id);
+ self.offchain_monitor_updates.lock().unwrap().entry(funding_txo).or_insert(new_hash_set()).insert(update_id);
}
ret
}
impl TestStore {
pub fn new(read_only: bool) -> Self {
- let persisted_bytes = Mutex::new(HashMap::new());
+ let persisted_bytes = Mutex::new(new_hash_map());
Self { persisted_bytes, read_only }
}
}
} else {
format!("{}/{}", primary_namespace, secondary_namespace)
};
- let outer_e = persisted_lock.entry(prefixed).or_insert(HashMap::new());
+ let outer_e = persisted_lock.entry(prefixed).or_insert(new_hash_map());
let mut bytes = Vec::new();
bytes.write_all(buf)?;
outer_e.insert(key.to_string(), bytes);
pub fn unique_txn_broadcast(&self) -> Vec<Transaction> {
let mut txn = self.txn_broadcasted.lock().unwrap().split_off(0);
- let mut seen = HashSet::new();
+ let mut seen = new_hash_set();
txn.retain(|tx| seen.insert(tx.txid()));
txn
}
TestChannelMessageHandler {
pending_events: Mutex::new(Vec::new()),
expected_recv_msgs: Mutex::new(None),
- connected_peers: Mutex::new(HashSet::new()),
+ connected_peers: Mutex::new(new_hash_set()),
message_fetch_counter: AtomicUsize::new(0),
chain_hash,
}
TestLogger {
level: Level::Trace,
id,
- lines: Mutex::new(HashMap::new()),
- context: Mutex::new(HashMap::new()),
+ lines: Mutex::new(new_hash_map()),
+ context: Mutex::new(new_hash_map()),
}
}
pub fn enable(&mut self, level: Level) {
backing: sign::PhantomKeysManager::new(seed, now.as_secs(), now.subsec_nanos(), seed),
override_random_bytes: Mutex::new(None),
disable_revocation_policy_check: false,
- enforcement_states: Mutex::new(HashMap::new()),
+ enforcement_states: Mutex::new(new_hash_map()),
expectations: Mutex::new(None),
}
}
chain_hash: ChainHash::using_genesis_block(network),
utxo_ret: Mutex::new(UtxoResult::Sync(Ok(TxOut { value: u64::max_value(), script_pubkey }))),
get_utxo_call_count: AtomicUsize::new(0),
- watched_txn: Mutex::new(HashSet::new()),
- watched_outputs: Mutex::new(HashSet::new()),
+ watched_txn: Mutex::new(new_hash_set()),
+ watched_outputs: Mutex::new(new_hash_set()),
}
}
}