Merge pull request #1790 from tnull/2022-10-inbound-user-channel-id-randomization
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Tue, 15 Nov 2022 22:35:17 +0000 (22:35 +0000)
committerGitHub <noreply@github.com>
Tue, 15 Nov 2022 22:35:17 +0000 (22:35 +0000)
Randomize `user_channel_id` for inbound channels

1  2 
fuzz/src/full_stack.rs
lightning/src/ln/channel.rs
lightning/src/ln/channelmanager.rs
lightning/src/util/events.rs
lightning/src/util/ser.rs
lightning/src/util/ser_macros.rs

diff --combined fuzz/src/full_stack.rs
index eeb3728adf59dc789653a12e4c54835a5a1ea979,dd9c0342fdae9f85a1d01a473d46b14d32a9d321..193085676cdf8267ecf1e570abcf93b87904ddea
@@@ -403,7 -403,7 +403,7 @@@ pub fn do_test(data: &[u8], logger: &Ar
        // Adding new calls to `KeysInterface::get_secure_random_bytes` during startup can change all the
        // keys subsequently generated in this test. Rather than regenerating all the messages manually,
        // it's easier to just increment the counter here so the keys don't change.
-       keys_manager.counter.fetch_sub(2, Ordering::AcqRel);
+       keys_manager.counter.fetch_sub(3, Ordering::AcqRel);
        let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret(Recipient::Node).unwrap());
        let network_graph = Arc::new(NetworkGraph::new(genesis_block(network).block_hash(), Arc::clone(&logger)));
        let gossip_sync = Arc::new(P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger)));
@@@ -796,7 -796,7 +796,7 @@@ mod tests 
                // 030012 - inbound read from peer id 0 of len 18
                // 05ac 03000000000000000000000000000000 - message header indicating message length 1452
                // 0300ff - inbound read from peer id 0 of len 255
 -              // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000000 0000000000003e80 ff00000000000000000000000000000000000000000000000000000000000000 000003f0 00 030000000000000000000000000000000000000000000000000000000000000555 0000000e000001000000000000000003e8000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
 +              // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000000 0000000000003e80 ff00000000000000000000000000000000000000000000000000000000000000 000003f0 00 030000000000000000000000000000000000000000000000000000000000000555 11 020203e8 0401a0 060800000e0000010000 0a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
                // 0300ff - inbound read from peer id 0 of len 255
                // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
                // 0300ff - inbound read from peer id 0 of len 255
                // 0300ff - inbound read from peer id 0 of len 255
                // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
                // 0300c1 - inbound read from peer id 0 of len 193
 -              // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 4e00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
 +              // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ab00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
                //
                // 030012 - inbound read from peer id 0 of len 18
                // 0064 03000000000000000000000000000000 - message header indicating message length 100
                // 030012 - inbound read from peer id 0 of len 18
                // 05ac 03000000000000000000000000000000 - message header indicating message length 1452
                // 0300ff - inbound read from peer id 0 of len 255
 -              // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000001 0000000000003e80 ff00000000000000000000000000000000000000000000000000000000000000 000003f0 00 030000000000000000000000000000000000000000000000000000000000000555 0000000e000001000000000000000003e8000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
 +              // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000001 0000000000003e80 ff00000000000000000000000000000000000000000000000000000000000000 000003f0 00 030000000000000000000000000000000000000000000000000000000000000555 11 020203e8 0401a0 060800000e0000010000 0a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
                // 0300ff - inbound read from peer id 0 of len 255
                // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
                // 0300ff - inbound read from peer id 0 of len 255
                // 0300ff - inbound read from peer id 0 of len 255
                // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
                // 0300c1 - inbound read from peer id 0 of len 193
 -              // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 4e00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
 +              // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ab00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
                //
                // - 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
                // 030012 - inbound read from peer id 0 of len 18
                // 05ac 03000000000000000000000000000000 - message header indicating message length 1452
                // 0300ff - inbound read from peer id 0 of len 255
 -              // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000002 00000000000b0838 ff00000000000000000000000000000000000000000000000000000000000000 000003f0 00 030000000000000000000000000000000000000000000000000000000000000555 0000000e000001000000000000000927c0000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
 +              // 0080 3d00000000000000000000000000000000000000000000000000000000000000 0000000000000002 00000000000b0838 ff00000000000000000000000000000000000000000000000000000000000000 000003f0 00 030000000000000000000000000000000000000000000000000000000000000555 12 02030927c0 0401a0 060800000e0000010000 0a00000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - beginning of update_add_htlc from 0 to 1 via client
                // 0300ff - inbound read from peer id 0 of len 255
                // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
                // 0300ff - inbound read from peer id 0 of len 255
                // 0300ff - inbound read from peer id 0 of len 255
                // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
                // 0300c1 - inbound read from peer id 0 of len 193
 -              // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 4b00000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
 +              // ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 5300000000000000000000000000000000000000000000000000000000000000 03000000000000000000000000000000 - end of update_add_htlc from 0 to 1 via client and mac
                //
                // 030012 - inbound read from peer id 0 of len 18
                // 00a4 03000000000000000000000000000000 - message header indicating message length 164
                // - 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(&::hex::decode("01000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000020300320003000000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000030012000a0300000000000000000000000000000003001a00100002200000022000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000162ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005020900000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d0000000000000000000000000000000000000000000000000000000000000002080000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000010301320003000000000000000000000000000000000000000000000000000000000000000703000000000000000000000000000000030142000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000030112000a0100000000000000000000000000000003011a0010000220000002200001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e05000000000000016200000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500026600000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c0001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000b03011200430100000000000000000000000000000003015300243a000000000000000000000000000000000000000000000000000000000000000267000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000020b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000002640000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a00823a000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000000265000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000020a000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c3010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000020d00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833a00000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020c000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000927c0000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4b000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007501000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006705000000000000000000000000000000000000000000000000000000000000060300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000020f0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013a000000000000000000000000000000000000000000000000000000000000000000000000000000800258020000000000002200204b0000000000000000000000000000000000000000000000000000000000000014c00000000000001600142800000000000000000000000000000000000000050000200c005e0200000001730000000000000000000000000000000000000000000000000000000000000000000000000000000001a701000000000000220020b200000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc<dyn Logger>));
 +              super::do_test(&::hex::decode("01000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000020300320003000000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000030012000a0300000000000000000000000000000003001a00100002200000022000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000162ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005020900000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d0000000000000000000000000000000000000000000000000000000000000002080000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000010301320003000000000000000000000000000000000000000000000000000000000000000703000000000000000000000000000000030142000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000030112000a0100000000000000000000000000000003011a0010000220000002200001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e05000000000000016200000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500026600000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c0001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000b03011200430100000000000000000000000000000003015300243a000000000000000000000000000000000000000000000000000000000000000267000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f00003000000000000000000000000000000000000000000000000000000000000055511020203e80401a0060800000e00000100000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffab000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000020b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000002640000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a00823a000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000000265000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f00003000000000000000000000000000000000000000000000000000000000000055511020203e80401a0060800000e00000100000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffab000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000020a000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c3010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000020d00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833a00000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020c000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005551202030927c00401a0060800000e00000100000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff53000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007501000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006705000000000000000000000000000000000000000000000000000000000000060300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000020f0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013a000000000000000000000000000000000000000000000000000000000000000000000000000000800258020000000000002200204b0000000000000000000000000000000000000000000000000000000000000014c00000000000001600142800000000000000000000000000000000000000050000200c005e0200000001730000000000000000000000000000000000000000000000000000000000000000000000000000000001a701000000000000220020b200000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c000007").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
index 0e304f3074524f56a537681279c558e685a9354d,50881ac9c6b59a004f42317d87a58540112bfb09..5d0c3dd4d57b2510239bd6aeda3d78912b3543e5
@@@ -509,7 -509,7 +509,7 @@@ pub(super) struct Channel<Signer: Sign
  
        inbound_handshake_limits_override: Option<ChannelHandshakeLimits>,
  
-       user_id: u64,
+       user_id: u128,
  
        channel_id: [u8; 32],
        channel_state: u32,
@@@ -902,7 -902,7 +902,7 @@@ impl<Signer: Sign> Channel<Signer> 
        // Constructors:
        pub fn new_outbound<K: Deref, F: Deref>(
                fee_estimator: &LowerBoundedFeeEstimator<F>, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
-               channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig, current_chain_height: u32,
+               channel_value_satoshis: u64, push_msat: u64, user_id: u128, config: &UserConfig, current_chain_height: u32,
                outbound_scid_alias: u64
        ) -> Result<Channel<Signer>, APIError>
        where K::Target: KeysInterface<Signer = Signer>,
        /// Assumes chain_hash has already been checked and corresponds with what we expect!
        pub fn new_from_req<K: Deref, F: Deref, L: Deref>(
                fee_estimator: &LowerBoundedFeeEstimator<F>, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
-               msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig, current_chain_height: u32, logger: &L,
+               msg: &msgs::OpenChannel, user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
                outbound_scid_alias: u64
        ) -> Result<Channel<Signer>, ChannelError>
                where K::Target: KeysInterface<Signer = Signer>,
        pub fn shutdown<K: Deref>(
                &mut self, keys_provider: &K, their_features: &InitFeatures, msg: &msgs::Shutdown
        ) -> Result<(Option<msgs::Shutdown>, Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>), ChannelError>
 -      where K::Target: KeysInterface<Signer = Signer>
 +      where K::Target: KeysInterface
        {
                if self.channel_state & (ChannelState::PeerDisconnected as u32) == ChannelState::PeerDisconnected as u32 {
                        return Err(ChannelError::Close("Peer sent shutdown when we needed a channel_reestablish".to_owned()));
  
        /// Gets the "user_id" value passed into the construction of this channel. It has no special
        /// meaning and exists only to allow users to have a persistent identifier of a channel.
-       pub fn get_user_id(&self) -> u64 {
+       pub fn get_user_id(&self) -> u128 {
                self.user_id
        }
  
                self.channel_transaction_parameters.funding_outpoint
        }
  
 +      /// Returns the block hash in which our funding transaction was confirmed.
 +      pub fn get_funding_tx_confirmed_in(&self) -> Option<BlockHash> {
 +              self.funding_tx_confirmed_in
 +      }
 +
        fn get_holder_selected_contest_delay(&self) -> u16 {
                self.channel_transaction_parameters.holder_selected_contest_delay
        }
        /// should be sent back to the counterparty node.
        ///
        /// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
-       pub fn accept_inbound_channel(&mut self, user_id: u64) -> msgs::AcceptChannel {
+       pub fn accept_inbound_channel(&mut self, user_id: u128) -> msgs::AcceptChannel {
                if self.is_outbound() {
                        panic!("Tried to send accept_channel for an outbound channel?");
                }
        /// holding cell HTLCs for payment failure.
        pub fn get_shutdown<K: Deref>(&mut self, keys_provider: &K, their_features: &InitFeatures, target_feerate_sats_per_kw: Option<u32>)
        -> Result<(msgs::Shutdown, Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>), APIError>
 -      where K::Target: KeysInterface<Signer = Signer> {
 +      where K::Target: KeysInterface {
                for htlc in self.pending_outbound_htlcs.iter() {
                        if let OutboundHTLCState::LocalAnnounced(_) = htlc.state {
                                return Err(APIError::APIMisuseError{err: "Cannot begin shutdown with pending HTLCs. Process pending events first".to_owned()});
@@@ -6007,7 -6002,11 +6007,11 @@@ impl<Signer: Sign> Writeable for Channe
  
                write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
  
-               self.user_id.write(writer)?;
+               // `user_id` used to be a single u64 value. In order to remain backwards compatible with
+               // versions prior to 0.0.113, the u128 is serialized as two separate u64 values. We write
+               // the low bytes now and the optional high bytes later.
+               let user_id_low = self.user_id as u64;
+               user_id_low.write(writer)?;
  
                // Version 1 deserializers expected to read parts of the config object here. Version 2
                // deserializers (0.0.99) now read config through TLVs, and as we now require them for
  
                let channel_ready_event_emitted = Some(self.channel_ready_event_emitted);
  
+               // `user_id` used to be a single u64 value. In order to remain backwards compatible with
+               // versions prior to 0.0.113, the u128 is serialized as two separate u64 values. Therefore,
+               // we write the high bytes as an option here.
+               let user_id_high_opt = Some((self.user_id >> 64) as u64);
                write_tlv_fields!(writer, {
                        (0, self.announcement_sigs, option),
                        // minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a
                        (19, self.latest_inbound_scid_alias, option),
                        (21, self.outbound_scid_alias, required),
                        (23, channel_ready_event_emitted, option),
+                       (25, user_id_high_opt, option),
                });
  
                Ok(())
  }
  
  const MAX_ALLOC_SIZE: usize = 64*1024;
 -impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
 -              where K::Target: KeysInterface<Signer = Signer> {
 +impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInterface>::Signer>
 +              where K::Target: KeysInterface {
        fn read<R : io::Read>(reader: &mut R, args: (&'a K, u32)) -> Result<Self, DecodeError> {
                let (keys_source, serialized_height) = args;
                let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
  
-               let user_id = Readable::read(reader)?;
+               // `user_id` used to be a single u64 value. In order to remain backwards compatible with
+               // versions prior to 0.0.113, the u128 is serialized as two separate u64 values. We read
+               // the low bytes now and the high bytes later.
+               let user_id_low: u64 = Readable::read(reader)?;
  
                let mut config = Some(LegacyChannelConfig::default());
                if ver == 1 {
                let mut outbound_scid_alias = None;
                let mut channel_ready_event_emitted = None;
  
+               let mut user_id_high_opt: Option<u64> = None;
                read_tlv_fields!(reader, {
                        (0, announcement_sigs, option),
                        (1, minimum_depth, option),
                        (19, latest_inbound_scid_alias, option),
                        (21, outbound_scid_alias, option),
                        (23, channel_ready_event_emitted, option),
+                       (25, user_id_high_opt, option),
                });
  
                if let Some(preimages) = preimages_opt {
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
  
+               // `user_id` used to be a single u64 value. In order to remain backwards
+               // compatible with versions prior to 0.0.113, the u128 is serialized as two
+               // separate u64 values.
+               let user_id = user_id_low as u128 + ((user_id_high_opt.unwrap_or(0) as u128) << 64);
                Ok(Channel {
                        user_id,
  
index d3fbc244021b059a16d12509510647801ae93549,561d43df761db9496172dc58f80ae251e76c438f..121c1d4c66c36cb64f21df76823f5d24ace0e97a
@@@ -53,7 -53,7 +53,7 @@@ use crate::ln::msgs::{ChannelMessageHan
  use crate::ln::wire::Encode;
  use crate::chain::keysinterface::{Sign, KeysInterface, KeysManager, Recipient};
  use crate::util::config::{UserConfig, ChannelConfig};
 -use crate::util::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
 +use crate::util::events::{Event, EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
  use crate::util::{byte_utils, events};
  use crate::util::wakers::{Future, Notifier};
  use crate::util::scid_utils::fake_scid;
@@@ -112,8 -112,7 +112,8 @@@ pub(super) struct PendingHTLCInfo 
        pub(super) routing: PendingHTLCRouting,
        pub(super) incoming_shared_secret: [u8; 32],
        payment_hash: PaymentHash,
 -      pub(super) amt_to_forward: u64,
 +      pub(super) incoming_amt_msat: Option<u64>, // Added in 0.0.113
 +      pub(super) outgoing_amt_msat: u64,
        pub(super) outgoing_cltv_value: u32,
  }
  
@@@ -130,22 -129,20 +130,22 @@@ pub(super) enum PendingHTLCStatus 
        Fail(HTLCFailureMsg),
  }
  
 -pub(super) enum HTLCForwardInfo {
 -      AddHTLC {
 -              forward_info: PendingHTLCInfo,
 +pub(super) struct PendingAddHTLCInfo {
 +      pub(super) forward_info: PendingHTLCInfo,
  
 -              // These fields are produced in `forward_htlcs()` and consumed in
 -              // `process_pending_htlc_forwards()` for constructing the
 -              // `HTLCSource::PreviousHopData` for failed and forwarded
 -              // HTLCs.
 -              //
 -              // Note that this may be an outbound SCID alias for the associated channel.
 -              prev_short_channel_id: u64,
 -              prev_htlc_id: u64,
 -              prev_funding_outpoint: OutPoint,
 -      },
 +      // These fields are produced in `forward_htlcs()` and consumed in
 +      // `process_pending_htlc_forwards()` for constructing the
 +      // `HTLCSource::PreviousHopData` for failed and forwarded
 +      // HTLCs.
 +      //
 +      // Note that this may be an outbound SCID alias for the associated channel.
 +      prev_short_channel_id: u64,
 +      prev_htlc_id: u64,
 +      prev_funding_outpoint: OutPoint,
 +}
 +
 +pub(super) enum HTLCForwardInfo {
 +      AddHTLC(PendingAddHTLCInfo),
        FailHTLC {
                htlc_id: u64,
                err_packet: msgs::OnionErrorPacket,
@@@ -292,7 -289,7 +292,7 @@@ type ShutdownResult = (Option<(OutPoint
  
  struct MsgHandleErrInternal {
        err: msgs::LightningError,
-       chan_id: Option<([u8; 32], u64)>, // If Some a channel of ours has been closed
+       chan_id: Option<([u8; 32], u128)>, // If Some a channel of ours has been closed
        shutdown_finish: Option<(ShutdownResult, Option<msgs::ChannelUpdate>)>,
  }
  impl MsgHandleErrInternal {
                Self { err, chan_id: None, shutdown_finish: None }
        }
        #[inline]
-       fn from_finish_shutdown(err: String, channel_id: [u8; 32], user_channel_id: u64, shutdown_res: ShutdownResult, channel_update: Option<msgs::ChannelUpdate>) -> Self {
+       fn from_finish_shutdown(err: String, channel_id: [u8; 32], user_channel_id: u128, shutdown_res: ShutdownResult, channel_update: Option<msgs::ChannelUpdate>) -> Self {
                Self {
                        err: LightningError {
                                err: err.clone(),
@@@ -1086,8 -1083,9 +1086,9 @@@ pub struct ChannelDetails 
        ///
        /// [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat
        pub unspendable_punishment_reserve: Option<u64>,
-       /// The `user_channel_id` passed in to create_channel, or 0 if the channel was inbound.
-       pub user_channel_id: u64,
+       /// The `user_channel_id` passed in to create_channel, or a random value if the channel was
+       /// inbound.
+       pub user_channel_id: u128,
        /// Our total balance.  This is the amount we would get if we close the channel.
        /// This value is not exact. Due to various in-flight changes and feerate changes, exactly this
        /// amount is not likely to be recoverable on close.
@@@ -1722,10 -1720,9 +1723,9 @@@ impl<M: Deref, T: Deref, K: Deref, F: D
        ///
        /// `user_channel_id` will be provided back as in
        /// [`Event::FundingGenerationReady::user_channel_id`] to allow tracking of which events
-       /// correspond with which `create_channel` call. Note that the `user_channel_id` defaults to 0
-       /// for inbound channels, so you may wish to avoid using 0 for `user_channel_id` here.
-       /// `user_channel_id` has no meaning inside of LDK, it is simply copied to events and otherwise
-       /// ignored.
+       /// correspond with which `create_channel` call. Note that the `user_channel_id` defaults to a
+       /// randomized value for inbound channels. `user_channel_id` has no meaning inside of LDK, it
+       /// is simply copied to events and otherwise ignored.
        ///
        /// Raises [`APIError::APIMisuseError`] when `channel_value_satoshis` > 2**24 or `push_msat` is
        /// greater than `channel_value_satoshis * 1k` or `channel_value_satoshis < 1000`.
        /// [`Event::FundingGenerationReady::user_channel_id`]: events::Event::FundingGenerationReady::user_channel_id
        /// [`Event::FundingGenerationReady::temporary_channel_id`]: events::Event::FundingGenerationReady::temporary_channel_id
        /// [`Event::ChannelClosed::channel_id`]: events::Event::ChannelClosed::channel_id
-       pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_channel_id: u64, override_config: Option<UserConfig>) -> Result<[u8; 32], APIError> {
+       pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_channel_id: u128, override_config: Option<UserConfig>) -> Result<[u8; 32], APIError> {
                if channel_value_satoshis < 1000 {
                        return Err(APIError::APIMisuseError { err: format!("Channel value must be at least 1000 satoshis. It was {}", channel_value_satoshis) });
                }
                }
  
                let routing = match hop_data.format {
 -                      msgs::OnionHopDataFormat::Legacy { .. } => {
 -                              return Err(ReceiveError {
 -                                      err_code: 0x4000|0x2000|3,
 -                                      err_data: Vec::new(),
 -                                      msg: "We require payment_secrets",
 -                              });
 -                      },
                        msgs::OnionHopDataFormat::NonFinalNode { .. } => {
                                return Err(ReceiveError {
                                        err_code: 0x4000|22,
                        routing,
                        payment_hash,
                        incoming_shared_secret: shared_secret,
 -                      amt_to_forward: amt_msat,
 +                      incoming_amt_msat: Some(amt_msat),
 +                      outgoing_amt_msat: amt_msat,
                        outgoing_cltv_value: hop_data.outgoing_cltv_value,
                })
        }
                                };
  
                                let short_channel_id = match next_hop_data.format {
 -                                      msgs::OnionHopDataFormat::Legacy { short_channel_id } => short_channel_id,
                                        msgs::OnionHopDataFormat::NonFinalNode { short_channel_id } => short_channel_id,
                                        msgs::OnionHopDataFormat::FinalNode { .. } => {
                                                return_err!("Final Node OnionHopData provided for us as an intermediary node", 0x4000 | 22, &[0;0]);
                                        },
                                        payment_hash: msg.payment_hash.clone(),
                                        incoming_shared_secret: shared_secret,
 -                                      amt_to_forward: next_hop_data.amt_to_forward,
 +                                      incoming_amt_msat: Some(msg.amount_msat),
 +                                      outgoing_amt_msat: next_hop_data.amt_to_forward,
                                        outgoing_cltv_value: next_hop_data.outgoing_cltv_value,
                                })
                        }
                };
  
 -              if let &PendingHTLCStatus::Forward(PendingHTLCInfo { ref routing, ref amt_to_forward, ref outgoing_cltv_value, .. }) = &pending_forward_info {
 +              if let &PendingHTLCStatus::Forward(PendingHTLCInfo { ref routing, ref outgoing_amt_msat, ref outgoing_cltv_value, .. }) = &pending_forward_info {
                        // If short_channel_id is 0 here, we'll reject the HTLC as there cannot be a channel
                        // with a short_channel_id of 0. This is important as various things later assume
                        // short_channel_id is non-0 in any ::Forward.
                                                None => { // unknown_next_peer
                                                        // Note that this is likely a timing oracle for detecting whether an scid is a
                                                        // phantom.
 -                                                      if fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, *short_channel_id) {
 +                                                      if fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, *short_channel_id, &self.genesis_hash) {
                                                                None
                                                        } else {
                                                                break Some(("Don't have available channel for forwarding as requested.", 0x4000 | 10, None));
                                                if !chan.is_live() { // channel_disabled
                                                        break Some(("Forwarding channel is not in a ready state.", 0x1000 | 20, chan_update_opt));
                                                }
 -                                              if *amt_to_forward < chan.get_counterparty_htlc_minimum_msat() { // amount_below_minimum
 +                                              if *outgoing_amt_msat < chan.get_counterparty_htlc_minimum_msat() { // amount_below_minimum
                                                        break Some(("HTLC amount was below the htlc_minimum_msat", 0x1000 | 11, chan_update_opt));
                                                }
 -                                              if let Err((err, code)) = chan.htlc_satisfies_config(&msg, *amt_to_forward, *outgoing_cltv_value) {
 +                                              if let Err((err, code)) = chan.htlc_satisfies_config(&msg, *outgoing_amt_msat, *outgoing_cltv_value) {
                                                        break Some((err, code, chan_update_opt));
                                                }
                                                chan_update_opt
                                                () => {
                                                        for forward_info in pending_forwards.drain(..) {
                                                                match forward_info {
 -                                                                      HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
 -                                                                              routing, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value },
 -                                                                              prev_funding_outpoint } => {
 -                                                                                      macro_rules! failure_handler {
 -                                                                                              ($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr, $next_hop_unknown: expr) => {
 -                                                                                                      log_info!(self.logger, "Failed to accept/forward incoming HTLC: {}", $msg);
 -
 -                                                                                                      let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
 -                                                                                                              short_channel_id: prev_short_channel_id,
 -                                                                                                              outpoint: prev_funding_outpoint,
 -                                                                                                              htlc_id: prev_htlc_id,
 -                                                                                                              incoming_packet_shared_secret: incoming_shared_secret,
 -                                                                                                              phantom_shared_secret: $phantom_ss,
 -                                                                                                      });
 -
 -                                                                                                      let reason = if $next_hop_unknown {
 -                                                                                                              HTLCDestination::UnknownNextHop { requested_forward_scid: short_chan_id }
 -                                                                                                      } else {
 -                                                                                                              HTLCDestination::FailedPayment{ payment_hash }
 -                                                                                                      };
 -
 -                                                                                                      failed_forwards.push((htlc_source, payment_hash,
 -                                                                                                              HTLCFailReason::Reason { failure_code: $err_code, data: $err_data },
 -                                                                                                              reason
 -                                                                                                      ));
 -                                                                                                      continue;
 -                                                                                              }
 +                                                                      HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
 +                                                                              prev_short_channel_id, prev_htlc_id, prev_funding_outpoint,
 +                                                                              forward_info: PendingHTLCInfo {
 +                                                                                      routing, incoming_shared_secret, payment_hash, outgoing_amt_msat,
 +                                                                                      outgoing_cltv_value, incoming_amt_msat: _
 +                                                                              }
 +                                                                      }) => {
 +                                                                              macro_rules! failure_handler {
 +                                                                                      ($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr, $next_hop_unknown: expr) => {
 +                                                                                              log_info!(self.logger, "Failed to accept/forward incoming HTLC: {}", $msg);
 +
 +                                                                                              let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
 +                                                                                                      short_channel_id: prev_short_channel_id,
 +                                                                                                      outpoint: prev_funding_outpoint,
 +                                                                                                      htlc_id: prev_htlc_id,
 +                                                                                                      incoming_packet_shared_secret: incoming_shared_secret,
 +                                                                                                      phantom_shared_secret: $phantom_ss,
 +                                                                                              });
 +
 +                                                                                              let reason = if $next_hop_unknown {
 +                                                                                                      HTLCDestination::UnknownNextHop { requested_forward_scid: short_chan_id }
 +                                                                                              } else {
 +                                                                                                      HTLCDestination::FailedPayment{ payment_hash }
 +                                                                                              };
 +
 +                                                                                              failed_forwards.push((htlc_source, payment_hash,
 +                                                                                                      HTLCFailReason::Reason { failure_code: $err_code, data: $err_data },
 +                                                                                                      reason
 +                                                                                              ));
 +                                                                                              continue;
                                                                                        }
 -                                                                                      macro_rules! fail_forward {
 -                                                                                              ($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr) => {
 -                                                                                                      {
 -                                                                                                              failure_handler!($msg, $err_code, $err_data, $phantom_ss, true);
 -                                                                                                      }
 +                                                                              }
 +                                                                              macro_rules! fail_forward {
 +                                                                                      ($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr) => {
 +                                                                                              {
 +                                                                                                      failure_handler!($msg, $err_code, $err_data, $phantom_ss, true);
                                                                                                }
                                                                                        }
 -                                                                                      macro_rules! failed_payment {
 -                                                                                              ($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr) => {
 -                                                                                                      {
 -                                                                                                              failure_handler!($msg, $err_code, $err_data, $phantom_ss, false);
 -                                                                                                      }
 +                                                                              }
 +                                                                              macro_rules! failed_payment {
 +                                                                                      ($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr) => {
 +                                                                                              {
 +                                                                                                      failure_handler!($msg, $err_code, $err_data, $phantom_ss, false);
                                                                                                }
                                                                                        }
 -                                                                                      if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
 -                                                                                              let phantom_secret_res = self.keys_manager.get_node_secret(Recipient::PhantomNode);
 -                                                                                              if phantom_secret_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id) {
 -                                                                                                      let phantom_shared_secret = SharedSecret::new(&onion_packet.public_key.unwrap(), &phantom_secret_res.unwrap()).secret_bytes();
 -                                                                                                      let next_hop = match onion_utils::decode_next_payment_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
 -                                                                                                              Ok(res) => res,
 -                                                                                                              Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
 -                                                                                                                      let sha256_of_onion = Sha256::hash(&onion_packet.hop_data).into_inner();
 -                                                                                                                      // In this scenario, the phantom would have sent us an
 -                                                                                                                      // `update_fail_malformed_htlc`, meaning here we encrypt the error as
 -                                                                                                                      // if it came from us (the second-to-last hop) but contains the sha256
 -                                                                                                                      // of the onion.
 -                                                                                                                      failed_payment!(err_msg, err_code, sha256_of_onion.to_vec(), None);
 -                                                                                                              },
 -                                                                                                              Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code }) => {
 -                                                                                                                      failed_payment!(err_msg, err_code, Vec::new(), Some(phantom_shared_secret));
 -                                                                                                              },
 -                                                                                                      };
 -                                                                                                      match next_hop {
 -                                                                                                              onion_utils::Hop::Receive(hop_data) => {
 -                                                                                                                      match self.construct_recv_pending_htlc_info(hop_data, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value, Some(phantom_shared_secret)) {
 -                                                                                                                              Ok(info) => phantom_receives.push((prev_short_channel_id, prev_funding_outpoint, vec![(info, prev_htlc_id)])),
 -                                                                                                                              Err(ReceiveError { err_code, err_data, msg }) => failed_payment!(msg, err_code, err_data, Some(phantom_shared_secret))
 -                                                                                                                      }
 -                                                                                                              },
 -                                                                                                              _ => panic!(),
 -                                                                                                      }
 -                                                                                              } else {
 -                                                                                                      fail_forward!(format!("Unknown short channel id {} for forward HTLC", short_chan_id), 0x4000 | 10, Vec::new(), None);
 +                                                                              }
 +                                                                              if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
 +                                                                                      let phantom_secret_res = self.keys_manager.get_node_secret(Recipient::PhantomNode);
 +                                                                                      if phantom_secret_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
 +                                                                                              let phantom_shared_secret = SharedSecret::new(&onion_packet.public_key.unwrap(), &phantom_secret_res.unwrap()).secret_bytes();
 +                                                                                              let next_hop = match onion_utils::decode_next_payment_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
 +                                                                                                      Ok(res) => res,
 +                                                                                                      Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
 +                                                                                                              let sha256_of_onion = Sha256::hash(&onion_packet.hop_data).into_inner();
 +                                                                                                              // In this scenario, the phantom would have sent us an
 +                                                                                                              // `update_fail_malformed_htlc`, meaning here we encrypt the error as
 +                                                                                                              // if it came from us (the second-to-last hop) but contains the sha256
 +                                                                                                              // of the onion.
 +                                                                                                              failed_payment!(err_msg, err_code, sha256_of_onion.to_vec(), None);
 +                                                                                                      },
 +                                                                                                      Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code }) => {
 +                                                                                                              failed_payment!(err_msg, err_code, Vec::new(), Some(phantom_shared_secret));
 +                                                                                                      },
 +                                                                                              };
 +                                                                                              match next_hop {
 +                                                                                                      onion_utils::Hop::Receive(hop_data) => {
 +                                                                                                              match self.construct_recv_pending_htlc_info(hop_data, incoming_shared_secret, payment_hash, outgoing_amt_msat, outgoing_cltv_value, Some(phantom_shared_secret)) {
 +                                                                                                                      Ok(info) => phantom_receives.push((prev_short_channel_id, prev_funding_outpoint, vec![(info, prev_htlc_id)])),
 +                                                                                                                      Err(ReceiveError { err_code, err_data, msg }) => failed_payment!(msg, err_code, err_data, Some(phantom_shared_secret))
 +                                                                                                              }
 +                                                                                                      },
 +                                                                                                      _ => panic!(),
                                                                                                }
                                                                                        } else {
                                                                                                fail_forward!(format!("Unknown short channel id {} for forward HTLC", short_chan_id), 0x4000 | 10, Vec::new(), None);
                                                                                        }
 -                                                                              },
 +                                                                              } else {
 +                                                                                      fail_forward!(format!("Unknown short channel id {} for forward HTLC", short_chan_id), 0x4000 | 10, Vec::new(), None);
 +                                                                              }
 +                                                                      },
                                                                        HTLCForwardInfo::FailHTLC { .. } => {
                                                                                // Channel went away before we could fail it. This implies
                                                                                // the channel is now on chain and our counterparty is
                                                        let mut fail_htlc_msgs = Vec::new();
                                                        for forward_info in pending_forwards.drain(..) {
                                                                match forward_info {
 -                                                                      HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
 -                                                                                      routing: PendingHTLCRouting::Forward {
 -                                                                                              onion_packet, ..
 -                                                                                      }, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value },
 -                                                                                      prev_funding_outpoint } => {
 +                                                                      HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
 +                                                                              prev_short_channel_id, prev_htlc_id, prev_funding_outpoint ,
 +                                                                              forward_info: PendingHTLCInfo {
 +                                                                                      incoming_shared_secret, payment_hash, outgoing_amt_msat, outgoing_cltv_value,
 +                                                                                      routing: PendingHTLCRouting::Forward { onion_packet, .. }, incoming_amt_msat: _,
 +                                                                              },
 +                                                                      }) => {
                                                                                log_trace!(self.logger, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", prev_short_channel_id, log_bytes!(payment_hash.0), short_chan_id);
                                                                                let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
                                                                                        short_channel_id: prev_short_channel_id,
                                                                                        // Phantom payments are only PendingHTLCRouting::Receive.
                                                                                        phantom_shared_secret: None,
                                                                                });
 -                                                                              match chan.get_mut().send_htlc(amt_to_forward, payment_hash, outgoing_cltv_value, htlc_source.clone(), onion_packet, &self.logger) {
 +                                                                              match chan.get_mut().send_htlc(outgoing_amt_msat, payment_hash, outgoing_cltv_value, htlc_source.clone(), onion_packet, &self.logger) {
                                                                                        Err(e) => {
                                                                                                if let ChannelError::Ignore(msg) = e {
                                                                                                        log_trace!(self.logger, "Failed to forward HTLC with payment_hash {}: {}", log_bytes!(payment_hash.0), msg);
                                } else {
                                        for forward_info in pending_forwards.drain(..) {
                                                match forward_info {
 -                                                      HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
 -                                                                      routing, incoming_shared_secret, payment_hash, amt_to_forward, .. },
 -                                                                      prev_funding_outpoint } => {
 +                                                      HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
 +                                                              prev_short_channel_id, prev_htlc_id, prev_funding_outpoint,
 +                                                              forward_info: PendingHTLCInfo {
 +                                                                      routing, incoming_shared_secret, payment_hash, outgoing_amt_msat, ..
 +                                                              }
 +                                                      }) => {
                                                                let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret) = match routing {
                                                                        PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } => {
                                                                                let _legacy_hop_data = Some(payment_data.clone());
                                                                                incoming_packet_shared_secret: incoming_shared_secret,
                                                                                phantom_shared_secret,
                                                                        },
 -                                                                      value: amt_to_forward,
 +                                                                      value: outgoing_amt_msat,
                                                                        timer_ticks: 0,
 -                                                                      total_msat: if let Some(data) = &payment_data { data.total_msat } else { amt_to_forward },
 +                                                                      total_msat: if let Some(data) = &payment_data { data.total_msat } else { outgoing_amt_msat },
                                                                        cltv_expiry,
                                                                        onion_payload,
                                                                };
                                                                                                                e.insert((purpose.clone(), vec![claimable_htlc]));
                                                                                                                new_events.push(events::Event::PaymentReceived {
                                                                                                                        payment_hash,
 -                                                                                                                      amount_msat: amt_to_forward,
 +                                                                                                                      amount_msat: outgoing_amt_msat,
                                                                                                                        purpose,
                                                                                                                });
                                                                                                        },
        ///
        /// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
        /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
-       pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u64) -> Result<(), APIError> {
+       pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> {
                self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, false, user_channel_id)
        }
  
        ///
        /// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
        /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
-       pub fn accept_inbound_channel_from_trusted_peer_0conf(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u64) -> Result<(), APIError> {
+       pub fn accept_inbound_channel_from_trusted_peer_0conf(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> {
                self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, true, user_channel_id)
        }
  
-       fn do_accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u64) -> Result<(), APIError> {
+       fn do_accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u128) -> Result<(), APIError> {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
  
                let mut channel_state_lock = self.channel_state.lock().unwrap();
                        return Err(MsgHandleErrInternal::send_err_msg_no_close("No inbound channels accepted".to_owned(), msg.temporary_channel_id.clone()));
                }
  
+               let mut random_bytes = [0u8; 16];
+               random_bytes.copy_from_slice(&self.keys_manager.get_secure_random_bytes()[..16]);
+               let user_channel_id = u128::from_be_bytes(random_bytes);
                let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
                let mut channel = match Channel::new_from_req(&self.fee_estimator, &self.keys_manager,
-                       counterparty_node_id.clone(), &their_features, msg, 0, &self.default_configuration,
+                       counterparty_node_id.clone(), &their_features, msg, user_channel_id, &self.default_configuration,
                        self.best_block.read().unwrap().height(), &self.logger, outbound_scid_alias)
                {
                        Err(e) => {
                                                        PendingHTLCRouting::ReceiveKeysend { .. } => 0,
                                        }) {
                                                hash_map::Entry::Occupied(mut entry) => {
 -                                                      entry.get_mut().push(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_funding_outpoint,
 -                                                                                                      prev_htlc_id, forward_info });
 +                                                      entry.get_mut().push(HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
 +                                                              prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info }));
                                                },
                                                hash_map::Entry::Vacant(entry) => {
 -                                                      entry.insert(vec!(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_funding_outpoint,
 -                                                                                                   prev_htlc_id, forward_info }));
 +                                                      entry.insert(vec!(HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
 +                                                              prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info })));
                                                }
                                        }
                                }
        #[cfg(any(test, fuzzing, feature = "_test_utils"))]
        pub fn get_and_clear_pending_events(&self) -> Vec<events::Event> {
                let events = core::cell::RefCell::new(Vec::new());
 -              let event_handler = |event: &events::Event| events.borrow_mut().push(event.clone());
 +              let event_handler = |event: events::Event| events.borrow_mut().push(event);
                self.process_pending_events(&event_handler);
                events.into_inner()
        }
        pub fn clear_pending_payments(&self) {
                self.pending_outbound_payments.lock().unwrap().clear()
        }
 +
 +      /// Processes any events asynchronously in the order they were generated since the last call
 +      /// using the given event handler.
 +      ///
 +      /// See the trait-level documentation of [`EventsProvider`] for requirements.
 +      pub async fn process_pending_events_async<Future: core::future::Future, H: Fn(Event) -> Future>(
 +              &self, handler: H
 +      ) {
 +              // We'll acquire our total consistency lock until the returned future completes so that
 +              // we can be sure no other persists happen while processing events.
 +              let _read_guard = self.total_consistency_lock.read().unwrap();
 +
 +              let mut result = NotifyOption::SkipPersist;
 +
 +              // TODO: This behavior should be documented. It's unintuitive that we query
 +              // ChannelMonitors when clearing other events.
 +              if self.process_pending_monitor_events() {
 +                      result = NotifyOption::DoPersist;
 +              }
 +
 +              let pending_events = mem::replace(&mut *self.pending_events.lock().unwrap(), vec![]);
 +              if !pending_events.is_empty() {
 +                      result = NotifyOption::DoPersist;
 +              }
 +
 +              for event in pending_events {
 +                      handler(event).await;
 +              }
 +
 +              if result == NotifyOption::DoPersist {
 +                      self.persistence_notifier.notify();
 +              }
 +      }
  }
  
  impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> MessageSendEventsProvider for ChannelManager<M, T, K, F, L>
@@@ -5816,13 -5781,13 +5820,13 @@@ wher
                                result = NotifyOption::DoPersist;
                        }
  
 -                      let mut pending_events = mem::replace(&mut *self.pending_events.lock().unwrap(), vec![]);
 +                      let pending_events = mem::replace(&mut *self.pending_events.lock().unwrap(), vec![]);
                        if !pending_events.is_empty() {
                                result = NotifyOption::DoPersist;
                        }
  
 -                      for event in pending_events.drain(..) {
 -                              handler.handle_event(&event);
 +                      for event in pending_events {
 +                              handler.handle_event(event);
                        }
  
                        result
@@@ -5931,12 -5896,12 +5935,12 @@@ wher
                });
        }
  
 -      fn get_relevant_txids(&self) -> Vec<Txid> {
 +      fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
                let channel_state = self.channel_state.lock().unwrap();
                let mut res = Vec::with_capacity(channel_state.by_id.len());
                for chan in channel_state.by_id.values() {
 -                      if let Some(funding_txo) = chan.get_funding_txo() {
 -                              res.push(funding_txo.txid);
 +                      if let (Some(funding_txo), block_hash) = (chan.get_funding_txo(), chan.get_funding_tx_confirmed_in()) {
 +                              res.push((funding_txo.txid, block_hash));
                        }
                }
                res
@@@ -6091,25 -6056,18 +6095,25 @@@ wher
  
        /// Blocks until ChannelManager needs to be persisted or a timeout is reached. It returns a bool
        /// indicating whether persistence is necessary. Only one listener on
 -      /// `await_persistable_update` or `await_persistable_update_timeout` is guaranteed to be woken
 -      /// up.
 +      /// [`await_persistable_update`], [`await_persistable_update_timeout`], or a future returned by
 +      /// [`get_persistable_update_future`] is guaranteed to be woken up.
        ///
        /// Note that this method is not available with the `no-std` feature.
 +      ///
 +      /// [`await_persistable_update`]: Self::await_persistable_update
 +      /// [`await_persistable_update_timeout`]: Self::await_persistable_update_timeout
 +      /// [`get_persistable_update_future`]: Self::get_persistable_update_future
        #[cfg(any(test, feature = "std"))]
        pub fn await_persistable_update_timeout(&self, max_wait: Duration) -> bool {
                self.persistence_notifier.wait_timeout(max_wait)
        }
  
        /// Blocks until ChannelManager needs to be persisted. Only one listener on
 -      /// `await_persistable_update` or `await_persistable_update_timeout` is guaranteed to be woken
 -      /// up.
 +      /// [`await_persistable_update`], `await_persistable_update_timeout`, or a future returned by
 +      /// [`get_persistable_update_future`] is guaranteed to be woken up.
 +      ///
 +      /// [`await_persistable_update`]: Self::await_persistable_update
 +      /// [`get_persistable_update_future`]: Self::get_persistable_update_future
        pub fn await_persistable_update(&self) {
                self.persistence_notifier.wait()
        }
@@@ -6450,33 -6408,108 +6454,108 @@@ impl_writeable_tlv_based!(ChannelCounte
        (11, outbound_htlc_maximum_msat, option),
  });
  
- impl_writeable_tlv_based!(ChannelDetails, {
-       (1, inbound_scid_alias, option),
-       (2, channel_id, required),
-       (3, channel_type, option),
-       (4, counterparty, required),
-       (5, outbound_scid_alias, option),
-       (6, funding_txo, option),
-       (7, config, option),
-       (8, short_channel_id, option),
-       (10, channel_value_satoshis, required),
-       (12, unspendable_punishment_reserve, option),
-       (14, user_channel_id, required),
-       (16, balance_msat, required),
-       (18, outbound_capacity_msat, required),
-       // Note that by the time we get past the required read above, outbound_capacity_msat will be
-       // filled in, so we can safely unwrap it here.
-       (19, next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap() as u64)),
-       (20, inbound_capacity_msat, required),
-       (22, confirmations_required, option),
-       (24, force_close_spend_delay, option),
-       (26, is_outbound, required),
-       (28, is_channel_ready, required),
-       (30, is_usable, required),
-       (32, is_public, required),
-       (33, inbound_htlc_minimum_msat, option),
-       (35, inbound_htlc_maximum_msat, option),
- });
+ impl Writeable for ChannelDetails {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+               // `user_channel_id` used to be a single u64 value. In order to remain backwards compatible with
+               // versions prior to 0.0.113, the u128 is serialized as two separate u64 values.
+               let user_channel_id_low = self.user_channel_id as u64;
+               let user_channel_id_high_opt = Some((self.user_channel_id >> 64) as u64);
+               write_tlv_fields!(writer, {
+                       (1, self.inbound_scid_alias, option),
+                       (2, self.channel_id, required),
+                       (3, self.channel_type, option),
+                       (4, self.counterparty, required),
+                       (5, self.outbound_scid_alias, option),
+                       (6, self.funding_txo, option),
+                       (7, self.config, option),
+                       (8, self.short_channel_id, option),
+                       (10, self.channel_value_satoshis, required),
+                       (12, self.unspendable_punishment_reserve, option),
+                       (14, user_channel_id_low, required),
+                       (16, self.balance_msat, required),
+                       (18, self.outbound_capacity_msat, required),
+                       // Note that by the time we get past the required read above, outbound_capacity_msat will be
+                       // filled in, so we can safely unwrap it here.
+                       (19, self.next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap() as u64)),
+                       (20, self.inbound_capacity_msat, required),
+                       (22, self.confirmations_required, option),
+                       (24, self.force_close_spend_delay, option),
+                       (26, self.is_outbound, required),
+                       (28, self.is_channel_ready, required),
+                       (30, self.is_usable, required),
+                       (32, self.is_public, required),
+                       (33, self.inbound_htlc_minimum_msat, option),
+                       (35, self.inbound_htlc_maximum_msat, option),
+                       (37, user_channel_id_high_opt, option),
+               });
+               Ok(())
+       }
+ }
+ impl Readable for ChannelDetails {
+       fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
+               init_and_read_tlv_fields!(reader, {
+                       (1, inbound_scid_alias, option),
+                       (2, channel_id, required),
+                       (3, channel_type, option),
+                       (4, counterparty, required),
+                       (5, outbound_scid_alias, option),
+                       (6, funding_txo, option),
+                       (7, config, option),
+                       (8, short_channel_id, option),
+                       (10, channel_value_satoshis, required),
+                       (12, unspendable_punishment_reserve, option),
+                       (14, user_channel_id_low, required),
+                       (16, balance_msat, required),
+                       (18, outbound_capacity_msat, required),
+                       // Note that by the time we get past the required read above, outbound_capacity_msat will be
+                       // filled in, so we can safely unwrap it here.
+                       (19, next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap() as u64)),
+                       (20, inbound_capacity_msat, required),
+                       (22, confirmations_required, option),
+                       (24, force_close_spend_delay, option),
+                       (26, is_outbound, required),
+                       (28, is_channel_ready, required),
+                       (30, is_usable, required),
+                       (32, is_public, required),
+                       (33, inbound_htlc_minimum_msat, option),
+                       (35, inbound_htlc_maximum_msat, option),
+                       (37, user_channel_id_high_opt, option),
+               });
+               // `user_channel_id` used to be a single u64 value. In order to remain backwards compatible with
+               // versions prior to 0.0.113, the u128 is serialized as two separate u64 values.
+               let user_channel_id_low: u64 = user_channel_id_low.0.unwrap();
+               let user_channel_id = user_channel_id_low as u128 +
+                       ((user_channel_id_high_opt.unwrap_or(0 as u64) as u128) << 64);
+               Ok(Self {
+                       inbound_scid_alias,
+                       channel_id: channel_id.0.unwrap(),
+                       channel_type,
+                       counterparty: counterparty.0.unwrap(),
+                       outbound_scid_alias,
+                       funding_txo,
+                       config,
+                       short_channel_id,
+                       channel_value_satoshis: channel_value_satoshis.0.unwrap(),
+                       unspendable_punishment_reserve,
+                       user_channel_id,
+                       balance_msat: balance_msat.0.unwrap(),
+                       outbound_capacity_msat: outbound_capacity_msat.0.unwrap(),
+                       next_outbound_htlc_limit_msat: next_outbound_htlc_limit_msat.0.unwrap(),
+                       inbound_capacity_msat: inbound_capacity_msat.0.unwrap(),
+                       confirmations_required,
+                       force_close_spend_delay,
+                       is_outbound: is_outbound.0.unwrap(),
+                       is_channel_ready: is_channel_ready.0.unwrap(),
+                       is_usable: is_usable.0.unwrap(),
+                       is_public: is_public.0.unwrap(),
+                       inbound_htlc_minimum_msat,
+                       inbound_htlc_maximum_msat,
+               })
+       }
+ }
  
  impl_writeable_tlv_based!(PhantomRouteHints, {
        (2, channels, vec_type),
@@@ -6504,9 -6537,8 +6583,9 @@@ impl_writeable_tlv_based!(PendingHTLCIn
        (0, routing, required),
        (2, incoming_shared_secret, required),
        (4, payment_hash, required),
 -      (6, amt_to_forward, required),
 -      (8, outgoing_cltv_value, required)
 +      (6, outgoing_amt_msat, required),
 +      (8, outgoing_cltv_value, required),
 +      (9, incoming_amt_msat, option),
  });
  
  
@@@ -6705,7 -6737,7 +6784,7 @@@ impl Writeable for HTLCSource 
                                        (1, payment_id_opt, option),
                                        (2, first_hop_htlc_msat, required),
                                        (3, payment_secret, option),
 -                                      (4, path, vec_type),
 +                                      (4, *path, vec_type),
                                        (5, payment_params, option),
                                 });
                        }
@@@ -6728,20 -6760,18 +6807,20 @@@ impl_writeable_tlv_based_enum!(HTLCFail
        },
  ;);
  
 +impl_writeable_tlv_based!(PendingAddHTLCInfo, {
 +      (0, forward_info, required),
 +      (2, prev_short_channel_id, required),
 +      (4, prev_htlc_id, required),
 +      (6, prev_funding_outpoint, required),
 +});
 +
  impl_writeable_tlv_based_enum!(HTLCForwardInfo,
 -      (0, AddHTLC) => {
 -              (0, forward_info, required),
 -              (2, prev_short_channel_id, required),
 -              (4, prev_htlc_id, required),
 -              (6, prev_funding_outpoint, required),
 -      },
        (1, FailHTLC) => {
                (0, htlc_id, required),
                (2, err_packet, required),
 -      },
 -;);
 +      };
 +      (0, AddHTLC)
 +);
  
  impl_writeable_tlv_based!(PendingInboundPayment, {
        (0, payment_secret, required),
@@@ -6953,10 -6983,10 +7032,10 @@@ impl<M: Deref, T: Deref, K: Deref, F: D
  /// which you've already broadcasted the transaction.
  ///
  /// [`ChainMonitor`]: crate::chain::chainmonitor::ChainMonitor
 -pub struct ChannelManagerReadArgs<'a, Signer: 'a + Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
 -      where M::Target: chain::Watch<Signer>,
 +pub struct ChannelManagerReadArgs<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
 +      where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
          T::Target: BroadcasterInterface,
 -        K::Target: KeysInterface<Signer = Signer>,
 +        K::Target: KeysInterface,
          F::Target: FeeEstimator,
          L::Target: Logger,
  {
        /// this struct.
        ///
        /// (C-not exported) because we have no HashMap bindings
 -      pub channel_monitors: HashMap<OutPoint, &'a mut ChannelMonitor<Signer>>,
 +      pub channel_monitors: HashMap<OutPoint, &'a mut ChannelMonitor<<K::Target as KeysInterface>::Signer>>,
  }
  
 -impl<'a, Signer: 'a + Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
 -              ChannelManagerReadArgs<'a, Signer, M, T, K, F, L>
 -      where M::Target: chain::Watch<Signer>,
 +impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
 +              ChannelManagerReadArgs<'a, M, T, K, F, L>
 +      where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
                T::Target: BroadcasterInterface,
 -              K::Target: KeysInterface<Signer = Signer>,
 +              K::Target: KeysInterface,
                F::Target: FeeEstimator,
                L::Target: Logger,
        {
        /// HashMap for you. This is primarily useful for C bindings where it is not practical to
        /// populate a HashMap directly from C.
        pub fn new(keys_manager: K, fee_estimator: F, chain_monitor: M, tx_broadcaster: T, logger: L, default_config: UserConfig,
 -                      mut channel_monitors: Vec<&'a mut ChannelMonitor<Signer>>) -> Self {
 +                      mut channel_monitors: Vec<&'a mut ChannelMonitor<<K::Target as KeysInterface>::Signer>>) -> Self {
                Self {
                        keys_manager, fee_estimator, chain_monitor, tx_broadcaster, logger, default_config,
                        channel_monitors: channel_monitors.drain(..).map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect()
  // Implement ReadableArgs for an Arc'd ChannelManager to make it a bit easier to work with the
  // SipmleArcChannelManager type:
  impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
 -      ReadableArgs<ChannelManagerReadArgs<'a, <K::Target as KeysInterface>::Signer, M, T, K, F, L>> for (BlockHash, Arc<ChannelManager<M, T, K, F, L>>)
 +      ReadableArgs<ChannelManagerReadArgs<'a, M, T, K, F, L>> for (BlockHash, Arc<ChannelManager<M, T, K, F, L>>)
        where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
          T::Target: BroadcasterInterface,
          K::Target: KeysInterface,
          F::Target: FeeEstimator,
          L::Target: Logger,
  {
 -      fn read<R: io::Read>(reader: &mut R, args: ChannelManagerReadArgs<'a, <K::Target as KeysInterface>::Signer, M, T, K, F, L>) -> Result<Self, DecodeError> {
 +      fn read<R: io::Read>(reader: &mut R, args: ChannelManagerReadArgs<'a, M, T, K, F, L>) -> Result<Self, DecodeError> {
                let (blockhash, chan_manager) = <(BlockHash, ChannelManager<M, T, K, F, L>)>::read(reader, args)?;
                Ok((blockhash, Arc::new(chan_manager)))
        }
  }
  
  impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
 -      ReadableArgs<ChannelManagerReadArgs<'a, <K::Target as KeysInterface>::Signer, M, T, K, F, L>> for (BlockHash, ChannelManager<M, T, K, F, L>)
 +      ReadableArgs<ChannelManagerReadArgs<'a, M, T, K, F, L>> for (BlockHash, ChannelManager<M, T, K, F, L>)
        where M::Target: chain::Watch<<K::Target as KeysInterface>::Signer>,
          T::Target: BroadcasterInterface,
          K::Target: KeysInterface,
          F::Target: FeeEstimator,
          L::Target: Logger,
  {
 -      fn read<R: io::Read>(reader: &mut R, mut args: ChannelManagerReadArgs<'a, <K::Target as KeysInterface>::Signer, M, T, K, F, L>) -> Result<Self, DecodeError> {
 +      fn read<R: io::Read>(reader: &mut R, mut args: ChannelManagerReadArgs<'a, M, T, K, F, L>) -> Result<Self, DecodeError> {
                let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
  
                let genesis_hash: BlockHash = Readable::read(reader)?;
index 9818bfc4c8da0eb8fc746a8133d08df84aaaa5d8,81219ec349c57435918b0ee8bedebc15d34bf164..a06c7f1e3c0b75ca7bba3562407afb22f5cd158a
@@@ -24,7 -24,7 +24,7 @@@ use crate::ln::msgs
  use crate::ln::msgs::DecodeError;
  use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
  use crate::routing::gossip::NetworkUpdate;
 -use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper, OptionDeserWrapper};
 +use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReadable, Readable, WithoutLength, OptionDeserWrapper};
  use crate::routing::router::{RouteHop, RouteParameters};
  
  use bitcoin::{PackedLockTime, Transaction};
@@@ -318,11 -318,11 +318,11 @@@ pub enum Event 
                channel_value_satoshis: u64,
                /// The script which should be used in the transaction output.
                output_script: Script,
-               /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`], or 0 for
-               /// an inbound channel.
+               /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`], or a
+               /// random value for an inbound channel.
                ///
                /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
-               user_channel_id: u64,
+               user_channel_id: u128,
        },
        /// Indicates we've received (an offer of) money! Just gotta dig out that payment preimage and
        /// feed it to [`ChannelManager::claim_funds`] to get it....
                /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
                /// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if
                /// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise
-               /// `user_channel_id` will be 0 for an inbound channel.
+               /// `user_channel_id` will be randomized for an inbound channel.
                ///
                /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
                /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
                /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
-               user_channel_id: u64,
+               user_channel_id: u128,
                /// The node_id of the channel counterparty.
                counterparty_node_id: PublicKey,
                /// The features that this channel will operate with.
                /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
                /// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if
                /// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise
-               /// `user_channel_id` will be 0 for an inbound channel.
+               /// `user_channel_id` will be randomized for an inbound channel.
                /// This will always be zero for objects serialized with LDK versions prior to 0.0.102.
                ///
                /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
                /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
                /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
-               user_channel_id: u64,
+               user_channel_id: u128,
                /// The reason the channel was closed.
                reason: ClosureReason
        },
@@@ -785,7 -785,7 +785,7 @@@ impl Writeable for Event 
                                        (1, network_update, option),
                                        (2, payment_failed_permanently, required),
                                        (3, all_paths_failed, required),
 -                                      (5, path, vec_type),
 +                                      (5, *path, vec_type),
                                        (7, short_channel_id, option),
                                        (9, retry, option),
                                        (11, payment_id, option),
                        &Event::SpendableOutputs { ref outputs } => {
                                5u8.write(writer)?;
                                write_tlv_fields!(writer, {
 -                                      (0, VecWriteWrapper(outputs), required),
 +                                      (0, WithoutLength(outputs), required),
                                });
                        },
                        &Event::PaymentForwarded { fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id } => {
                        },
                        &Event::ChannelClosed { ref channel_id, ref user_channel_id, ref reason } => {
                                9u8.write(writer)?;
+                               // `user_channel_id` used to be a single u64 value. In order to remain backwards
+                               // compatible with versions prior to 0.0.113, the u128 is serialized as two
+                               // separate u64 values.
+                               let user_channel_id_low = *user_channel_id as u64;
+                               let user_channel_id_high = (*user_channel_id >> 64) as u64;
                                write_tlv_fields!(writer, {
                                        (0, channel_id, required),
-                                       (1, user_channel_id, required),
-                                       (2, reason, required)
+                                       (1, user_channel_id_low, required),
+                                       (2, reason, required),
+                                       (3, user_channel_id_high, required),
                                });
                        },
                        &Event::DiscardFunding { ref channel_id, ref transaction } => {
                                write_tlv_fields!(writer, {
                                        (0, payment_id, required),
                                        (2, payment_hash, option),
 -                                      (4, path, vec_type)
 +                                      (4, *path, vec_type)
                                })
                        },
                        &Event::PaymentFailed { ref payment_id, ref payment_hash } => {
                                write_tlv_fields!(writer, {
                                        (0, payment_id, required),
                                        (2, payment_hash, required),
 -                                      (4, path, vec_type)
 +                                      (4, *path, vec_type)
                                })
                        },
                        &Event::ProbeFailed { ref payment_id, ref payment_hash, ref path, ref short_channel_id } => {
                                write_tlv_fields!(writer, {
                                        (0, payment_id, required),
                                        (2, payment_hash, required),
 -                                      (4, path, vec_type),
 +                                      (4, *path, vec_type),
                                        (6, short_channel_id, option),
                                })
                        },
@@@ -1007,7 -1013,7 +1013,7 @@@ impl MaybeReadable for Event 
                        4u8 => Ok(None),
                        5u8 => {
                                let f = || {
 -                                      let mut outputs = VecReadWrapper(Vec::new());
 +                                      let mut outputs = WithoutLength(Vec::new());
                                        read_tlv_fields!(reader, {
                                                (0, outputs, required),
                                        });
                                let f = || {
                                        let mut channel_id = [0; 32];
                                        let mut reason = None;
-                                       let mut user_channel_id_opt = None;
+                                       let mut user_channel_id_low_opt: Option<u64> = None;
+                                       let mut user_channel_id_high_opt: Option<u64> = None;
                                        read_tlv_fields!(reader, {
                                                (0, channel_id, required),
-                                               (1, user_channel_id_opt, option),
+                                               (1, user_channel_id_low_opt, option),
                                                (2, reason, ignorable),
+                                               (3, user_channel_id_high_opt, option),
                                        });
                                        if reason.is_none() { return Ok(None); }
-                                       let user_channel_id = if let Some(id) = user_channel_id_opt { id } else { 0 };
+                                       // `user_channel_id` used to be a single u64 value. In order to remain
+                                       // backwards compatible with versions prior to 0.0.113, the u128 is serialized
+                                       // as two separate u64 values.
+                                       let user_channel_id = (user_channel_id_low_opt.unwrap_or(0) as u128) +
+                                               ((user_channel_id_high_opt.unwrap_or(0) as u128) << 64);
                                        Ok(Some(Event::ChannelClosed { channel_id, user_channel_id, reason: reason.unwrap() }))
                                };
                                f()
                        29u8 => {
                                let f = || {
                                        let mut channel_id = [0; 32];
-                                       let mut user_channel_id: u64 = 0;
+                                       let mut user_channel_id: u128 = 0;
                                        let mut counterparty_node_id = OptionDeserWrapper(None);
                                        let mut channel_type = OptionDeserWrapper(None);
                                        read_tlv_fields!(reader, {
@@@ -1400,10 -1414,6 +1414,10 @@@ pub trait OnionMessageProvider 
  ///
  /// Events are processed by passing an [`EventHandler`] to [`process_pending_events`].
  ///
 +/// Implementations of this trait may also feature an async version of event handling, as shown with
 +/// [`ChannelManager::process_pending_events_async`] and
 +/// [`ChainMonitor::process_pending_events_async`].
 +///
  /// # Requirements
  ///
  /// When using this trait, [`process_pending_events`] will call [`handle_event`] for each pending
  /// [`handle_event`]: EventHandler::handle_event
  /// [`ChannelManager::process_pending_events`]: crate::ln::channelmanager::ChannelManager#method.process_pending_events
  /// [`ChainMonitor::process_pending_events`]: crate::chain::chainmonitor::ChainMonitor#method.process_pending_events
 +/// [`ChannelManager::process_pending_events_async`]: crate::ln::channelmanager::ChannelManager::process_pending_events_async
 +/// [`ChainMonitor::process_pending_events_async`]: crate::chain::chainmonitor::ChainMonitor::process_pending_events_async
  pub trait EventsProvider {
        /// Processes any events generated since the last call using the given event handler.
        ///
  }
  
  /// A trait implemented for objects handling events from [`EventsProvider`].
 +///
 +/// An async variation also exists for implementations of [`EventsProvider`] that support async
 +/// event handling. The async event handler should satisfy the generic bounds: `F:
 +/// core::future::Future, H: Fn(Event) -> F`.
  pub trait EventHandler {
        /// Handles the given [`Event`].
        ///
        /// See [`EventsProvider`] for details that must be considered when implementing this method.
 -      fn handle_event(&self, event: &Event);
 +      fn handle_event(&self, event: Event);
  }
  
 -impl<F> EventHandler for F where F: Fn(&Event) {
 -      fn handle_event(&self, event: &Event) {
 +impl<F> EventHandler for F where F: Fn(Event) {
 +      fn handle_event(&self, event: Event) {
                self(event)
        }
  }
  
  impl<T: EventHandler> EventHandler for Arc<T> {
 -      fn handle_event(&self, event: &Event) {
 +      fn handle_event(&self, event: Event) {
                self.deref().handle_event(event)
        }
  }
index 7c4ba7fd50f99888745a6944971c10f3f00f77a9,ee12c43bda01618e8e6f623233a482ad3249ba41..1f79b063e55d1b3eb4cc58b0ab67b46ec5c919fe
@@@ -22,7 -22,6 +22,7 @@@ use core::ops::Deref
  use bitcoin::secp256k1::{PublicKey, SecretKey};
  use bitcoin::secp256k1::constants::{PUBLIC_KEY_SIZE, SECRET_KEY_SIZE, COMPACT_SIGNATURE_SIZE};
  use bitcoin::secp256k1::ecdsa::Signature;
 +use bitcoin::blockdata::constants::ChainHash;
  use bitcoin::blockdata::script::Script;
  use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
  use bitcoin::consensus;
@@@ -284,6 -283,39 +284,6 @@@ impl<T: Readable> From<T> for OptionDes
        fn from(t: T) -> OptionDeserWrapper<T> { OptionDeserWrapper(Some(t)) }
  }
  
 -/// Wrapper to write each element of a Vec with no length prefix
 -pub(crate) struct VecWriteWrapper<'a, T: Writeable>(pub &'a Vec<T>);
 -impl<'a, T: Writeable> Writeable for VecWriteWrapper<'a, T> {
 -      #[inline]
 -      fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
 -              for ref v in self.0.iter() {
 -                      v.write(writer)?;
 -              }
 -              Ok(())
 -      }
 -}
 -
 -/// Wrapper to read elements from a given stream until it reaches the end of the stream.
 -pub(crate) struct VecReadWrapper<T>(pub Vec<T>);
 -impl<T: MaybeReadable> Readable for VecReadWrapper<T> {
 -      #[inline]
 -      fn read<R: Read>(mut reader: &mut R) -> Result<Self, DecodeError> {
 -              let mut values = Vec::new();
 -              loop {
 -                      let mut track_read = ReadTrackingReader::new(&mut reader);
 -                      match MaybeReadable::read(&mut track_read) {
 -                              Ok(Some(v)) => { values.push(v); },
 -                              Ok(None) => { },
 -                              // If we failed to read any bytes at all, we reached the end of our TLV
 -                              // stream and have simply exhausted all entries.
 -                              Err(ref e) if e == &DecodeError::ShortRead && !track_read.have_read => break,
 -                              Err(e) => return Err(e),
 -                      }
 -              }
 -              Ok(Self(values))
 -      }
 -}
 -
  pub(crate) struct U48(pub u64);
  impl Writeable for U48 {
        #[inline]
@@@ -419,12 -451,10 +419,13 @@@ macro_rules! impl_writeable_primitive 
                                }
                        }
                }
 +              impl From<$val_type> for HighZeroBytesDroppedBigSize<$val_type> {
 +                      fn from(val: $val_type) -> Self { Self(val) }
 +              }
        }
  }
  
+ impl_writeable_primitive!(u128, 16);
  impl_writeable_primitive!(u64, 8);
  impl_writeable_primitive!(u32, 4);
  impl_writeable_primitive!(u16, 2);
@@@ -485,7 -515,7 +486,7 @@@ macro_rules! impl_array 
        );
  }
  
 -impl_array!(3); // for rgb
 +impl_array!(3); // for rgb, ISO 4712 code
  impl_array!(4); // for IPv4
  impl_array!(12); // for OnionV2
  impl_array!(16); // for IPv6
@@@ -517,59 -547,6 +518,59 @@@ impl Readable for [u16; 8] 
        }
  }
  
 +/// For variable-length values within TLV record where the length is encoded as part of the record.
 +/// Used to prevent encoding the length twice.
 +pub(crate) struct WithoutLength<T>(pub T);
 +
 +impl Writeable for WithoutLength<&String> {
 +      #[inline]
 +      fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
 +              w.write_all(self.0.as_bytes())
 +      }
 +}
 +impl Readable for WithoutLength<String> {
 +      #[inline]
 +      fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
 +              let v: WithoutLength<Vec<u8>> = Readable::read(r)?;
 +              Ok(Self(String::from_utf8(v.0).map_err(|_| DecodeError::InvalidValue)?))
 +      }
 +}
 +impl<'a> From<&'a String> for WithoutLength<&'a String> {
 +      fn from(s: &'a String) -> Self { Self(s) }
 +}
 +
 +impl<'a, T: Writeable> Writeable for WithoutLength<&'a Vec<T>> {
 +      #[inline]
 +      fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
 +              for ref v in self.0.iter() {
 +                      v.write(writer)?;
 +              }
 +              Ok(())
 +      }
 +}
 +
 +impl<T: MaybeReadable> Readable for WithoutLength<Vec<T>> {
 +      #[inline]
 +      fn read<R: Read>(mut reader: &mut R) -> Result<Self, DecodeError> {
 +              let mut values = Vec::new();
 +              loop {
 +                      let mut track_read = ReadTrackingReader::new(&mut reader);
 +                      match MaybeReadable::read(&mut track_read) {
 +                              Ok(Some(v)) => { values.push(v); },
 +                              Ok(None) => { },
 +                              // If we failed to read any bytes at all, we reached the end of our TLV
 +                              // stream and have simply exhausted all entries.
 +                              Err(ref e) if e == &DecodeError::ShortRead && !track_read.have_read => break,
 +                              Err(e) => return Err(e),
 +                      }
 +              }
 +              Ok(Self(values))
 +      }
 +}
 +impl<'a, T> From<&'a Vec<T>> for WithoutLength<&'a Vec<T>> {
 +      fn from(v: &'a Vec<T>) -> Self { Self(v) }
 +}
 +
  // HashMap
  impl<K, V> Writeable for HashMap<K, V>
        where K: Writeable + Eq + Hash,
@@@ -884,19 -861,6 +885,19 @@@ impl Readable for BlockHash 
        }
  }
  
 +impl Writeable for ChainHash {
 +      fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
 +              w.write_all(self.as_bytes())
 +      }
 +}
 +
 +impl Readable for ChainHash {
 +      fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
 +              let buf: [u8; 32] = Readable::read(r)?;
 +              Ok(ChainHash::from(&buf[..]))
 +      }
 +}
 +
  impl Writeable for OutPoint {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                self.txid.write(w)?;
index 3ec0848680ffe62a2532e03d47d1fc5b62d7f4b8,6c9b618dad4a281f0609c1301cb290025881aaf1..9a11dac7a4922bfb5e6ddf2911d9974f2a1e9470
@@@ -17,7 -17,7 +17,7 @@@ macro_rules! encode_tlv 
                $field.write($stream)?;
        };
        ($stream: expr, $type: expr, $field: expr, vec_type) => {
 -              encode_tlv!($stream, $type, $crate::util::ser::VecWriteWrapper(&$field), required);
 +              encode_tlv!($stream, $type, $crate::util::ser::WithoutLength(&$field), required);
        };
        ($stream: expr, $optional_type: expr, $optional_field: expr, option) => {
                if let Some(ref field) = $optional_field {
                        field.write($stream)?;
                }
        };
 +      ($stream: expr, $type: expr, $field: expr, (option, encoding: ($fieldty: ty, $encoding: ident))) => {
 +              encode_tlv!($stream, $type, $field.map(|f| $encoding(f)), option);
 +      };
 +      ($stream: expr, $type: expr, $field: expr, (option, encoding: $fieldty: ty)) => {
 +              encode_tlv!($stream, $type, $field, option);
 +      };
  }
  
  macro_rules! encode_tlv_stream {
@@@ -72,7 -66,7 +72,7 @@@ macro_rules! get_varint_length_prefixed
                $len.0 += field_len;
        };
        ($len: expr, $type: expr, $field: expr, vec_type) => {
 -              get_varint_length_prefixed_tlv_length!($len, $type, $crate::util::ser::VecWriteWrapper(&$field), required);
 +              get_varint_length_prefixed_tlv_length!($len, $type, $crate::util::ser::WithoutLength(&$field), required);
        };
        ($len: expr, $optional_type: expr, $optional_field: expr, option) => {
                if let Some(ref field) = $optional_field {
@@@ -127,9 -121,6 +127,9 @@@ macro_rules! check_tlv_order 
        ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
                // no-op
        }};
 +      ($last_seen_type: expr, $typ: expr, $type: expr, $field: ident, (option, encoding: $encoding: tt)) => {{
 +              // no-op
 +      }};
  }
  
  macro_rules! check_missing_tlv {
        ($last_seen_type: expr, $type: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
                // no-op
        }};
 +      ($last_seen_type: expr, $type: expr, $field: ident, (option, encoding: $encoding: tt)) => {{
 +              // no-op
 +      }};
  }
  
  macro_rules! decode_tlv {
                $field = $crate::util::ser::Readable::read(&mut $reader)?;
        }};
        ($reader: expr, $field: ident, vec_type) => {{
 -              let f: $crate::util::ser::VecReadWrapper<_> = $crate::util::ser::Readable::read(&mut $reader)?;
 +              let f: $crate::util::ser::WithoutLength<Vec<_>> = $crate::util::ser::Readable::read(&mut $reader)?;
                $field = Some(f.0);
        }};
        ($reader: expr, $field: ident, option) => {{
        ($reader: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
                $field = Some($trait::read(&mut $reader $(, $read_arg)*)?);
        }};
 +      ($reader: expr, $field: ident, (option, encoding: ($fieldty: ty, $encoding: ident))) => {{
 +              $field = {
 +                      let field: $encoding<$fieldty> = ser::Readable::read(&mut $reader)?;
 +                      Some(field.0)
 +              };
 +      }};
 +      ($reader: expr, $field: ident, (option, encoding: $fieldty: ty)) => {{
 +              decode_tlv!($reader, $field, option);
 +      }};
  }
  
  // `$decode_custom_tlv` is a closure that may be optionally provided to handle custom message types.
@@@ -412,6 -391,18 +412,18 @@@ macro_rules! init_tlv_field_var 
        };
  }
  
+ macro_rules! init_and_read_tlv_fields {
+       ($reader: ident, {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}) => {
+               $(
+                       init_tlv_field_var!($field, $fieldty);
+               )*
+               read_tlv_fields!($reader, {
+                       $(($type, $field, $fieldty)),*
+               });
+       }
+ }
  /// Implements Readable/Writeable for a struct storing it as a set of TLVs
  /// If $fieldty is `required`, then $field is a required field that is not an Option nor a Vec.
  /// If $fieldty is `option`, then $field is optional field.
@@@ -446,10 -437,7 +458,7 @@@ macro_rules! impl_writeable_tlv_based 
  
                impl $crate::util::ser::Readable for $st {
                        fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
-                               $(
-                                       init_tlv_field_var!($field, $fieldty);
-                               )*
-                               read_tlv_fields!(reader, {
+                               init_and_read_tlv_fields!(reader, {
                                        $(($type, $field, $fieldty)),*
                                });
                                Ok(Self {
        }
  }
  
 +/// Defines a struct for a TLV stream and a similar struct using references for non-primitive types,
 +/// implementing [`Readable`] for the former and [`Writeable`] for the latter. Useful as an
 +/// intermediary format when reading or writing a type encoded as a TLV stream. Note that each field
 +/// representing a TLV record has its type wrapped with an [`Option`]. A tuple consisting of a type
 +/// and a serialization wrapper may be given in place of a type when custom serialization is
 +/// required.
 +///
 +/// [`Readable`]: crate::util::ser::Readable
 +/// [`Writeable`]: crate::util::ser::Writeable
 +macro_rules! tlv_stream {
 +      ($name:ident, $nameref:ident, {
 +              $(($type:expr, $field:ident : $fieldty:tt)),* $(,)*
 +      }) => {
 +              #[derive(Debug)]
 +              struct $name {
 +                      $(
 +                              $field: Option<tlv_record_type!($fieldty)>,
 +                      )*
 +              }
 +
 +              pub(crate) struct $nameref<'a> {
 +                      $(
 +                              pub(crate) $field: Option<tlv_record_ref_type!($fieldty)>,
 +                      )*
 +              }
 +
 +              impl<'a> $crate::util::ser::Writeable for $nameref<'a> {
 +                      fn write<W: $crate::util::ser::Writer>(&self, writer: &mut W) -> Result<(), $crate::io::Error> {
 +                              encode_tlv_stream!(writer, {
 +                                      $(($type, self.$field, (option, encoding: $fieldty))),*
 +                              });
 +                              Ok(())
 +                      }
 +              }
 +
 +              impl $crate::util::ser::Readable for $name {
 +                      fn read<R: $crate::io::Read>(reader: &mut R) -> Result<Self, $crate::ln::msgs::DecodeError> {
 +                              $(
 +                                      init_tlv_field_var!($field, option);
 +                              )*
 +                              decode_tlv_stream!(reader, {
 +                                      $(($type, $field, (option, encoding: $fieldty))),*
 +                              });
 +
 +                              Ok(Self {
 +                                      $(
 +                                              $field: $field
 +                                      ),*
 +                              })
 +                      }
 +              }
 +      }
 +}
 +
 +macro_rules! tlv_record_type {
 +      (($type:ty, $wrapper:ident)) => { $type };
 +      ($type:ty) => { $type };
 +}
 +
 +macro_rules! tlv_record_ref_type {
 +      (char) => { char };
 +      (u8) => { u8 };
 +      ((u16, $wrapper: ident)) => { u16 };
 +      ((u32, $wrapper: ident)) => { u32 };
 +      ((u64, $wrapper: ident)) => { u64 };
 +      (($type:ty, $wrapper:ident)) => { &'a $type };
 +      ($type:ty) => { &'a $type };
 +}
 +
  macro_rules! _impl_writeable_tlv_based_enum_common {
        ($st: ident, $(($variant_id: expr, $variant_name: ident) =>
                {$(($type: expr, $field: ident, $fieldty: tt)),* $(,)*}
                                                let id: u8 = $variant_id;
                                                id.write(writer)?;
                                                write_tlv_fields!(writer, {
 -                                                      $(($type, $field, $fieldty)),*
 +                                                      $(($type, *$field, $fieldty)),*
                                                });
                                        }),*
                                        $($st::$tuple_variant_name (ref field) => {
@@@ -583,10 -502,7 +592,7 @@@ macro_rules! impl_writeable_tlv_based_e
                                                // Because read_tlv_fields creates a labeled loop, we cannot call it twice
                                                // in the same function body. Instead, we define a closure and call it.
                                                let f = || {
-                                                       $(
-                                                               init_tlv_field_var!($field, $fieldty);
-                                                       )*
-                                                       read_tlv_fields!(reader, {
+                                                       init_and_read_tlv_fields!(reader, {
                                                                $(($type, $field, $fieldty)),*
                                                        });
                                                        Ok(Some($st::$variant_name {
@@@ -636,10 -552,7 +642,7 @@@ macro_rules! impl_writeable_tlv_based_e
                                                // Because read_tlv_fields creates a labeled loop, we cannot call it twice
                                                // in the same function body. Instead, we define a closure and call it.
                                                let f = || {
-                                                       $(
-                                                               init_tlv_field_var!($field, $fieldty);
-                                                       )*
-                                                       read_tlv_fields!(reader, {
+                                                       init_and_read_tlv_fields!(reader, {
                                                                $(($type, $field, $fieldty)),*
                                                        });
                                                        Ok($st::$variant_name {