From: Matt Corallo <649246+TheBlueMatt@users.noreply.github.com> Date: Mon, 31 May 2021 18:05:45 +0000 (+0000) Subject: Merge pull request #931 from jkczyz/2021-05-http-client-reconnect X-Git-Tag: v0.0.98~12 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=58a4f6c4ad3c262f7ed7009f6c99d36936e958b4;hp=4a12d7656ef8355bfd41f57f2350de4b14bda935;p=rust-lightning Merge pull request #931 from jkczyz/2021-05-http-client-reconnect Cache socket address in HttpClient for reconnect --- diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad9d8752..61e96169 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -143,13 +143,13 @@ jobs: id: cache-graph uses: actions/cache@v2 with: - path: lightning/net_graph-2021-02-12.bin - key: ldk-net_graph-05f0c5a0d772-2020-02-12.bin + path: lightning/net_graph-2021-05-27.bin + key: ldk-net_graph-45d86ead641d-2021-05-27.bin - name: Fetch routing graph snapshot if: steps.cache-graph.outputs.cache-hit != 'true' run: | - wget -O lightning/net_graph-2021-02-12.bin https://bitcoin.ninja/ldk-net_graph-05f0c5a0d772-2020-02-12.bin - if [ "$(sha256sum lightning/net_graph-2021-02-12.bin | awk '{ print $1 }')" != "7116fca78551fedc714a604cec0ad1ca66caa77bb4d0051290258e7a10e0c6e7" ]; then + wget -O lightning/net_graph-2021-05-27.bin https://bitcoin.ninja/ldk-net_graph-45d86ead641d-2021-05-27.bin + if [ "$(sha256sum lightning/net_graph-2021-05-27.bin | awk '{ print $1 }')" != "3d6261187cfa583255d978efb908b51c2f4dc4ad9a7160cd2c5263c9a4830121" ]; then echo "Bad hash" exit 1 fi diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 52b37a10..adfd2a83 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -905,7 +905,6 @@ mod tests { // 0c007d - connect a block with one transaction of len 125 // 02000000013a000000000000000000000000000000000000000000000000000000000000000000000000000000800258020000000000002200204b0000000000000000000000000000000000000000000000000000000000000014c0000000000000160014280000000000000000000000000000000000000005000020 - the commitment transaction for channel 3f00000000000000000000000000000000000000000000000000000000000000 // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator) - // 00fd - A feerate request (returning min feerate, which our open_channel also uses) (gonna be ingested by FuzzEstimator) // 0c005e - connect a block with one transaction of len 94 // 0200000001730000000000000000000000000000000000000000000000000000000000000000000000000000000001a701000000000000220020b20000000000000000000000000000000000000000000000000000000000000000000000 - the HTLC timeout transaction // 0c0000 - connect a block with no transactions @@ -918,7 +917,7 @@ mod tests { // - 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("01000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000020300320003000000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000030012000a0300000000000000000000000000000003001a00100002200000022000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c3500000000000000000000000000000014affffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005020900000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d0000000000000000000000000000000000000000000000000000000000000002080000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000010301320003000000000000000000000000000000000000000000000000000000000000000703000000000000000000000000000000030142000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000030112000a0100000000000000000000000000000003011a0010000220000002200001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e05000000000000014a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500026600000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c0001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000b03011200430100000000000000000000000000000003015300243a000000000000000000000000000000000000000000000000000000000000000267000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000020b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000002640000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a00823a000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000000265000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000020a000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c3010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000020d00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833a00000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020c000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000927c0000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4b000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007501000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006705000000000000000000000000000000000000000000000000000000000000060300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000020f0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013a000000000000000000000000000000000000000000000000000000000000000000000000000000800258020000000000002200204b0000000000000000000000000000000000000000000000000000000000000014c000000000000016001428000000000000000000000000000000000000000500002000fd00fd0c005e0200000001730000000000000000000000000000000000000000000000000000000000000000000000000000000001a701000000000000220020b200000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc)); + super::do_test(&::hex::decode("01000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000020300320003000000000000000000000000000000000000000000000000000000000000000203000000000000000000000000000000030012000a0300000000000000000000000000000003001a00100002200000022000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c3500000000000000000000000000000014affffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005020900000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d0000000000000000000000000000000000000000000000000000000000000002080000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000010301320003000000000000000000000000000000000000000000000000000000000000000703000000000000000000000000000000030142000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000030112000a0100000000000000000000000000000003011a0010000220000002200001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e05000000000000014a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500026600000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c0001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000b03011200430100000000000000000000000000000003015300243a000000000000000000000000000000000000000000000000000000000000000267000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000020b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000660000000000000000000000000000000000000000000000000000000000000002640000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a00823a000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a0000000000000000000000000000000000000000000000000000000000000067000000000000000000000000000000000000000000000000000000000000000265000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e8000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000020a000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c3010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000020d00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000002700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833a00000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853a000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020c000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032010000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff00000000000000000000000000000000000000000000000000000000000000000003f0000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000927c0000000a00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4b000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007501000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006705000000000000000000000000000000000000000000000000000000000000060300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000020f0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013a000000000000000000000000000000000000000000000000000000000000000000000000000000800258020000000000002200204b0000000000000000000000000000000000000000000000000000000000000014c000000000000016001428000000000000000000000000000000000000000500002000fd0c005e0200000001730000000000000000000000000000000000000000000000000000000000000000000000000000000001a701000000000000220020b200000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc)); 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 diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 69aa2ea0..e9ca316a 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -238,7 +238,7 @@ mod tests { fn create_nodes(num_nodes: usize, persist_dir: String) -> Vec { let mut nodes = Vec::new(); for i in 0..num_nodes { - let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}); + let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))}); let fee_estimator = Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 }); let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet)); let logger = Arc::new(test_utils::TestLogger::with_id(format!("node {}", i))); diff --git a/lightning/src/chain/chainmonitor.rs b/lightning/src/chain/chainmonitor.rs index 8e6ddc76..a3365f2b 100644 --- a/lightning/src/chain/chainmonitor.rs +++ b/lightning/src/chain/chainmonitor.rs @@ -37,6 +37,7 @@ use util::logger::Logger; use util::events; use util::events::EventHandler; +use prelude::*; use std::collections::{HashMap, hash_map}; use std::sync::RwLock; use core::ops::Deref; @@ -143,7 +144,7 @@ where C::Target: chain::Filter, #[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))] pub fn get_and_clear_pending_events(&self) -> Vec { use util::events::EventsProvider; - let events = std::cell::RefCell::new(Vec::new()); + let events = core::cell::RefCell::new(Vec::new()); let event_handler = |event| events.borrow_mut().push(event); self.process_pending_events(&event_handler); events.into_inner() diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index de826814..26187ce3 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -51,6 +51,7 @@ use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48}; use util::byte_utils; use util::events::Event; +use prelude::*; use std::collections::{HashMap, HashSet}; use core::{cmp, mem}; use std::io::Error; @@ -1386,7 +1387,7 @@ impl ChannelMonitorImpl { macro_rules! claim_htlcs { ($commitment_number: expr, $txid: expr) => { let htlc_claim_reqs = self.get_counterparty_htlc_output_claim_reqs($commitment_number, $txid, None); - self.onchain_tx_handler.update_claims_view(&Vec::new(), htlc_claim_reqs, None, broadcaster, fee_estimator, logger); + self.onchain_tx_handler.update_claims_view(&Vec::new(), htlc_claim_reqs, self.best_block.height(), broadcaster, fee_estimator, logger); } } if let Some(txid) = self.current_counterparty_commitment_txid { @@ -1409,10 +1410,10 @@ impl ChannelMonitorImpl { // holder commitment transactions. if self.broadcasted_holder_revokable_script.is_some() { let (claim_reqs, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, 0); - self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, None, broadcaster, fee_estimator, logger); + self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, self.best_block.height(), broadcaster, fee_estimator, logger); if let Some(ref tx) = self.prev_holder_signed_commitment_tx { let (claim_reqs, _) = self.get_broadcasted_holder_claims(&tx, 0); - self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, None, broadcaster, fee_estimator, logger); + self.onchain_tx_handler.update_claims_view(&Vec::new(), claim_reqs, self.best_block.height(), broadcaster, fee_estimator, logger); } } } @@ -1785,14 +1786,17 @@ impl ChannelMonitorImpl { for &(ref htlc, _, _) in holder_tx.htlc_outputs.iter() { if let Some(transaction_output_index) = htlc.transaction_output_index { - let htlc_output = HolderHTLCOutput::build(if !htlc.offered { - if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { - Some(preimage.clone()) + let htlc_output = if htlc.offered { + HolderHTLCOutput::build_offered(htlc.amount_msat, htlc.cltv_expiry) } else { - // We can't build an HTLC-Success transaction without the preimage - continue; - } - } else { None }, htlc.amount_msat); + let payment_preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) { + preimage.clone() + } else { + // We can't build an HTLC-Success transaction without the preimage + continue; + }; + HolderHTLCOutput::build_accepted(payment_preimage, htlc.amount_msat) + }; let htlc_package = PackageTemplate::build_package(holder_tx.txid, transaction_output_index, PackageSolvingData::HolderHTLCOutput(htlc_output), height, false, height); claim_requests.push(htlc_package); } @@ -1895,7 +1899,7 @@ impl ChannelMonitorImpl { self.holder_tx_signed = true; let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript); let txid = commitment_tx.txid(); - let mut res = vec![commitment_tx]; + let mut holder_transactions = vec![commitment_tx]; for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() { if let Some(vout) = htlc.0.transaction_output_index { let preimage = if !htlc.0.offered { @@ -1903,24 +1907,32 @@ impl ChannelMonitorImpl { // We can't build an HTLC-Success transaction without the preimage continue; } + } else if htlc.0.cltv_expiry > self.best_block.height() + 1 { + // Don't broadcast HTLC-Timeout transactions immediately as they don't meet the + // current locktime requirements on-chain. We will broadcast them in + // `block_confirmed` when `would_broadcast_at_height` returns true. + // Note that we add + 1 as transactions are broadcastable when they can be + // confirmed in the next block. + continue; } else { None }; if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx( &::bitcoin::OutPoint { txid, vout }, &preimage) { - res.push(htlc_tx); + holder_transactions.push(htlc_tx); } } } // We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do. // The data will be re-generated and tracked in check_spend_holder_transaction if we get a confirmation. - return res; + holder_transactions } #[cfg(any(test,feature = "unsafe_revoked_tx_signing"))] + /// Note that this includes possibly-locktimed-in-the-future transactions! fn unsafe_get_latest_holder_commitment_txn(&mut self, logger: &L) -> Vec where L::Target: Logger { log_trace!(logger, "Getting signed copy of latest holder commitment transaction!"); let commitment_tx = self.onchain_tx_handler.get_fully_signed_copy_holder_tx(&self.funding_redeemscript); let txid = commitment_tx.txid(); - let mut res = vec![commitment_tx]; + let mut holder_transactions = vec![commitment_tx]; for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() { if let Some(vout) = htlc.0.transaction_output_index { let preimage = if !htlc.0.offered { @@ -1931,11 +1943,11 @@ impl ChannelMonitorImpl { } else { None }; if let Some(htlc_tx) = self.onchain_tx_handler.unsafe_get_fully_signed_htlc_tx( &::bitcoin::OutPoint { txid, vout }, &preimage) { - res.push(htlc_tx); + holder_transactions.push(htlc_tx); } } } - return res + holder_transactions } pub fn block_connected(&mut self, header: &BlockHeader, txdata: &TransactionData, height: u32, broadcaster: B, fee_estimator: F, logger: L) -> Vec @@ -2140,7 +2152,7 @@ impl ChannelMonitorImpl { } } - self.onchain_tx_handler.update_claims_view(&txn_matched, claimable_outpoints, Some(height), &&*broadcaster, &&*fee_estimator, &&*logger); + self.onchain_tx_handler.update_claims_view(&txn_matched, claimable_outpoints, height, &&*broadcaster, &&*fee_estimator, &&*logger); // Determine new outputs to watch by comparing against previously known outputs to watch, // updating the latter in the process. @@ -2911,12 +2923,13 @@ mod tests { use bitcoin::secp256k1::Secp256k1; use std::sync::{Arc, Mutex}; use chain::keysinterface::InMemorySigner; + use prelude::*; #[test] fn test_prune_preimages() { let secp_ctx = Secp256k1::new(); let logger = Arc::new(TestLogger::new()); - let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}); + let broadcaster = Arc::new(TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))}); let fee_estimator = Arc::new(TestFeeEstimator { sat_per_kw: 253 }); let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); diff --git a/lightning/src/chain/keysinterface.rs b/lightning/src/chain/keysinterface.rs index d6fea17d..1f118562 100644 --- a/lightning/src/chain/keysinterface.rs +++ b/lightning/src/chain/keysinterface.rs @@ -37,6 +37,7 @@ use ln::chan_utils; use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction}; use ln::msgs::UnsignedChannelAnnouncement; +use prelude::*; use std::collections::HashSet; use core::sync::atomic::{AtomicUsize, Ordering}; use std::io::Error; diff --git a/lightning/src/chain/mod.rs b/lightning/src/chain/mod.rs index 856a9e8a..e4bb66c7 100644 --- a/lightning/src/chain/mod.rs +++ b/lightning/src/chain/mod.rs @@ -18,6 +18,8 @@ use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitor use chain::keysinterface::Sign; use chain::transaction::{OutPoint, TransactionData}; +use prelude::*; + pub mod chaininterface; pub mod chainmonitor; pub mod channelmonitor; diff --git a/lightning/src/chain/onchaintx.rs b/lightning/src/chain/onchaintx.rs index 4e6a067f..1f604422 100644 --- a/lightning/src/chain/onchaintx.rs +++ b/lightning/src/chain/onchaintx.rs @@ -32,6 +32,8 @@ use util::logger::Logger; use util::ser::{Readable, ReadableArgs, Writer, Writeable, VecWriter}; use util::byte_utils; +use prelude::*; +use alloc::collections::BTreeMap; use std::collections::HashMap; use core::cmp; use core::ops::Deref; @@ -164,9 +166,9 @@ pub struct OnchainTxHandler { #[cfg(not(test))] claimable_outpoints: HashMap, - onchain_events_awaiting_threshold_conf: Vec, + locktimed_packages: BTreeMap>, - latest_height: u32, + onchain_events_awaiting_threshold_conf: Vec, pub(super) secp_ctx: Secp256k1, } @@ -206,6 +208,15 @@ impl OnchainTxHandler { claim_and_height.1.write(writer)?; } + writer.write_all(&byte_utils::be64_to_array(self.locktimed_packages.len() as u64))?; + for (ref locktime, ref packages) in self.locktimed_packages.iter() { + locktime.write(writer)?; + writer.write_all(&byte_utils::be64_to_array(packages.len() as u64))?; + for ref package in packages.iter() { + package.write(writer)?; + } + } + writer.write_all(&byte_utils::be64_to_array(self.onchain_events_awaiting_threshold_conf.len() as u64))?; for ref entry in self.onchain_events_awaiting_threshold_conf.iter() { entry.txid.write(writer)?; @@ -221,7 +232,6 @@ impl OnchainTxHandler { } } } - self.latest_height.write(writer)?; write_tlv_fields!(writer, {}, {}); Ok(()) @@ -266,6 +276,19 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler { let height = Readable::read(reader)?; claimable_outpoints.insert(outpoint, (ancestor_claim_txid, height)); } + + let locktimed_packages_len: u64 = Readable::read(reader)?; + let mut locktimed_packages = BTreeMap::new(); + for _ in 0..locktimed_packages_len { + let locktime = Readable::read(reader)?; + let packages_len: u64 = Readable::read(reader)?; + let mut packages = Vec::with_capacity(cmp::min(packages_len as usize, MAX_ALLOC_SIZE / std::mem::size_of::())); + for _ in 0..packages_len { + packages.push(Readable::read(reader)?); + } + locktimed_packages.insert(locktime, packages); + } + let waiting_threshold_conf_len: u64 = Readable::read(reader)?; let mut onchain_events_awaiting_threshold_conf = Vec::with_capacity(cmp::min(waiting_threshold_conf_len as usize, MAX_ALLOC_SIZE / 128)); for _ in 0..waiting_threshold_conf_len { @@ -288,7 +311,6 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler { }; onchain_events_awaiting_threshold_conf.push(OnchainEventEntry { txid, height, event }); } - let latest_height = Readable::read(reader)?; read_tlv_fields!(reader, {}, {}); @@ -304,9 +326,9 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler { signer, channel_transaction_parameters: channel_parameters, claimable_outpoints, + locktimed_packages, pending_claim_requests, onchain_events_awaiting_threshold_conf, - latest_height, secp_ctx, }) } @@ -324,8 +346,8 @@ impl OnchainTxHandler { channel_transaction_parameters: channel_parameters, pending_claim_requests: HashMap::new(), claimable_outpoints: HashMap::new(), + locktimed_packages: BTreeMap::new(), onchain_events_awaiting_threshold_conf: Vec::new(), - latest_height: 0, secp_ctx, } @@ -344,10 +366,9 @@ impl OnchainTxHandler { // Compute new height timer to decide when we need to regenerate a new bumped version of the claim tx (if we // didn't receive confirmation of it before, or not enough reorg-safe depth on top of it). let new_timer = Some(cached_request.get_height_timer(height)); - let amt = cached_request.package_amount(); if cached_request.is_malleable() { let predicted_weight = cached_request.package_weight(&self.destination_script); - if let Some((output_value, new_feerate)) = cached_request.compute_package_output(predicted_weight, amt, fee_estimator, logger) { + if let Some((output_value, new_feerate)) = cached_request.compute_package_output(predicted_weight, fee_estimator, logger) { assert!(new_feerate != 0); let transaction = cached_request.finalize_package(self, output_value, self.destination_script.clone(), logger).unwrap(); @@ -359,8 +380,7 @@ impl OnchainTxHandler { // Note: Currently, amounts of holder outputs spending witnesses aren't used // as we can't malleate spending package to increase their feerate. This // should change with the remaining anchor output patchset. - debug_assert!(amt == 0); - if let Some(transaction) = cached_request.finalize_package(self, amt, self.destination_script.clone(), logger) { + if let Some(transaction) = cached_request.finalize_package(self, 0, self.destination_script.clone(), logger) { return Some((None, 0, transaction)); } } @@ -371,15 +391,11 @@ impl OnchainTxHandler { /// for this channel, provide new relevant on-chain transactions and/or new claim requests. /// Formerly this was named `block_connected`, but it is now also used for claiming an HTLC output /// if we receive a preimage after force-close. - pub(crate) fn update_claims_view(&mut self, txn_matched: &[&Transaction], requests: Vec, latest_height: Option, broadcaster: &B, fee_estimator: &F, logger: &L) + pub(crate) fn update_claims_view(&mut self, txn_matched: &[&Transaction], requests: Vec, height: u32, broadcaster: &B, fee_estimator: &F, logger: &L) where B::Target: BroadcasterInterface, F::Target: FeeEstimator, L::Target: Logger, { - let height = match latest_height { - Some(h) => h, - None => self.latest_height, - }; log_trace!(logger, "Updating claims view at height {} with {} matched transactions and {} claim requests", height, txn_matched.len(), requests.len()); let mut preprocessed_requests = Vec::with_capacity(requests.len()); let mut aggregated_request = None; @@ -388,7 +404,26 @@ impl OnchainTxHandler { // <= CLTV_SHARED_CLAIM_BUFFER) and they don't require an immediate nLockTime (aggregable). for req in requests { // Don't claim a outpoint twice that would be bad for privacy and may uselessly lock a CPFP input for a while - if let Some(_) = self.claimable_outpoints.get(req.outpoints()[0]) { log_trace!(logger, "Bouncing off outpoint {}:{}, already registered its claiming request", req.outpoints()[0].txid, req.outpoints()[0].vout); } else { + if let Some(_) = self.claimable_outpoints.get(req.outpoints()[0]) { + log_trace!(logger, "Ignoring second claim for outpoint {}:{}, already registered its claiming request", req.outpoints()[0].txid, req.outpoints()[0].vout); + } else { + let timelocked_equivalent_package = self.locktimed_packages.iter().map(|v| v.1.iter()).flatten() + .find(|locked_package| locked_package.outpoints() == req.outpoints()); + if let Some(package) = timelocked_equivalent_package { + log_trace!(logger, "Ignoring second claim for outpoint {}:{}, we already have one which we're waiting on a timelock at {} for.", + req.outpoints()[0].txid, req.outpoints()[0].vout, package.package_timelock()); + continue; + } + + if req.package_timelock() > height + 1 { + log_debug!(logger, "Delaying claim of package until its timelock at {} (current height {}), the following outpoints are spent:", req.package_timelock(), height); + for outpoint in req.outpoints() { + log_debug!(logger, " Outpoint {}", outpoint); + } + self.locktimed_packages.entry(req.package_timelock()).or_insert(Vec::new()).push(req); + continue; + } + log_trace!(logger, "Test if outpoint can be aggregated with expiration {} against {}", req.timelock(), height + CLTV_SHARED_CLAIM_BUFFER); if req.timelock() <= height + CLTV_SHARED_CLAIM_BUFFER || !req.aggregable() { // Don't aggregate if outpoint package timelock is soon or marked as non-aggregable @@ -404,6 +439,14 @@ impl OnchainTxHandler { preprocessed_requests.push(req); } + // Claim everything up to and including height + 1 + let remaining_locked_packages = self.locktimed_packages.split_off(&(height + 2)); + for (pop_height, mut entry) in self.locktimed_packages.iter_mut() { + log_trace!(logger, "Restoring delayed claim of package(s) at their timelock at {}.", pop_height); + preprocessed_requests.append(&mut entry); + } + self.locktimed_packages = remaining_locked_packages; + // Generate claim transactions and track them to bump if necessary at // height timer expiration (i.e in how many blocks we're going to take action). for mut req in preprocessed_requests { diff --git a/lightning/src/chain/package.rs b/lightning/src/chain/package.rs index 2e1e5037..a7339468 100644 --- a/lightning/src/chain/package.rs +++ b/lightning/src/chain/package.rs @@ -21,7 +21,7 @@ use bitcoin::hash_types::Txid; use bitcoin::secp256k1::key::{SecretKey,PublicKey}; use ln::PaymentPreimage; -use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment, HTLC_OUTPUT_IN_COMMITMENT_SIZE}; +use ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment}; use ln::chan_utils; use ln::msgs::DecodeError; use chain::chaininterface::{FeeEstimator, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT}; @@ -31,9 +31,9 @@ use util::byte_utils; use util::logger::Logger; use util::ser::{Readable, Writer, Writeable}; -use std::cmp; -use std::mem; -use std::ops::Deref; +use core::cmp; +use core::mem; +use core::ops::Deref; const MAX_ALLOC_SIZE: usize = 64*1024; @@ -86,15 +86,15 @@ impl RevokedOutput { } } -impl_writeable!(RevokedOutput, 33*3 + 32 + 8 + 8 + 2, { - per_commitment_point, - counterparty_delayed_payment_base_key, - counterparty_htlc_base_key, - per_commitment_key, - weight, - amount, - on_counterparty_tx_csv -}); +impl_writeable_tlv_based!(RevokedOutput, { + (0, per_commitment_point), + (2, counterparty_delayed_payment_base_key), + (4, counterparty_htlc_base_key), + (6, per_commitment_key), + (8, weight), + (10, amount), + (12, on_counterparty_tx_csv), +}, {}, {}); /// A struct to describe a revoked offered output and corresponding information to generate a /// solving witness. @@ -130,15 +130,15 @@ impl RevokedHTLCOutput { } } -impl_writeable!(RevokedHTLCOutput, 33*3 + 32 + 8 + 8 + HTLC_OUTPUT_IN_COMMITMENT_SIZE, { - per_commitment_point, - counterparty_delayed_payment_base_key, - counterparty_htlc_base_key, - per_commitment_key, - weight, - amount, - htlc -}); +impl_writeable_tlv_based!(RevokedHTLCOutput, { + (0, per_commitment_point), + (2, counterparty_delayed_payment_base_key), + (4, counterparty_htlc_base_key), + (6, per_commitment_key), + (8, weight), + (10, amount), + (12, htlc), +}, {}, {}); /// A struct to describe a HTLC output on a counterparty commitment transaction. /// @@ -167,13 +167,13 @@ impl CounterpartyOfferedHTLCOutput { } } -impl_writeable!(CounterpartyOfferedHTLCOutput, 33*3 + 32 + HTLC_OUTPUT_IN_COMMITMENT_SIZE, { - per_commitment_point, - counterparty_delayed_payment_base_key, - counterparty_htlc_base_key, - preimage, - htlc -}); +impl_writeable_tlv_based!(CounterpartyOfferedHTLCOutput, { + (0, per_commitment_point), + (2, counterparty_delayed_payment_base_key), + (4, counterparty_htlc_base_key), + (6, preimage), + (8, htlc), +}, {}, {}); /// A struct to describe a HTLC output on a counterparty commitment transaction. /// @@ -198,12 +198,12 @@ impl CounterpartyReceivedHTLCOutput { } } -impl_writeable!(CounterpartyReceivedHTLCOutput, 33*3 + HTLC_OUTPUT_IN_COMMITMENT_SIZE, { - per_commitment_point, - counterparty_delayed_payment_base_key, - counterparty_htlc_base_key, - htlc -}); +impl_writeable_tlv_based!(CounterpartyReceivedHTLCOutput, { + (0, per_commitment_point), + (2, counterparty_delayed_payment_base_key), + (4, counterparty_htlc_base_key), + (6, htlc), +}, {}, {}); /// A struct to describe a HTLC output on holder commitment transaction. /// @@ -213,21 +213,34 @@ impl_writeable!(CounterpartyReceivedHTLCOutput, 33*3 + HTLC_OUTPUT_IN_COMMITMENT pub(crate) struct HolderHTLCOutput { preimage: Option, amount: u64, + /// Defaults to 0 for HTLC-Success transactions, which have no expiry + cltv_expiry: u32, } impl HolderHTLCOutput { - pub(crate) fn build(preimage: Option, amount: u64) -> Self { + pub(crate) fn build_offered(amount: u64, cltv_expiry: u32) -> Self { HolderHTLCOutput { - preimage, - amount + preimage: None, + amount, + cltv_expiry, + } + } + + pub(crate) fn build_accepted(preimage: PaymentPreimage, amount: u64) -> Self { + HolderHTLCOutput { + preimage: Some(preimage), + amount, + cltv_expiry: 0, } } } -impl_writeable!(HolderHTLCOutput, 0, { - preimage, - amount -}); +impl_writeable_tlv_based!(HolderHTLCOutput, { + (0, amount), + (2, cltv_expiry), +}, { + (4, preimage), +}, {}); /// A struct to describe the channel output on the funding transaction. /// @@ -245,9 +258,9 @@ impl HolderFundingOutput { } } -impl_writeable!(HolderFundingOutput, 0, { - funding_redeemscript -}); +impl_writeable_tlv_based!(HolderFundingOutput, { + (0, funding_redeemscript), +}, {}, {}); /// A wrapper encapsulating all in-protocol differing outputs types. /// @@ -273,8 +286,8 @@ impl PackageSolvingData { // Note: Currently, amounts of holder outputs spending witnesses aren't used // as we can't malleate spending package to increase their feerate. This // should change with the remaining anchor output patchset. - PackageSolvingData::HolderHTLCOutput(..) => { 0 }, - PackageSolvingData::HolderFundingOutput(..) => { 0 }, + PackageSolvingData::HolderHTLCOutput(..) => { unreachable!() }, + PackageSolvingData::HolderFundingOutput(..) => { unreachable!() }, }; amt } @@ -287,8 +300,8 @@ impl PackageSolvingData { // Note: Currently, weights of holder outputs spending witnesses aren't used // as we can't malleate spending package to increase their feerate. This // should change with the remaining anchor output patchset. - PackageSolvingData::HolderHTLCOutput(..) => { debug_assert!(false); 0 }, - PackageSolvingData::HolderFundingOutput(..) => { debug_assert!(false); 0 }, + PackageSolvingData::HolderHTLCOutput(..) => { unreachable!() }, + PackageSolvingData::HolderFundingOutput(..) => { unreachable!() }, }; weight } @@ -374,6 +387,21 @@ impl PackageSolvingData { _ => { panic!("API Error!"); } } } + fn absolute_tx_timelock(&self, output_conf_height: u32) -> u32 { + // Get the absolute timelock at which this output can be spent given the height at which + // this output was confirmed. We use `output_conf_height + 1` as a safe default as we can + // be confirmed in the next block and transactions with time lock `current_height + 1` + // always propagate. + let absolute_timelock = match self { + PackageSolvingData::RevokedOutput(_) => output_conf_height + 1, + PackageSolvingData::RevokedHTLCOutput(_) => output_conf_height + 1, + PackageSolvingData::CounterpartyOfferedHTLCOutput(_) => output_conf_height + 1, + PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => std::cmp::max(outp.htlc.cltv_expiry, output_conf_height + 1), + PackageSolvingData::HolderHTLCOutput(ref outp) => std::cmp::max(outp.cltv_expiry, output_conf_height + 1), + PackageSolvingData::HolderFundingOutput(_) => output_conf_height + 1, + }; + absolute_timelock + } } impl Writeable for PackageSolvingData { @@ -576,13 +604,19 @@ impl PackageTemplate { } self.height_timer = cmp::min(self.height_timer, merge_from.height_timer); } - pub(crate) fn package_amount(&self) -> u64 { + /// Gets the amount of all outptus being spent by this package, only valid for malleable + /// packages. + fn package_amount(&self) -> u64 { let mut amounts = 0; for (_, outp) in self.inputs.iter() { amounts += outp.amount(); } amounts } + pub(crate) fn package_timelock(&self) -> u32 { + self.inputs.iter().map(|(_, outp)| outp.absolute_tx_timelock(self.height_original)) + .max().expect("There must always be at least one output to spend in a PackageTemplate") + } pub(crate) fn package_weight(&self, destination_script: &Script) -> usize { let mut inputs_weight = 0; let mut witnesses_weight = 2; // count segwit flags @@ -627,6 +661,7 @@ impl PackageTemplate { return Some(bumped_tx); }, PackageMalleability::Untractable => { + debug_assert_eq!(value, 0, "value is ignored for non-malleable packages, should be zero to ensure callsites are correct"); if let Some((outpoint, outp)) = self.inputs.first() { if let Some(final_tx) = outp.get_finalized_tx(outpoint, onchain_handler) { log_trace!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout); @@ -652,10 +687,12 @@ impl PackageTemplate { current_height + LOW_FREQUENCY_BUMP_INTERVAL } /// Returns value in satoshis to be included as package outgoing output amount and feerate with which package finalization should be done. - pub(crate) fn compute_package_output(&self, predicted_weight: usize, input_amounts: u64, fee_estimator: &F, logger: &L) -> Option<(u64, u64)> + pub(crate) fn compute_package_output(&self, predicted_weight: usize, fee_estimator: &F, logger: &L) -> Option<(u64, u64)> where F::Target: FeeEstimator, L::Target: Logger, { + debug_assert!(self.malleability == PackageMalleability::Malleable, "The package output is fixed for non-malleable packages"); + let input_amounts = self.package_amount(); // If old feerate is 0, first iteration of this claim, use normal fee calculation if self.feerate_previous != 0 { if let Some((new_fee, feerate)) = feerate_bump(predicted_weight, input_amounts, self.feerate_previous, fee_estimator, logger) { @@ -703,10 +740,11 @@ impl Writeable for PackageTemplate { outpoint.write(writer)?; rev_outp.write(writer)?; } - self.soonest_conf_deadline.write(writer)?; - self.feerate_previous.write(writer)?; - self.height_timer.write(writer)?; - self.height_original.write(writer)?; + write_tlv_fields!(writer, { + (0, self.soonest_conf_deadline), + (2, self.feerate_previous), + (4, self.height_original), + }, { (6, self.height_timer) }); Ok(()) } } @@ -730,10 +768,15 @@ impl Readable for PackageTemplate { PackageSolvingData::HolderFundingOutput(..) => { (PackageMalleability::Untractable, false) }, } } else { return Err(DecodeError::InvalidValue); }; - let soonest_conf_deadline = Readable::read(reader)?; - let feerate_previous = Readable::read(reader)?; - let height_timer = Readable::read(reader)?; - let height_original = Readable::read(reader)?; + let mut soonest_conf_deadline = 0; + let mut feerate_previous = 0; + let mut height_timer = None; + let mut height_original = 0; + read_tlv_fields!(reader, { + (0, soonest_conf_deadline), + (2, feerate_previous), + (4, height_original) + }, { (6, height_timer) }); Ok(PackageTemplate { inputs, malleability, @@ -867,7 +910,7 @@ mod tests { () => { { let preimage = PaymentPreimage([2;32]); - PackageSolvingData::HolderHTLCOutput(HolderHTLCOutput::build(Some(preimage), 0)) + PackageSolvingData::HolderHTLCOutput(HolderHTLCOutput::build_accepted(preimage, 0)) } } } diff --git a/lightning/src/chain/transaction.rs b/lightning/src/chain/transaction.rs index 502eb895..4db5fbed 100644 --- a/lightning/src/chain/transaction.rs +++ b/lightning/src/chain/transaction.rs @@ -73,6 +73,14 @@ impl OutPoint { vout: self.index as u32, } } + + /// Creates a dummy BitcoinOutPoint, useful for deserializing into. + pub(crate) fn null() -> Self { + Self { + txid: Default::default(), + index: 0 + } + } } impl_writeable!(OutPoint, 0, { txid, index }); diff --git a/lightning/src/lib.rs b/lightning/src/lib.rs index 3c09f386..a9f46b43 100644 --- a/lightning/src/lib.rs +++ b/lightning/src/lib.rs @@ -31,6 +31,7 @@ #![cfg_attr(all(any(test, feature = "_test_utils"), feature = "unstable"), feature(test))] #[cfg(all(any(test, feature = "_test_utils"), feature = "unstable"))] extern crate test; +extern crate alloc; extern crate bitcoin; extern crate core; #[cfg(any(test, feature = "_test_utils"))] extern crate hex; @@ -41,3 +42,7 @@ pub mod util; pub mod chain; pub mod ln; pub mod routing; + +mod prelude { + pub use alloc::{vec, vec::Vec, string::String}; +} \ No newline at end of file diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index 28b5a9f8..81b0df09 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -31,6 +31,7 @@ use bitcoin::secp256k1::{Secp256k1, Signature, Message}; use bitcoin::secp256k1::Error as SecpError; use bitcoin::secp256k1; +use prelude::*; use core::cmp; use ln::chan_utils; use util::transaction_utils::sort_outputs; @@ -178,6 +179,7 @@ impl Writeable for CounterpartyCommitmentSecrets { writer.write_all(secret)?; writer.write_all(&byte_utils::be64_to_array(*idx))?; } + write_tlv_fields!(writer, {}, {}); Ok(()) } } @@ -188,7 +190,7 @@ impl Readable for CounterpartyCommitmentSecrets { *secret = Readable::read(reader)?; *idx = Readable::read(reader)?; } - + read_tlv_fields!(reader, {}, {}); Ok(Self { old_secrets }) } } @@ -322,8 +324,13 @@ pub struct TxCreationKeys { pub broadcaster_delayed_payment_key: PublicKey, } -impl_writeable!(TxCreationKeys, 33*5, - { per_commitment_point, revocation_key, broadcaster_htlc_key, countersignatory_htlc_key, broadcaster_delayed_payment_key }); +impl_writeable_tlv_based!(TxCreationKeys, { + (0, per_commitment_point), + (2, revocation_key), + (4, broadcaster_htlc_key), + (6, countersignatory_htlc_key), + (8, broadcaster_delayed_payment_key), +}, {}, {}); /// One counterparty's public keys which do not change over the life of a channel. #[derive(Clone, PartialEq)] @@ -349,14 +356,13 @@ pub struct ChannelPublicKeys { pub htlc_basepoint: PublicKey, } -impl_writeable!(ChannelPublicKeys, 33*5, { - funding_pubkey, - revocation_basepoint, - payment_point, - delayed_payment_basepoint, - htlc_basepoint -}); - +impl_writeable_tlv_based!(ChannelPublicKeys, { + (0, funding_pubkey), + (2, revocation_basepoint), + (4, payment_point), + (6, delayed_payment_basepoint), + (8, htlc_basepoint), +}, {}, {}); impl TxCreationKeys { /// Create per-state keys from channel base points and the per-commitment point. @@ -429,16 +435,14 @@ pub struct HTLCOutputInCommitment { pub transaction_output_index: Option, } -impl_writeable_len_match!(HTLCOutputInCommitment, { - { HTLCOutputInCommitment { transaction_output_index: None, .. }, HTLC_OUTPUT_IN_COMMITMENT_SIZE - 4 }, - { _, HTLC_OUTPUT_IN_COMMITMENT_SIZE } - }, { - offered, - amount_msat, - cltv_expiry, - payment_hash, - transaction_output_index -}); +impl_writeable_tlv_based!(HTLCOutputInCommitment, { + (0, offered), + (2, amount_msat), + (4, cltv_expiry), + (6, payment_hash), +}, { + (8, transaction_output_index) +}, {}); #[inline] pub(crate) fn get_htlc_redeemscript_with_explicit_keys(htlc: &HTLCOutputInCommitment, broadcaster_htlc_key: &PublicKey, countersignatory_htlc_key: &PublicKey, revocation_key: &PublicKey) -> Script { @@ -622,18 +626,19 @@ impl ChannelTransactionParameters { } } -impl_writeable!(CounterpartyChannelTransactionParameters, 0, { - pubkeys, - selected_contest_delay -}); +impl_writeable_tlv_based!(CounterpartyChannelTransactionParameters, { + (0, pubkeys), + (2, selected_contest_delay), +}, {}, {}); -impl_writeable!(ChannelTransactionParameters, 0, { - holder_pubkeys, - holder_selected_contest_delay, - is_outbound_from_holder, - counterparty_parameters, - funding_outpoint -}); +impl_writeable_tlv_based!(ChannelTransactionParameters, { + (0, holder_pubkeys), + (2, holder_selected_contest_delay), + (4, is_outbound_from_holder), +}, { + (6, counterparty_parameters), + (8, funding_outpoint), +}, {}); /// Static channel fields used to build transactions given per-commitment fields, organized by /// broadcaster/countersignatory. @@ -715,8 +720,12 @@ impl PartialEq for HolderCommitmentTransaction { } } -impl_writeable!(HolderCommitmentTransaction, 0, { - inner, counterparty_sig, counterparty_htlc_sigs, holder_sig_first +impl_writeable_tlv_based!(HolderCommitmentTransaction, { + (0, inner), + (2, counterparty_sig), + (4, holder_sig_first), +}, {}, { + (6, counterparty_htlc_sigs), }); impl HolderCommitmentTransaction { @@ -800,7 +809,10 @@ pub struct BuiltCommitmentTransaction { pub txid: Txid, } -impl_writeable!(BuiltCommitmentTransaction, 0, { transaction, txid }); +impl_writeable_tlv_based!(BuiltCommitmentTransaction, { + (0, transaction), + (2, txid) +}, {}, {}); impl BuiltCommitmentTransaction { /// Get the SIGHASH_ALL sighash value of the transaction. @@ -883,15 +895,15 @@ impl Readable for Vec { } } -impl_writeable!(CommitmentTransaction, 0, { - commitment_number, - to_broadcaster_value_sat, - to_countersignatory_value_sat, - feerate_per_kw, - htlcs, - keys, - built -}); +impl_writeable_tlv_based!(CommitmentTransaction, { + (0, commitment_number), + (2, to_broadcaster_value_sat), + (4, to_countersignatory_value_sat), + (6, feerate_per_kw), + (8, htlcs), + (10, keys), + (12, built), +}, {}, {}); impl CommitmentTransaction { /// Construct an object of the class while assigning transaction output indices to HTLCs. @@ -1235,6 +1247,7 @@ fn script_for_p2wpkh(key: &PublicKey) -> Script { mod tests { use super::CounterpartyCommitmentSecrets; use hex; + use prelude::*; #[test] fn test_per_commitment_storage() { diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 2e758aa4..e945f051 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -13,6 +13,7 @@ //! here. See also the chanmon_fail_consistency fuzz test. use bitcoin::blockdata::block::{Block, BlockHeader}; +use bitcoin::blockdata::constants::genesis_block; use bitcoin::hash_types::BlockHash; use bitcoin::network::constants::Network; use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr}; @@ -30,6 +31,7 @@ use util::enforcing_trait_impls::EnforcingSigner; use util::events::{Event, MessageSendEvent, MessageSendEventsProvider}; use util::errors::APIError; use util::ser::{ReadableArgs, Writeable}; +use util::test_utils::TestBroadcaster; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::Hash; @@ -38,7 +40,9 @@ use ln::functional_test_utils::*; use util::test_utils; +use prelude::*; use std::collections::HashMap; +use std::sync::{Arc, Mutex}; // If persister_fail is true, we have the persister return a PermanentFailure // instead of the higher-level ChainMonitor. @@ -106,6 +110,13 @@ fn test_monitor_and_persister_update_fail() { let chain_source = test_utils::TestChainSource::new(Network::Testnet); let logger = test_utils::TestLogger::with_id(format!("node {}", 0)); let persister = test_utils::TestPersister::new(); + let tx_broadcaster = TestBroadcaster { + txn_broadcasted: Mutex::new(Vec::new()), + // Because we will connect a block at height 200 below, we need the TestBroadcaster to know + // that we are at height 200 so that it doesn't think we're violating the time lock + // requirements of transactions broadcasted at that point. + blocks: Arc::new(Mutex::new(vec![(genesis_block(Network::Testnet).header, 200); 200])), + }; let chain_mon = { let monitors = nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap(); let monitor = monitors.get(&outpoint).unwrap(); @@ -114,7 +125,7 @@ fn test_monitor_and_persister_update_fail() { let new_monitor = <(BlockHash, ChannelMonitor)>::read( &mut ::std::io::Cursor::new(&w.0), &test_utils::OnlyReadsKeysInterface {}).unwrap().1; assert!(new_monitor == *monitor); - let chain_mon = test_utils::TestChainMonitor::new(Some(&chain_source), &chanmon_cfgs[0].tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager); + let chain_mon = test_utils::TestChainMonitor::new(Some(&chain_source), &tx_broadcaster, &logger, &chanmon_cfgs[0].fee_estimator, &persister, &node_cfgs[0].keys_manager); assert!(chain_mon.watch_channel(outpoint, new_monitor).is_ok()); chain_mon }; diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index 51872337..1c1b85ca 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -40,6 +40,7 @@ use util::errors::APIError; use util::config::{UserConfig,ChannelConfig}; use util::scid_utils::scid_from_parts; +use prelude::*; use core::{cmp,mem,fmt}; use core::ops::Deref; #[cfg(any(test, feature = "fuzztarget"))] @@ -4928,6 +4929,7 @@ mod tests { use bitcoin::hashes::Hash; use bitcoin::hash_types::{Txid, WPubkeyHash}; use std::sync::Arc; + use prelude::*; struct TestFeeEstimator { fee_est: u32 diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 9d4d55c4..9c1f8ecf 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -61,8 +61,9 @@ use util::chacha20::{ChaCha20, ChaChaReader}; use util::logger::Logger; use util::errors::APIError; +use prelude::*; use core::{cmp, mem}; -use std::cell::RefCell; +use core::cell::RefCell; use std::collections::{HashMap, hash_map, HashSet}; use std::io::{Cursor, Read}; use std::sync::{Arc, Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard}; @@ -3685,7 +3686,7 @@ impl ChannelMana #[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))] pub fn get_and_clear_pending_events(&self) -> Vec { - let events = std::cell::RefCell::new(Vec::new()); + let events = core::cell::RefCell::new(Vec::new()); let event_handler = |event| events.borrow_mut().push(event); self.process_pending_events(&event_handler); events.into_inner() @@ -4316,9 +4317,9 @@ impl PersistenceNotifier { const SERIALIZATION_VERSION: u8 = 1; const MIN_SERIALIZATION_VERSION: u8 = 1; -impl Writeable for PendingHTLCInfo { +impl Writeable for PendingHTLCRouting { fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - match &self.routing { + match &self { &PendingHTLCRouting::Forward { ref onion_packet, ref short_channel_id } => { 0u8.write(writer)?; onion_packet.write(writer)?; @@ -4331,39 +4332,37 @@ impl Writeable for PendingHTLCInfo { incoming_cltv_expiry.write(writer)?; }, } - self.incoming_shared_secret.write(writer)?; - self.payment_hash.write(writer)?; - self.amt_to_forward.write(writer)?; - self.outgoing_cltv_value.write(writer)?; Ok(()) } } -impl Readable for PendingHTLCInfo { - fn read(reader: &mut R) -> Result { - Ok(PendingHTLCInfo { - routing: match Readable::read(reader)? { - 0u8 => PendingHTLCRouting::Forward { - onion_packet: Readable::read(reader)?, - short_channel_id: Readable::read(reader)?, - }, - 1u8 => PendingHTLCRouting::Receive { - payment_data: msgs::FinalOnionHopData { - payment_secret: Readable::read(reader)?, - total_msat: Readable::read(reader)?, - }, - incoming_cltv_expiry: Readable::read(reader)?, +impl Readable for PendingHTLCRouting { + fn read(reader: &mut R) -> Result { + match Readable::read(reader)? { + 0u8 => Ok(PendingHTLCRouting::Forward { + onion_packet: Readable::read(reader)?, + short_channel_id: Readable::read(reader)?, + }), + 1u8 => Ok(PendingHTLCRouting::Receive { + payment_data: msgs::FinalOnionHopData { + payment_secret: Readable::read(reader)?, + total_msat: Readable::read(reader)?, }, - _ => return Err(DecodeError::InvalidValue), - }, - incoming_shared_secret: Readable::read(reader)?, - payment_hash: Readable::read(reader)?, - amt_to_forward: Readable::read(reader)?, - outgoing_cltv_value: Readable::read(reader)?, - }) + incoming_cltv_expiry: Readable::read(reader)?, + }), + _ => Err(DecodeError::InvalidValue), + } } } +impl_writeable_tlv_based!(PendingHTLCInfo, { + (0, routing), + (2, incoming_shared_secret), + (4, payment_hash), + (6, amt_to_forward), + (8, outgoing_cltv_value) +}, {}, {}); + impl Writeable for HTLCFailureMsg { fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { match self { @@ -4416,33 +4415,52 @@ impl Readable for PendingHTLCStatus { } } -impl_writeable!(HTLCPreviousHopData, 0, { - short_channel_id, - outpoint, - htlc_id, - incoming_packet_shared_secret -}); +impl_writeable_tlv_based!(HTLCPreviousHopData, { + (0, short_channel_id), + (2, outpoint), + (4, htlc_id), + (6, incoming_packet_shared_secret) +}, {}, {}); impl Writeable for ClaimableHTLC { fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - self.prev_hop.write(writer)?; - self.value.write(writer)?; - self.payment_data.payment_secret.write(writer)?; - self.payment_data.total_msat.write(writer)?; - self.cltv_expiry.write(writer) + write_tlv_fields!(writer, { + (0, self.prev_hop), + (2, self.value), + (4, self.payment_data.payment_secret), + (6, self.payment_data.total_msat), + (8, self.cltv_expiry) + }, {}); + Ok(()) } } impl Readable for ClaimableHTLC { fn read(reader: &mut R) -> Result { + let mut prev_hop = HTLCPreviousHopData { + short_channel_id: 0, htlc_id: 0, + incoming_packet_shared_secret: [0; 32], + outpoint: OutPoint::null(), + }; + let mut value = 0; + let mut payment_secret = PaymentSecret([0; 32]); + let mut total_msat = 0; + let mut cltv_expiry = 0; + read_tlv_fields!(reader, { + (0, prev_hop), + (2, value), + (4, payment_secret), + (6, total_msat), + (8, cltv_expiry) + }, {}); Ok(ClaimableHTLC { - prev_hop: Readable::read(reader)?, - value: Readable::read(reader)?, + prev_hop, + value, payment_data: msgs::FinalOnionHopData { - payment_secret: Readable::read(reader)?, - total_msat: Readable::read(reader)?, + payment_secret, + total_msat, }, - cltv_expiry: Readable::read(reader)?, + cltv_expiry, }) } } @@ -4547,13 +4565,13 @@ impl Readable for HTLCForwardInfo { } } -impl_writeable!(PendingInboundPayment, 0, { - payment_secret, - expiry_time, - user_payment_id, - payment_preimage, - min_value_msat -}); +impl_writeable_tlv_based!(PendingInboundPayment, { + (0, payment_secret), + (2, expiry_time), + (4, user_payment_id), + (6, payment_preimage), + (8, min_value_msat), +}, {}, {}); impl Writeable for ChannelManager where M::Target: chain::Watch, @@ -5017,7 +5035,7 @@ pub mod bench { use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::{Block, BlockHeader, Transaction, TxOut}; - use std::sync::Mutex; + use std::sync::{Arc, Mutex}; use test::Bencher; @@ -5043,7 +5061,7 @@ pub mod bench { let network = bitcoin::Network::Testnet; let genesis_hash = bitcoin::blockdata::constants::genesis_block(network).header.block_hash(); - let tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}; + let tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))}; let fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; let mut config: UserConfig = Default::default(); diff --git a/lightning/src/ln/features.rs b/lightning/src/ln/features.rs index cbe8cedf..b459baf0 100644 --- a/lightning/src/ln/features.rs +++ b/lightning/src/ln/features.rs @@ -22,6 +22,7 @@ //! [BOLT #9]: https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md //! [messages]: crate::ln::msgs +use prelude::*; use core::{cmp, fmt}; use core::marker::PhantomData; @@ -31,6 +32,7 @@ use ln::msgs::DecodeError; use util::ser::{Readable, Writeable, Writer}; mod sealed { + use prelude::*; use ln::features::Features; /// The context in which [`Features`] are applicable. Defines which features are required and diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 590f95e2..fb0435a0 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -39,9 +39,10 @@ use bitcoin::hash_types::BlockHash; use bitcoin::secp256k1::key::PublicKey; +use prelude::*; use core::cell::RefCell; use std::rc::Rc; -use std::sync::Mutex; +use std::sync::{Arc, Mutex}; use core::mem; use std::collections::HashMap; @@ -148,14 +149,14 @@ fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, s } } node.node.test_process_background_events(); - node.blocks.borrow_mut().push((block.header, height)); + node.blocks.lock().unwrap().push((block.header, height)); } pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) { for i in 0..count { - let orig_header = node.blocks.borrow_mut().pop().unwrap(); + let orig_header = node.blocks.lock().unwrap().pop().unwrap(); assert!(orig_header.1 > 0); // Cannot disconnect genesis - let prev_header = node.blocks.borrow().last().unwrap().clone(); + let prev_header = node.blocks.lock().unwrap().last().unwrap().clone(); match *node.connect_style.borrow() { ConnectStyle::FullBlockViaListen => { @@ -177,7 +178,7 @@ pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32) } pub fn disconnect_all_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>) { - let count = node.blocks.borrow_mut().len() as u32 - 1; + let count = node.blocks.lock().unwrap().len() as u32 - 1; disconnect_blocks(node, count); } @@ -211,15 +212,15 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> { pub network_payment_count: Rc>, pub network_chan_count: Rc>, pub logger: &'c test_utils::TestLogger, - pub blocks: RefCell>, + pub blocks: Arc>>, pub connect_style: Rc>, } impl<'a, 'b, 'c> Node<'a, 'b, 'c> { pub fn best_block_hash(&self) -> BlockHash { - self.blocks.borrow_mut().last().unwrap().0.block_hash() + self.blocks.lock().unwrap().last().unwrap().0.block_hash() } pub fn best_block_info(&self) -> (BlockHash, u32) { - self.blocks.borrow_mut().last().map(|(a, b)| (a.block_hash(), *b)).unwrap() + self.blocks.lock().unwrap().last().map(|(a, b)| (a.block_hash(), *b)).unwrap() } } @@ -295,7 +296,8 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: 253 }, chain_monitor: self.chain_monitor, tx_broadcaster: &test_utils::TestBroadcaster { - txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()) + txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()), + blocks: Arc::new(Mutex::new(self.tx_broadcaster.blocks.lock().unwrap().clone())), }, logger: &test_utils::TestLogger::new(), channel_monitors, @@ -304,7 +306,8 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> { let persister = test_utils::TestPersister::new(); let broadcaster = test_utils::TestBroadcaster { - txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()) + txn_broadcasted: Mutex::new(self.tx_broadcaster.txn_broadcasted.lock().unwrap().clone()), + blocks: Arc::new(Mutex::new(self.tx_broadcaster.blocks.lock().unwrap().clone())), }; let chain_source = test_utils::TestChainSource::new(Network::Testnet); let chain_monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &broadcaster, &self.logger, &feeest, &persister, &self.keys_manager); @@ -1283,7 +1286,10 @@ pub fn fail_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: pub fn create_chanmon_cfgs(node_count: usize) -> Vec { let mut chan_mon_cfgs = Vec::new(); for i in 0..node_count { - let tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}; + let tx_broadcaster = test_utils::TestBroadcaster { + txn_broadcasted: Mutex::new(Vec::new()), + blocks: Arc::new(Mutex::new(vec![(genesis_block(Network::Testnet).header, 0)])), + }; let fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; let chain_source = test_utils::TestChainSource::new(Network::Testnet); let logger = test_utils::TestLogger::with_id(format!("node {}", i)); @@ -1344,7 +1350,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec 0, preimage tx - check_spends!(htlc_pair.0, remote_txn[0]); - assert_eq!(htlc_pair.1.input.len(), 1); - assert_eq!(htlc_pair.1.input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // HTLC 0 <--> 1, timeout tx - check_spends!(htlc_pair.1, remote_txn[0]); + assert_eq!(claim_txn.len(), 8); + assert_eq!(claim_txn[1], claim_txn[4]); + assert_eq!(claim_txn[2], claim_txn[5]); + check_spends!(claim_txn[1], chan_1.3); + check_spends!(claim_txn[2], claim_txn[1]); + check_spends!(claim_txn[7], claim_txn[1]); + + assert_eq!(claim_txn[0].input.len(), 1); + assert_eq!(claim_txn[3].input.len(), 1); + assert_eq!(claim_txn[0].input[0].previous_output, claim_txn[3].input[0].previous_output); + + assert_eq!(claim_txn[0].input.len(), 1); + assert_eq!(claim_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // HTLC 1 <--> 0, preimage tx + check_spends!(claim_txn[0], remote_txn[0]); + assert_eq!(remote_txn[0].output[claim_txn[0].input[0].previous_output.vout as usize].value, 800); + assert_eq!(claim_txn[6].input.len(), 1); + assert_eq!(claim_txn[6].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // HTLC 0 <--> 1, timeout tx + check_spends!(claim_txn[6], remote_txn[0]); + assert_eq!(remote_txn[0].output[claim_txn[6].input[0].previous_output.vout as usize].value, 900); let events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 3); @@ -2306,12 +2318,15 @@ fn channel_monitor_network_test() { // One pending HTLC is discarded by the force-close: let payment_preimage_1 = route_payment(&nodes[1], &vec!(&nodes[2], &nodes[3])[..], 3000000).0; - // Simple case of one pending HTLC to HTLC-Timeout + // Simple case of one pending HTLC to HTLC-Timeout (note that the HTLC-Timeout is not + // broadcasted until we reach the timelock time). nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), true); check_closed_broadcast!(nodes[1], false); check_added_monitors!(nodes[1], 1); { - let mut node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT); + let mut node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::NONE); + connect_blocks(&nodes[1], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + MIN_CLTV_EXPIRY_DELTA as u32 + 1); + test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT); mine_transaction(&nodes[2], &node_txn[0]); check_added_monitors!(nodes[2], 1); test_txn_broadcast(&nodes[2], &chan_2, None, HTLCType::NONE); @@ -2347,7 +2362,9 @@ fn channel_monitor_network_test() { check_closed_broadcast!(nodes[2], false); let node2_commitment_txid; { - let node_txn = test_txn_broadcast(&nodes[2], &chan_3, None, HTLCType::TIMEOUT); + let node_txn = test_txn_broadcast(&nodes[2], &chan_3, None, HTLCType::NONE); + connect_blocks(&nodes[2], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + MIN_CLTV_EXPIRY_DELTA as u32 + 1); + test_txn_broadcast(&nodes[2], &chan_3, None, HTLCType::TIMEOUT); node2_commitment_txid = node_txn[0].txid(); // Claim the payment on nodes[3], giving it knowledge of the preimage @@ -2482,6 +2499,7 @@ fn test_justice_tx() { test_txn_broadcast(&nodes[1], &chan_5, None, HTLCType::NONE); mine_transaction(&nodes[0], &revoked_local_txn[0]); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires // Verify broadcast of revoked HTLC-timeout let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT); check_added_monitors!(nodes[0], 1); @@ -2608,7 +2626,7 @@ fn claim_htlc_outputs_shared_tx() { expect_payment_failed!(nodes[1], payment_hash_2, true); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 3); // ChannelMonitor: penalty tx, ChannelManager: local commitment + HTLC-timeout + assert_eq!(node_txn.len(), 2); // ChannelMonitor: penalty tx, ChannelManager: local commitment assert_eq!(node_txn[0].input.len(), 3); // Claim the revoked output + both revoked HTLC outputs check_spends!(node_txn[0], revoked_local_txn[0]); @@ -2625,13 +2643,6 @@ fn claim_htlc_outputs_shared_tx() { // Next nodes[1] broadcasts its current local tx state: assert_eq!(node_txn[1].input.len(), 1); assert_eq!(node_txn[1].input[0].previous_output.txid, chan_1.3.txid()); //Spending funding tx unique txouput, tx broadcasted by ChannelManager - - assert_eq!(node_txn[2].input.len(), 1); - let witness_script = node_txn[2].clone().input[0].witness.pop().unwrap(); - assert_eq!(witness_script.len(), OFFERED_HTLC_SCRIPT_WEIGHT); //Spending an offered htlc output - assert_eq!(node_txn[2].input[0].previous_output.txid, node_txn[1].txid()); - assert_ne!(node_txn[2].input[0].previous_output.txid, node_txn[0].input[0].previous_output.txid); - assert_ne!(node_txn[2].input[0].previous_output.txid, node_txn[0].input[1].previous_output.txid); } get_announce_close_broadcast_events(&nodes, 0, 1); assert_eq!(nodes[0].node.list_channels().len(), 0); @@ -2735,6 +2746,12 @@ fn test_htlc_on_chain_success() { let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known()); + // Ensure all nodes are at the same height + let node_max_height = nodes.iter().map(|node| node.blocks.lock().unwrap().len()).max().unwrap() as u32; + connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1); + connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1); + connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1); + // Rebalance the network a bit by relaying one payment through all the channels... send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000); send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000); @@ -2776,6 +2793,7 @@ fn test_htlc_on_chain_success() { // Verify that B's ChannelManager is able to extract preimage from HTLC Success tx and pass it backward let header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[1].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; connect_block(&nodes[1], &Block { header, txdata: node_txn}); + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires { let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); @@ -2813,34 +2831,26 @@ fn test_htlc_on_chain_success() { macro_rules! check_tx_local_broadcast { ($node: expr, $htlc_offered: expr, $commitment_tx: expr, $chan_tx: expr) => { { let mut node_txn = $node.tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 5); + assert_eq!(node_txn.len(), 3); // Node[1]: ChannelManager: 3 (commitment tx, 2*HTLC-Timeout tx), ChannelMonitor: 2 (timeout tx) // Node[0]: ChannelManager: 3 (commtiemtn tx, 2*HTLC-Timeout tx), ChannelMonitor: 2 HTLC-timeout - check_spends!(node_txn[0], $commitment_tx); check_spends!(node_txn[1], $commitment_tx); - assert_ne!(node_txn[0].lock_time, 0); + check_spends!(node_txn[2], $commitment_tx); assert_ne!(node_txn[1].lock_time, 0); + assert_ne!(node_txn[2].lock_time, 0); if $htlc_offered { - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); assert!(node_txn[1].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert!(node_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output } else { - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert!(node_txn[1].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + assert!(node_txn[2].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment } - check_spends!(node_txn[2], $chan_tx); - check_spends!(node_txn[3], node_txn[2]); - check_spends!(node_txn[4], node_txn[2]); - assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), 71); - assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[4].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(node_txn[3].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - assert!(node_txn[4].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - assert_ne!(node_txn[3].lock_time, 0); - assert_ne!(node_txn[4].lock_time, 0); + check_spends!(node_txn[0], $chan_tx); + assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), 71); node_txn.clear(); } } } @@ -2851,29 +2861,43 @@ fn test_htlc_on_chain_success() { // Broadcast legit commitment tx from A on B's chain // Broadcast preimage tx by B on offered output from A commitment tx on A's chain - let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2); - check_spends!(commitment_tx[0], chan_1.3); - mine_transaction(&nodes[1], &commitment_tx[0]); + let node_a_commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2); + check_spends!(node_a_commitment_tx[0], chan_1.3); + mine_transaction(&nodes[1], &node_a_commitment_tx[0]); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); - let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 3 (commitment tx + HTLC-Sucess * 2), ChannelMonitor : 1 (HTLC-Success) - assert_eq!(node_txn.len(), 4); - check_spends!(node_txn[0], commitment_tx[0]); - assert_eq!(node_txn[0].input.len(), 2); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[0].input[1].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[0].lock_time, 0); - assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment - check_spends!(node_txn[1], chan_1.3); - assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), 71); - check_spends!(node_txn[2], node_txn[1]); - check_spends!(node_txn[3], node_txn[1]); + let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); + assert_eq!(node_txn.len(), 6); // ChannelManager : 3 (commitment tx + HTLC-Sucess * 2), ChannelMonitor : 3 (HTLC-Success, 2* RBF bumps of above HTLC txn) + let commitment_spend = + if node_txn[0].input[0].previous_output.txid == node_a_commitment_tx[0].txid() { + check_spends!(node_txn[1], commitment_tx[0]); + check_spends!(node_txn[2], commitment_tx[0]); + assert_ne!(node_txn[1].input[0].previous_output.vout, node_txn[2].input[0].previous_output.vout); + &node_txn[0] + } else { + check_spends!(node_txn[0], commitment_tx[0]); + check_spends!(node_txn[1], commitment_tx[0]); + assert_ne!(node_txn[0].input[0].previous_output.vout, node_txn[1].input[0].previous_output.vout); + &node_txn[2] + }; + + check_spends!(commitment_spend, node_a_commitment_tx[0]); + assert_eq!(commitment_spend.input.len(), 2); + assert_eq!(commitment_spend.input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(commitment_spend.input[1].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(commitment_spend.lock_time, 0); + assert!(commitment_spend.output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + check_spends!(node_txn[3], chan_1.3); + assert_eq!(node_txn[3].input[0].witness.clone().last().unwrap().len(), 71); + check_spends!(node_txn[4], node_txn[3]); + check_spends!(node_txn[5], node_txn[3]); // We don't bother to check that B can claim the HTLC output on its commitment tx here as // we already checked the same situation with A. // Verify that A's ChannelManager is able to extract preimage from preimage tx and generate PaymentSent let mut header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[0].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; - connect_block(&nodes[0], &Block { header, txdata: vec![commitment_tx[0].clone(), node_txn[0].clone()] }); + connect_block(&nodes[0], &Block { header, txdata: vec![node_a_commitment_tx[0].clone(), commitment_spend.clone()] }); + connect_blocks(&nodes[0], TEST_FINAL_CLTV + MIN_CLTV_EXPIRY_DELTA as u32 - 1); // Confirm blocks until the HTLC expires check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); let events = nodes[0].node.get_and_clear_pending_events(); @@ -2892,7 +2916,7 @@ fn test_htlc_on_chain_success() { _ => panic!("Unexpected event"), } } - check_tx_local_broadcast!(nodes[0], true, commitment_tx[0], chan_1.3); + check_tx_local_broadcast!(nodes[0], true, node_a_commitment_tx[0], chan_1.3); } fn do_test_htlc_on_chain_timeout(connect_style: ConnectStyle) { @@ -3011,17 +3035,16 @@ fn do_test_htlc_on_chain_timeout(connect_style: ConnectStyle) { check_spends!(commitment_tx[0], chan_1.3); mine_transaction(&nodes[0], &commitment_tx[0]); + connect_blocks(&nodes[0], TEST_FINAL_CLTV + MIN_CLTV_EXPIRY_DELTA as u32 - 1); // Confirm blocks until the HTLC expires check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); - let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 1 timeout tx - assert_eq!(node_txn.len(), 3); - check_spends!(node_txn[0], commitment_tx[0]); - assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[1], chan_1.3); - check_spends!(node_txn[2], node_txn[1]); - assert_eq!(node_txn[1].clone().input[0].witness.last().unwrap().len(), 71); - assert_eq!(node_txn[2].clone().input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 1 commitment tx, ChannelMonitor : 1 timeout tx + assert_eq!(node_txn.len(), 2); + check_spends!(node_txn[0], chan_1.3); + assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), 71); + check_spends!(node_txn[1], commitment_tx[0]); + assert_eq!(node_txn[1].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); } #[test] @@ -3400,11 +3423,13 @@ fn test_htlc_ignore_latest_remote_commitment() { route_payment(&nodes[0], &[&nodes[1]], 10000000); nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap(); + connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + 1); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 2); + assert_eq!(node_txn.len(), 3); + assert_eq!(node_txn[0], node_txn[1]); let mut header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[1].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; connect_block(&nodes[1], &Block { header, txdata: vec![node_txn[0].clone(), node_txn[1].clone()]}); @@ -3414,7 +3439,7 @@ fn test_htlc_ignore_latest_remote_commitment() { // Duplicate the connect_block call since this may happen due to other listeners // registering new transactions header.prev_blockhash = header.block_hash(); - connect_block(&nodes[1], &Block { header, txdata: vec![node_txn[0].clone(), node_txn[1].clone()]}); + connect_block(&nodes[1], &Block { header, txdata: vec![node_txn[0].clone(), node_txn[2].clone()]}); } #[test] @@ -4424,19 +4449,23 @@ fn test_dup_htlc_onchain_fails_on_reload() { nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); + // Connect blocks until the CLTV timeout is up so that we get an HTLC-Timeout transaction + connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + 1); let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0); - assert_eq!(node_txn.len(), 2); + assert_eq!(node_txn.len(), 3); + assert_eq!(node_txn[0], node_txn[1]); assert!(nodes[1].node.claim_funds(payment_preimage)); check_added_monitors!(nodes[1], 1); let mut header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[1].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - connect_block(&nodes[1], &Block { header, txdata: vec![node_txn[0].clone(), node_txn[1].clone()]}); + connect_block(&nodes[1], &Block { header, txdata: vec![node_txn[1].clone(), node_txn[2].clone()]}); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); let claim_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0); - connect_block(&nodes[0], &Block { header, txdata: node_txn}); + header.prev_blockhash = nodes[0].best_block_hash(); + connect_block(&nodes[0], &Block { header, txdata: vec![node_txn[1].clone(), node_txn[2].clone()]}); // Serialize out the ChannelMonitor before connecting the on-chain claim transactions. This is // fairly normal behavior as ChannelMonitor(s) are often not re-serialized when on-chain events @@ -4444,7 +4473,7 @@ fn test_dup_htlc_onchain_fails_on_reload() { let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new()); nodes[0].chain_monitor.chain_monitor.monitors.read().unwrap().iter().next().unwrap().1.write(&mut chan_0_monitor_serialized).unwrap(); - header.prev_blockhash = header.block_hash(); + header.prev_blockhash = nodes[0].best_block_hash(); let claim_block = Block { header, txdata: claim_txn}; connect_block(&nodes[0], &claim_block); expect_payment_sent!(nodes[0], payment_preimage); @@ -4487,7 +4516,8 @@ fn test_dup_htlc_onchain_fails_on_reload() { // Note that if we re-connect the block which exposed nodes[0] to the payment preimage (but // which the current ChannelMonitor has not seen), the ChannelManager's de-duplication of // payment events should kick in, leaving us with no pending events here. - nodes[0].chain_monitor.chain_monitor.block_connected(&claim_block, nodes[0].blocks.borrow().len() as u32 - 1); + let height = nodes[0].blocks.lock().unwrap().len() as u32 - 1; + nodes[0].chain_monitor.chain_monitor.block_connected(&claim_block, height); assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); } @@ -4764,11 +4794,11 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() { nodes_0_deserialized = nodes_0_deserialized_tmp; assert!(nodes_0_read.is_empty()); - { // Channel close should result in a commitment tx and an HTLC tx + { // Channel close should result in a commitment tx let txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(txn.len(), 2); + assert_eq!(txn.len(), 1); + check_spends!(txn[0], funding_tx); assert_eq!(txn[0].input[0].previous_output.txid, funding_tx.txid()); - assert_eq!(txn[1].input[0].previous_output.txid, txn[0].txid()); } for monitor in node_0_monitors.drain(..) { @@ -4987,24 +5017,24 @@ fn test_static_spendable_outputs_timeout_tx() { MessageSendEvent::BroadcastChannelUpdate { .. } => {}, _ => panic!("Unexpected event"), } + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires // Check B's monitor was able to send back output descriptor event for timeout tx on A's commitment tx - let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 3); // ChannelManager : 2 (local commitent tx + HTLC-timeout), ChannelMonitor: timeout tx - check_spends!(node_txn[0], commitment_tx[0].clone()); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[1], chan_1.3.clone()); - check_spends!(node_txn[2], node_txn[1]); + let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0); + assert_eq!(node_txn.len(), 2); // ChannelManager : 1 local commitent tx, ChannelMonitor: timeout tx + check_spends!(node_txn[0], chan_1.3.clone()); + check_spends!(node_txn[1], commitment_tx[0].clone()); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - mine_transaction(&nodes[1], &node_txn[0]); + mine_transaction(&nodes[1], &node_txn[1]); connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1); expect_payment_failed!(nodes[1], our_payment_hash, true); let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000); assert_eq!(spend_txn.len(), 3); // SpendableOutput: remote_commitment_tx.to_remote, timeout_tx.output check_spends!(spend_txn[0], commitment_tx[0]); - check_spends!(spend_txn[1], node_txn[0]); - check_spends!(spend_txn[2], node_txn[0], commitment_tx[0]); // All outputs + check_spends!(spend_txn[1], node_txn[1]); + check_spends!(spend_txn[2], node_txn[1], commitment_tx[0]); // All outputs } #[test] @@ -5063,35 +5093,37 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { mine_transaction(&nodes[0], &revoked_local_txn[0]); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires let revoked_htlc_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(revoked_htlc_txn.len(), 2); - assert_eq!(revoked_htlc_txn[0].input.len(), 1); - assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); - check_spends!(revoked_htlc_txn[1], chan_1.3); + check_spends!(revoked_htlc_txn[0], chan_1.3); + assert_eq!(revoked_htlc_txn[1].input.len(), 1); + assert_eq!(revoked_htlc_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(revoked_htlc_txn[1], revoked_local_txn[0]); + assert_ne!(revoked_htlc_txn[1].lock_time, 0); // HTLC-Timeout // B will generate justice tx from A's revoked commitment/HTLC tx let header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[1].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - connect_block(&nodes[1], &Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }); + connect_block(&nodes[1], &Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[1].clone()] }); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 3); // ChannelMonitor: bogus justice tx, justice tx on revoked outputs, ChannelManager: local commitment tx // The first transaction generated is bogus - it spends both outputs of revoked_local_txn[0] - // including the one already spent by revoked_htlc_txn[0]. That's OK, we'll spend with valid + // including the one already spent by revoked_htlc_txn[1]. That's OK, we'll spend with valid // transactions next... assert_eq!(node_txn[0].input.len(), 3); - check_spends!(node_txn[0], revoked_local_txn[0], revoked_htlc_txn[0]); + check_spends!(node_txn[0], revoked_local_txn[0], revoked_htlc_txn[1]); assert_eq!(node_txn[1].input.len(), 2); - check_spends!(node_txn[1], revoked_local_txn[0], revoked_htlc_txn[0]); - if node_txn[1].input[1].previous_output.txid == revoked_htlc_txn[0].txid() { - assert_ne!(node_txn[1].input[0].previous_output, revoked_htlc_txn[0].input[0].previous_output); + check_spends!(node_txn[1], revoked_local_txn[0], revoked_htlc_txn[1]); + if node_txn[1].input[1].previous_output.txid == revoked_htlc_txn[1].txid() { + assert_ne!(node_txn[1].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output); } else { - assert_eq!(node_txn[1].input[0].previous_output.txid, revoked_htlc_txn[0].txid()); - assert_ne!(node_txn[1].input[1].previous_output, revoked_htlc_txn[0].input[0].previous_output); + assert_eq!(node_txn[1].input[0].previous_output.txid, revoked_htlc_txn[1].txid()); + assert_ne!(node_txn[1].input[1].previous_output, revoked_htlc_txn[1].input[0].previous_output); } assert_eq!(node_txn[2].input.len(), 1); @@ -5204,6 +5236,12 @@ fn test_onchain_to_onchain_claim() { let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known()); + // Ensure all nodes are at the same height + let node_max_height = nodes.iter().map(|node| node.blocks.lock().unwrap().len()).max().unwrap() as u32; + connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1); + connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1); + connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1); + // Rebalance the network a bit by relaying one payment through all the channels ... send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000); send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000); @@ -5237,19 +5275,16 @@ fn test_onchain_to_onchain_claim() { // So we broadcast C's commitment tx and HTLC-Success on B's chain, we should successfully be able to extract preimage and update downstream monitor let header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[1].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; connect_block(&nodes[1], &Block { header, txdata: vec![c_txn[1].clone(), c_txn[2].clone()]}); + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires { let mut b_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - // ChannelMonitor: claim tx, ChannelManager: local commitment tx + HTLC-timeout tx - assert_eq!(b_txn.len(), 3); - check_spends!(b_txn[1], chan_2.3); // B local commitment tx, issued by ChannelManager - check_spends!(b_txn[2], b_txn[1]); // HTLC-Timeout on B local commitment tx, issued by ChannelManager - assert_eq!(b_txn[2].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(b_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - assert_ne!(b_txn[2].lock_time, 0); // Timeout tx - check_spends!(b_txn[0], c_txn[1]); // timeout tx on C remote commitment tx, issued by ChannelMonitor - assert_eq!(b_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert!(b_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment - assert_ne!(b_txn[2].lock_time, 0); // Timeout tx + // ChannelMonitor: claim tx, ChannelManager: local commitment tx + assert_eq!(b_txn.len(), 2); + check_spends!(b_txn[0], chan_2.3); // B local commitment tx, issued by ChannelManager + check_spends!(b_txn[1], c_txn[1]); // timeout tx on C remote commitment tx, issued by ChannelMonitor + assert_eq!(b_txn[1].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert!(b_txn[1].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + assert_ne!(b_txn[1].lock_time, 0); // Timeout tx b_txn.clear(); } check_added_monitors!(nodes[1], 1); @@ -5278,14 +5313,19 @@ fn test_onchain_to_onchain_claim() { let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2); mine_transaction(&nodes[1], &commitment_tx[0]); let b_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - // ChannelMonitor: HTLC-Success tx, ChannelManager: local commitment tx + HTLC-Success tx - assert_eq!(b_txn.len(), 3); - check_spends!(b_txn[1], chan_1.3); - check_spends!(b_txn[2], b_txn[1]); - check_spends!(b_txn[0], commitment_tx[0]); - assert_eq!(b_txn[0].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(b_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment - assert_eq!(b_txn[0].lock_time, 0); // Success tx + // ChannelMonitor: HTLC-Success tx + HTLC-Timeout RBF Bump, ChannelManager: local commitment tx + HTLC-Success tx + assert_eq!(b_txn.len(), 4); + check_spends!(b_txn[2], chan_1.3); + check_spends!(b_txn[3], b_txn[2]); + let (htlc_success_claim, htlc_timeout_bumped) = + if b_txn[0].input[0].previous_output.txid == commitment_tx[0].txid() + { (&b_txn[0], &b_txn[1]) } else { (&b_txn[1], &b_txn[0]) }; + check_spends!(htlc_success_claim, commitment_tx[0]); + assert_eq!(htlc_success_claim.input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert!(htlc_success_claim.output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + assert_eq!(htlc_success_claim.lock_time, 0); // Success tx + check_spends!(htlc_timeout_bumped, c_txn[1]); // timeout tx on C remote commitment tx, issued by ChannelMonitor + assert_ne!(htlc_timeout_bumped.lock_time, 0); // Success tx check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); @@ -5306,11 +5346,20 @@ fn test_duplicate_payment_hash_one_failure_one_success() { let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known()); create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::known(), InitFeatures::known()); + let node_max_height = nodes.iter().map(|node| node.blocks.lock().unwrap().len()).max().unwrap() as u32; + connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1); + connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1); + connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1); + connect_blocks(&nodes[3], node_max_height - nodes[3].best_block_info().1); + let (our_payment_preimage, duplicate_payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 900000); let payment_secret = nodes[3].node.create_inbound_payment_for_hash(duplicate_payment_hash, None, 7200, 0).unwrap(); + // We reduce the final CLTV here by a somewhat arbitrary constant to keep it under the one-byte + // script push size limit so that the below script length checks match + // ACCEPTED_HTLC_SCRIPT_WEIGHT. let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), - &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 900000, TEST_FINAL_CLTV, nodes[0].logger).unwrap(); + &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 900000, TEST_FINAL_CLTV - 40, nodes[0].logger).unwrap(); send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2], &nodes[3]]], 900000, duplicate_payment_hash, payment_secret); let commitment_txn = get_local_commitment_txn!(nodes[2], chan_2.2); @@ -5320,22 +5369,26 @@ fn test_duplicate_payment_hash_one_failure_one_success() { mine_transaction(&nodes[1], &commitment_txn[0]); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 40 + MIN_CLTV_EXPIRY_DELTA as u32 - 1); // Confirm blocks until the HTLC expires let htlc_timeout_tx; { // Extract one of the two HTLC-Timeout transaction let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - // ChannelMonitor: timeout tx * 2, ChannelManager: local commitment tx + HTLC-timeout * 2 - assert_eq!(node_txn.len(), 5); - check_spends!(node_txn[0], commitment_txn[0]); - assert_eq!(node_txn[0].input.len(), 1); + // ChannelMonitor: timeout tx * 3, ChannelManager: local commitment tx + assert_eq!(node_txn.len(), 4); + check_spends!(node_txn[0], chan_2.3); + check_spends!(node_txn[1], commitment_txn[0]); assert_eq!(node_txn[1].input.len(), 1); - assert_ne!(node_txn[0].input[0], node_txn[1].input[0]); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[2], commitment_txn[0]); + assert_eq!(node_txn[2].input.len(), 1); + assert_eq!(node_txn[1].input[0].previous_output, node_txn[2].input[0].previous_output); + check_spends!(node_txn[3], commitment_txn[0]); + assert_ne!(node_txn[1].input[0].previous_output, node_txn[3].input[0].previous_output); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[2], chan_2.3); - check_spends!(node_txn[3], node_txn[2]); - check_spends!(node_txn[4], node_txn[2]); + assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); htlc_timeout_tx = node_txn[1].clone(); } @@ -5353,18 +5406,17 @@ fn test_duplicate_payment_hash_one_failure_one_success() { } let htlc_success_txn: Vec<_> = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); assert_eq!(htlc_success_txn.len(), 5); // ChannelMonitor: HTLC-Success txn (*2 due to 2-HTLC outputs), ChannelManager: local commitment tx + HTLC-Success txn (*2 due to 2-HTLC outputs) - check_spends!(htlc_success_txn[2], chan_2.3); - check_spends!(htlc_success_txn[3], htlc_success_txn[2]); - check_spends!(htlc_success_txn[4], htlc_success_txn[2]); - assert_eq!(htlc_success_txn[0], htlc_success_txn[3]); + check_spends!(htlc_success_txn[0], commitment_txn[0]); + check_spends!(htlc_success_txn[1], commitment_txn[0]); assert_eq!(htlc_success_txn[0].input.len(), 1); assert_eq!(htlc_success_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert_eq!(htlc_success_txn[1], htlc_success_txn[4]); assert_eq!(htlc_success_txn[1].input.len(), 1); assert_eq!(htlc_success_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert_ne!(htlc_success_txn[0].input[0], htlc_success_txn[1].input[0]); - check_spends!(htlc_success_txn[0], commitment_txn[0]); - check_spends!(htlc_success_txn[1], commitment_txn[0]); + assert_ne!(htlc_success_txn[0].input[0].previous_output, htlc_success_txn[1].input[0].previous_output); + assert_eq!(htlc_success_txn[2], commitment_txn[0]); + assert_eq!(htlc_success_txn[3], htlc_success_txn[0]); + assert_eq!(htlc_success_txn[4], htlc_success_txn[1]); + assert_ne!(htlc_success_txn[0].input[0].previous_output, htlc_timeout_tx.input[0].previous_output); mine_transaction(&nodes[1], &htlc_timeout_tx); connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1); @@ -5737,13 +5789,16 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { mine_transaction(&nodes[0], &local_txn[0]); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires let htlc_timeout = { let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn[0]); - node_txn[0].clone() + assert_eq!(node_txn.len(), 2); + check_spends!(node_txn[0], chan_1.3); + assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[1], local_txn[0]); + node_txn[1].clone() }; mine_transaction(&nodes[0], &htlc_timeout); @@ -5785,6 +5840,12 @@ fn test_key_derivation_params() { let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); assert_ne!(chan_0.3.output[0].script_pubkey, chan_1.3.output[0].script_pubkey); + // Ensure all nodes are at the same height + let node_max_height = nodes.iter().map(|node| node.blocks.lock().unwrap().len()).max().unwrap() as u32; + connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1); + connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1); + connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1); + let (_, our_payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000); let local_txn_0 = get_local_commitment_txn!(nodes[0], chan_0.2); let local_txn_1 = get_local_commitment_txn!(nodes[0], chan_1.2); @@ -5803,15 +5864,16 @@ fn test_key_derivation_params() { // Timeout HTLC on A's chain and so it can generate a HTLC-Timeout tx mine_transaction(&nodes[0], &local_txn_1[0]); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); let htlc_timeout = { let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn_1[0]); - node_txn[0].clone() + assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[1], local_txn_1[0]); + node_txn[1].clone() }; mine_transaction(&nodes[0], &htlc_timeout); @@ -7244,12 +7306,14 @@ fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) { if local { // We fail dust-HTLC 1 by broadcast of local commitment tx mine_transaction(&nodes[0], &as_commitment_tx[0]); + connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); + expect_payment_failed!(nodes[0], dust_hash, true); + + connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS - ANTI_REORG_DELAY); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); - timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone()); - connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); - expect_payment_failed!(nodes[0], dust_hash, true); + timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[1].clone()); assert_eq!(timeout_tx[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // We fail non-dust-HTLC 2 by broadcast of local HTLC-timeout tx on local commitment tx assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); @@ -7262,8 +7326,8 @@ fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) { check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); - timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone()); - connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires + timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[1].clone()); if !revoked { expect_payment_failed!(nodes[0], dust_hash, true); assert_eq!(timeout_tx[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); @@ -7620,7 +7684,7 @@ fn test_data_loss_protect() { logger = test_utils::TestLogger::with_id(format!("node {}", 0)); let mut chain_monitor = <(BlockHash, ChannelMonitor)>::read(&mut ::std::io::Cursor::new(previous_chain_monitor_state.0), keys_manager).unwrap().1; chain_source = test_utils::TestChainSource::new(Network::Testnet); - tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}; + tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), blocks: Arc::new(Mutex::new(Vec::new()))}; fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; persister = test_utils::TestPersister::new(); monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &tx_broadcaster, &logger, &fee_estimator, &persister, keys_manager); @@ -7878,7 +7942,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { let feerate_1; { let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 3); // justice tx (broadcasted from ChannelMonitor) + local commitment tx + local HTLC-timeout (broadcasted from ChannelManager) + assert_eq!(node_txn.len(), 2); // justice tx (broadcasted from ChannelMonitor) + local commitment tx assert_eq!(node_txn[0].input.len(), 3); // Penalty txn claims to_local, offered_htlc and received_htlc outputs assert_eq!(node_txn[0].output.len(), 1); check_spends!(node_txn[0], revoked_txn[0]); @@ -7970,31 +8034,27 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { connect_block(&nodes[1], &Block { header, txdata: vec![revoked_local_txn[0].clone()] }); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); + connect_blocks(&nodes[1], 49); // Confirm blocks until the HTLC expires (note CLTV was explicitly 50 above) let revoked_htlc_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(revoked_htlc_txn.len(), 4); - if revoked_htlc_txn[0].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { - assert_eq!(revoked_htlc_txn[0].input.len(), 1); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); - assert_eq!(revoked_htlc_txn[1].input.len(), 1); - assert_eq!(revoked_htlc_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(revoked_htlc_txn[1].output.len(), 1); - check_spends!(revoked_htlc_txn[1], revoked_local_txn[0]); - } else if revoked_htlc_txn[1].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { - assert_eq!(revoked_htlc_txn[1].input.len(), 1); - check_spends!(revoked_htlc_txn[1], revoked_local_txn[0]); - assert_eq!(revoked_htlc_txn[0].input.len(), 1); - assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(revoked_htlc_txn[0].output.len(), 1); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); - } + assert_eq!(revoked_htlc_txn.len(), 3); + check_spends!(revoked_htlc_txn[1], chan.3); + + assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert_eq!(revoked_htlc_txn[0].input.len(), 1); + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); + + assert_eq!(revoked_htlc_txn[2].input.len(), 1); + assert_eq!(revoked_htlc_txn[2].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(revoked_htlc_txn[2].output.len(), 1); + check_spends!(revoked_htlc_txn[2], revoked_local_txn[0]); // Broadcast set of revoked txn on A let hash_128 = connect_blocks(&nodes[0], 40); let header_11 = BlockHeader { version: 0x20000000, prev_blockhash: hash_128, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; connect_block(&nodes[0], &Block { header: header_11, txdata: vec![revoked_local_txn[0].clone()] }); let header_129 = BlockHeader { version: 0x20000000, prev_blockhash: header_11.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - connect_block(&nodes[0], &Block { header: header_129, txdata: vec![revoked_htlc_txn[0].clone(), revoked_htlc_txn[1].clone()] }); + connect_block(&nodes[0], &Block { header: header_129, txdata: vec![revoked_htlc_txn[0].clone(), revoked_htlc_txn[2].clone()] }); expect_pending_htlcs_forwardable_ignore!(nodes[0]); let first; let feerate_1; @@ -8023,7 +8083,7 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { assert_ne!(node_txn[1].input[0].previous_output, node_txn[2].input[0].previous_output); assert_eq!(node_txn[0].input[0].previous_output, revoked_htlc_txn[0].input[0].previous_output); - assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output); + assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[2].input[0].previous_output); // node_txn[3] is the local commitment tx broadcast just because (and somewhat in case of // reorgs, though its not clear its ever worth broadcasting conflicting txn like this when @@ -8034,11 +8094,11 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { // output, checked above). assert_eq!(node_txn[4].input.len(), 2); assert_eq!(node_txn[4].output.len(), 1); - check_spends!(node_txn[4], revoked_htlc_txn[0], revoked_htlc_txn[1]); + check_spends!(node_txn[4], revoked_htlc_txn[0], revoked_htlc_txn[2]); first = node_txn[4].txid(); // Store both feerates for later comparison - let fee_1 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[1].output[0].value - node_txn[4].output[0].value; + let fee_1 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[2].output[0].value - node_txn[4].output[0].value; feerate_1 = fee_1 * 1000 / node_txn[4].get_weight() as u64; penalty_txn = vec![node_txn[2].clone()]; node_txn.clear(); @@ -8057,9 +8117,9 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { check_spends!(node_txn[1], revoked_local_txn[0]); // Note that these are both bogus - they spend outputs already claimed in block 129: if node_txn[0].input[0].previous_output == revoked_htlc_txn[0].input[0].previous_output { - assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output); + assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[2].input[0].previous_output); } else { - assert_eq!(node_txn[0].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output); + assert_eq!(node_txn[0].input[0].previous_output, revoked_htlc_txn[2].input[0].previous_output); assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[0].input[0].previous_output); } @@ -8075,10 +8135,10 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { assert_eq!(node_txn.len(), 1); assert_eq!(node_txn[0].input.len(), 2); - check_spends!(node_txn[0], revoked_htlc_txn[0], revoked_htlc_txn[1]); + check_spends!(node_txn[0], revoked_htlc_txn[0], revoked_htlc_txn[2]); // Verify bumped tx is different and 25% bump heuristic assert_ne!(first, node_txn[0].txid()); - let fee_2 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[1].output[0].value - node_txn[0].output[0].value; + let fee_2 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[2].output[0].value - node_txn[0].output[0].value; let feerate_2 = fee_2 * 1000 / node_txn[0].get_weight() as u64; assert!(feerate_2 * 100 > feerate_1 * 125); let txn = vec![node_txn[0].clone()]; @@ -8132,43 +8192,44 @@ fn test_bump_penalty_txn_on_remote_commitment() { nodes[1].node.claim_funds(payment_preimage); mine_transaction(&nodes[1], &remote_txn[0]); check_added_monitors!(nodes[1], 2); + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires // One or more claim tx should have been broadcast, check it let timeout; let preimage; + let preimage_bump; let feerate_timeout; let feerate_preimage; { let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 5); // 2 * claim tx (broadcasted from ChannelMonitor) + local commitment tx + local HTLC-timeout + local HTLC-success (broadcasted from ChannelManager) + // 9 transactions including: + // 1*2 ChannelManager local broadcasts of commitment + HTLC-Success + // 1*3 ChannelManager local broadcasts of commitment + HTLC-Success + HTLC-Timeout + // 2 * HTLC-Success (one RBF bump we'll check later) + // 1 * HTLC-Timeout + assert_eq!(node_txn.len(), 8); assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(node_txn[6].input.len(), 1); check_spends!(node_txn[0], remote_txn[0]); - check_spends!(node_txn[1], remote_txn[0]); - check_spends!(node_txn[2], chan.3); - check_spends!(node_txn[3], node_txn[2]); - check_spends!(node_txn[4], node_txn[2]); - if node_txn[0].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { - timeout = node_txn[0].txid(); - let index = node_txn[0].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value; - feerate_timeout = fee * 1000 / node_txn[0].get_weight() as u64; - - preimage = node_txn[1].txid(); - let index = node_txn[1].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[1].output[0].value; - feerate_preimage = fee * 1000 / node_txn[1].get_weight() as u64; - } else { - timeout = node_txn[1].txid(); - let index = node_txn[1].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[1].output[0].value; - feerate_timeout = fee * 1000 / node_txn[1].get_weight() as u64; - - preimage = node_txn[0].txid(); - let index = node_txn[0].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value; - feerate_preimage = fee * 1000 / node_txn[0].get_weight() as u64; - } + check_spends!(node_txn[6], remote_txn[0]); + assert_eq!(node_txn[0].input[0].previous_output, node_txn[3].input[0].previous_output); + preimage_bump = node_txn[3].clone(); + + check_spends!(node_txn[1], chan.3); + check_spends!(node_txn[2], node_txn[1]); + assert_eq!(node_txn[1], node_txn[4]); + assert_eq!(node_txn[2], node_txn[5]); + + timeout = node_txn[6].txid(); + let index = node_txn[6].input[0].previous_output.vout; + let fee = remote_txn[0].output[index as usize].value - node_txn[6].output[0].value; + feerate_timeout = fee * 1000 / node_txn[6].get_weight() as u64; + + preimage = node_txn[0].txid(); + let index = node_txn[0].input[0].previous_output.vout; + let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value; + feerate_preimage = fee * 1000 / node_txn[0].get_weight() as u64; + node_txn.clear(); }; assert_ne!(feerate_timeout, 0); @@ -8178,36 +8239,24 @@ fn test_bump_penalty_txn_on_remote_commitment() { connect_blocks(&nodes[1], 15); { let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 2); + assert_eq!(node_txn.len(), 1); assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(preimage_bump.input.len(), 1); check_spends!(node_txn[0], remote_txn[0]); - check_spends!(node_txn[1], remote_txn[0]); - if node_txn[0].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { - let index = node_txn[0].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value; - let new_feerate = fee * 1000 / node_txn[0].get_weight() as u64; - assert!(new_feerate * 100 > feerate_timeout * 125); - assert_ne!(timeout, node_txn[0].txid()); - - let index = node_txn[1].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[1].output[0].value; - let new_feerate = fee * 1000 / node_txn[1].get_weight() as u64; - assert!(new_feerate * 100 > feerate_preimage * 125); - assert_ne!(preimage, node_txn[1].txid()); - } else { - let index = node_txn[1].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[1].output[0].value; - let new_feerate = fee * 1000 / node_txn[1].get_weight() as u64; - assert!(new_feerate * 100 > feerate_timeout * 125); - assert_ne!(timeout, node_txn[1].txid()); - - let index = node_txn[0].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value; - let new_feerate = fee * 1000 / node_txn[0].get_weight() as u64; - assert!(new_feerate * 100 > feerate_preimage * 125); - assert_ne!(preimage, node_txn[0].txid()); - } + check_spends!(preimage_bump, remote_txn[0]); + + let index = preimage_bump.input[0].previous_output.vout; + let fee = remote_txn[0].output[index as usize].value - preimage_bump.output[0].value; + let new_feerate = fee * 1000 / preimage_bump.get_weight() as u64; + assert!(new_feerate * 100 > feerate_timeout * 125); + assert_ne!(timeout, preimage_bump.txid()); + + let index = node_txn[0].input[0].previous_output.vout; + let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value; + let new_feerate = fee * 1000 / node_txn[0].get_weight() as u64; + assert!(new_feerate * 100 > feerate_preimage * 125); + assert_ne!(preimage, node_txn[0].txid()); + node_txn.clear(); } @@ -8418,13 +8467,16 @@ fn test_secret_timeout() { if let Err(APIError::APIMisuseError { err }) = nodes[1].node.create_inbound_payment_for_hash(payment_hash, Some(100_000), 2, 0) { assert_eq!(err, "Duplicate payment hash"); } else { panic!(); } - let mut block = Block { - header: BlockHeader { - version: 0x2000000, - prev_blockhash: nodes[1].blocks.borrow().last().unwrap().0.block_hash(), - merkle_root: Default::default(), - time: nodes[1].blocks.borrow().len() as u32 + 7200, bits: 42, nonce: 42 }, - txdata: vec![], + let mut block = { + let node_1_blocks = nodes[1].blocks.lock().unwrap(); + Block { + header: BlockHeader { + version: 0x2000000, + prev_blockhash: node_1_blocks.last().unwrap().0.block_hash(), + merkle_root: Default::default(), + time: node_1_blocks.len() as u32 + 7200, bits: 42, nonce: 42 }, + txdata: vec![], + } }; connect_block(&nodes[1], &block); if let Err(APIError::APIMisuseError { err }) = nodes[1].node.create_inbound_payment_for_hash(payment_hash, Some(100_000), 2, 0) { @@ -8574,6 +8626,9 @@ fn test_update_err_monitor_lockdown() { watchtower }; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + // Make the tx_broadcaster aware of enough blocks that it doesn't think we're violating + // transaction lock time requirements here. + chanmon_cfgs[0].tx_broadcaster.blocks.lock().unwrap().resize(200, (header, 0)); watchtower.chain_monitor.block_connected(&Block { header, txdata: vec![] }, 200); // Try to update ChannelMonitor @@ -8633,6 +8688,9 @@ fn test_concurrent_monitor_claim() { watchtower }; let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + // Make the tx_broadcaster aware of enough blocks that it doesn't think we're violating + // transaction lock time requirements here. + chanmon_cfgs[0].tx_broadcaster.blocks.lock().unwrap().resize((CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS) as usize, (header, 0)); watchtower_alice.chain_monitor.block_connected(&Block { header, txdata: vec![] }, CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS); // Watchtower Alice should have broadcast a commitment/HTLC-timeout @@ -8779,16 +8837,17 @@ fn test_htlc_no_detection() { chain::Listen::block_connected(&nodes[0].chain_monitor.chain_monitor, &Block { header, txdata: vec![local_txn[0].clone()] }, nodes[0].best_block_info().1 + 1); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); let htlc_timeout = { let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn[0]); - node_txn[0].clone() + assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[1], local_txn[0]); + node_txn[1].clone() }; - let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: nodes[0].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; connect_block(&nodes[0], &Block { header: header_201, txdata: vec![htlc_timeout.clone()] }); connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); expect_payment_failed!(nodes[0], our_payment_hash, true); diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index 3de0595d..7500b93c 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -68,6 +68,7 @@ pub struct PaymentPreimage(pub [u8;32]); #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] pub struct PaymentSecret(pub [u8;32]); +use prelude::*; use bitcoin::bech32; use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, WriteBase32, u5}; diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 94136a9e..eec1a053 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -32,6 +32,7 @@ use bitcoin::hash_types::{Txid, BlockHash}; use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; +use prelude::*; use core::{cmp, fmt}; use core::fmt::Debug; use std::io::Read; @@ -482,6 +483,17 @@ impl Readable for Result { } } +impl Readable for NetAddress { + fn read(reader: &mut R) -> Result { + match Readable::read(reader) { + Ok(Ok(res)) => Ok(res), + Ok(Err(_)) => Err(DecodeError::UnknownVersion), + Err(e) => Err(e), + } + } +} + + /// The unsigned part of a node_announcement #[derive(Clone, Debug, PartialEq)] pub struct UnsignedNodeAnnouncement { @@ -867,6 +879,7 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider { } mod fuzzy_internal_msgs { + use prelude::*; use ln::PaymentSecret; // These types aren't intended to be pub, but are exposed for direct fuzzing (as we deserialize @@ -1841,6 +1854,7 @@ mod tests { use bitcoin::secp256k1::key::{PublicKey,SecretKey}; use bitcoin::secp256k1::{Secp256k1, Message}; + use prelude::*; use std::io::Cursor; #[test] diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs index bab78e7a..3fc01f1b 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -32,6 +32,7 @@ use bitcoin::hashes::Hash; use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::key::SecretKey; +use prelude::*; use core::default::Default; use std::io; diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 07686a21..f80fd676 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -27,6 +27,7 @@ use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::ecdh::SharedSecret; use bitcoin::secp256k1; +use prelude::*; use std::io::Cursor; use core::ops::Deref; @@ -478,6 +479,7 @@ pub(super) fn process_onion_failure(secp_ctx: & #[cfg(test)] mod tests { + use prelude::*; use ln::PaymentHash; use ln::features::{ChannelFeatures, NodeFeatures}; use routing::router::{Route, RouteHop}; diff --git a/lightning/src/ln/peer_channel_encryptor.rs b/lightning/src/ln/peer_channel_encryptor.rs index dd8619bf..76385fc8 100644 --- a/lightning/src/ln/peer_channel_encryptor.rs +++ b/lightning/src/ln/peer_channel_encryptor.rs @@ -7,6 +7,8 @@ // You may not use this file except in accordance with one or both of these // licenses. +use prelude::*; + use ln::msgs::LightningError; use ln::msgs; diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 097e9928..33c4050b 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -30,7 +30,9 @@ use util::events::{MessageSendEvent, MessageSendEventsProvider}; use util::logger::Logger; use routing::network_graph::NetGraphMsgHandler; -use std::collections::{HashMap,hash_map,HashSet,LinkedList}; +use prelude::*; +use alloc::collections::LinkedList; +use std::collections::{HashMap,hash_map,HashSet}; use std::sync::{Arc, Mutex}; use core::sync::atomic::{AtomicUsize, Ordering}; use core::{cmp, hash, fmt, mem}; @@ -1421,6 +1423,7 @@ mod tests { use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::key::{SecretKey, PublicKey}; + use prelude::*; use std::sync::{Arc, Mutex}; use core::sync::atomic::Ordering; diff --git a/lightning/src/ln/reorg_tests.rs b/lightning/src/ln/reorg_tests.rs index f81c42a3..fb316caf 100644 --- a/lightning/src/ln/reorg_tests.rs +++ b/lightning/src/ln/reorg_tests.rs @@ -22,6 +22,7 @@ use util::ser::{ReadableArgs, Writeable}; use bitcoin::blockdata::block::{Block, BlockHeader}; use bitcoin::hash_types::BlockHash; +use prelude::*; use std::collections::HashMap; use core::mem; @@ -101,16 +102,17 @@ fn do_test_onchain_htlc_reorg(local_commitment: bool, claim: bool) { // Give node 1 node 2's commitment transaction and get its response (timing the HTLC out) mine_transaction(&nodes[1], &node_2_commitment_txn[0]); - let node_1_commitment_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_1_commitment_txn.len(), 3); // ChannelMonitor: 1 offered HTLC-Timeout, ChannelManger: 1 local commitment tx, 1 Offered HTLC-Timeout - assert_eq!(node_1_commitment_txn[1].output.len(), 2); // to-local and Offered HTLC (to-remote is dust) - check_spends!(node_1_commitment_txn[1], chan_2.3); - check_spends!(node_1_commitment_txn[2], node_1_commitment_txn[1]); - check_spends!(node_1_commitment_txn[0], node_2_commitment_txn[0]); + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires + let node_1_commitment_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); + assert_eq!(node_1_commitment_txn.len(), 2); // ChannelMonitor: 1 offered HTLC-Timeout, ChannelManger: 1 local commitment tx + assert_eq!(node_1_commitment_txn[0].output.len(), 2); // to-local and Offered HTLC (to-remote is dust) + check_spends!(node_1_commitment_txn[0], chan_2.3); + check_spends!(node_1_commitment_txn[1], node_2_commitment_txn[0]); // Confirm node 2's commitment txn (and node 1's HTLC-Timeout) on node 1 header.prev_blockhash = nodes[1].best_block_hash(); - connect_block(&nodes[1], &Block { header, txdata: vec![node_2_commitment_txn[0].clone(), node_1_commitment_txn[0].clone()] }); + let block = Block { header, txdata: vec![node_2_commitment_txn[0].clone(), node_1_commitment_txn[1].clone()] }; + connect_block(&nodes[1], &block); // ...but return node 2's commitment tx (and claim) in case claim is set and we're preparing to reorg node_2_commitment_txn }; diff --git a/lightning/src/ln/wire.rs b/lightning/src/ln/wire.rs index 532ebbf3..3433d9e1 100644 --- a/lightning/src/ln/wire.rs +++ b/lightning/src/ln/wire.rs @@ -351,6 +351,7 @@ impl Encode for msgs::GossipTimestampFilter { mod tests { use super::*; use util::byte_utils; + use prelude::*; // Big-endian wire encoding of Pong message (type = 19, byteslen = 2). const ENCODED_PONG: [u8; 6] = [0u8, 19u8, 0u8, 2u8, 0u8, 0u8]; diff --git a/lightning/src/routing/network_graph.rs b/lightning/src/routing/network_graph.rs index 16e0a978..4b90cad4 100644 --- a/lightning/src/routing/network_graph.rs +++ b/lightning/src/routing/network_graph.rs @@ -32,12 +32,12 @@ use util::logger::Logger; use util::events::{MessageSendEvent, MessageSendEventsProvider}; use util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK}; +use prelude::*; +use alloc::collections::{BTreeMap, btree_map::Entry as BtreeEntry}; use core::{cmp, fmt}; use std::sync::{RwLock, RwLockReadGuard}; use core::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Mutex; -use std::collections::BTreeMap; -use std::collections::btree_map::Entry as BtreeEntry; use core::ops::Deref; use bitcoin::hashes::hex::ToHex; @@ -459,15 +459,15 @@ impl fmt::Display for DirectionalChannelInfo { } } -impl_writeable!(DirectionalChannelInfo, 0, { - last_update, - enabled, - cltv_expiry_delta, - htlc_minimum_msat, - htlc_maximum_msat, - fees, - last_update_message -}); +impl_writeable_tlv_based!(DirectionalChannelInfo, { + (0, last_update), + (2, enabled), + (4, cltv_expiry_delta), + (6, htlc_minimum_msat), + (8, htlc_maximum_msat), + (10, fees), + (12, last_update_message), +}, {}, {}); #[derive(Clone, Debug, PartialEq)] /// Details about a channel (both directions). @@ -500,15 +500,15 @@ impl fmt::Display for ChannelInfo { } } -impl_writeable!(ChannelInfo, 0, { - features, - node_one, - one_to_two, - node_two, - two_to_one, - capacity_sats, - announcement_message -}); +impl_writeable_tlv_based!(ChannelInfo, { + (0, features), + (2, node_one), + (4, one_to_two), + (6, node_two), + (8, two_to_one), + (10, capacity_sats), + (12, announcement_message), +}, {}, {}); /// Fees for routing via a given channel or a node @@ -521,24 +521,7 @@ pub struct RoutingFees { pub proportional_millionths: u32, } -impl Readable for RoutingFees{ - fn read(reader: &mut R) -> Result { - let base_msat: u32 = Readable::read(reader)?; - let proportional_millionths: u32 = Readable::read(reader)?; - Ok(RoutingFees { - base_msat, - proportional_millionths, - }) - } -} - -impl Writeable for RoutingFees { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - self.base_msat.write(writer)?; - self.proportional_millionths.write(writer)?; - Ok(()) - } -} +impl_writeable_tlv_based!(RoutingFees, {(0, base_msat), (2, proportional_millionths)}, {}, {}); #[derive(Clone, Debug, PartialEq)] /// Information received in the latest node_announcement from this node. @@ -563,48 +546,16 @@ pub struct NodeAnnouncementInfo { pub announcement_message: Option } -impl Writeable for NodeAnnouncementInfo { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - self.features.write(writer)?; - self.last_update.write(writer)?; - self.rgb.write(writer)?; - self.alias.write(writer)?; - (self.addresses.len() as u64).write(writer)?; - for ref addr in &self.addresses { - addr.write(writer)?; - } - self.announcement_message.write(writer)?; - Ok(()) - } -} - -impl Readable for NodeAnnouncementInfo { - fn read(reader: &mut R) -> Result { - let features = Readable::read(reader)?; - let last_update = Readable::read(reader)?; - let rgb = Readable::read(reader)?; - let alias = Readable::read(reader)?; - let addresses_count: u64 = Readable::read(reader)?; - let mut addresses = Vec::with_capacity(cmp::min(addresses_count, MAX_ALLOC_SIZE / 40) as usize); - for _ in 0..addresses_count { - match Readable::read(reader) { - Ok(Ok(addr)) => { addresses.push(addr); }, - Ok(Err(_)) => return Err(DecodeError::InvalidValue), - Err(DecodeError::ShortRead) => return Err(DecodeError::BadLengthDescriptor), - _ => unreachable!(), - } - } - let announcement_message = Readable::read(reader)?; - Ok(NodeAnnouncementInfo { - features, - last_update, - rgb, - alias, - addresses, - announcement_message - }) - } -} +impl_writeable_tlv_based!(NodeAnnouncementInfo, { + (0, features), + (2, last_update), + (4, rgb), + (6, alias), +}, { + (8, announcement_message), +}, { + (10, addresses), +}); #[derive(Clone, Debug, PartialEq)] /// Details about a node in the network, known from the network announcement. @@ -629,36 +580,12 @@ impl fmt::Display for NodeInfo { } } -impl Writeable for NodeInfo { - fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - (self.channels.len() as u64).write(writer)?; - for ref chan in self.channels.iter() { - chan.write(writer)?; - } - self.lowest_inbound_channel_fees.write(writer)?; - self.announcement_info.write(writer)?; - Ok(()) - } -} - -const MAX_ALLOC_SIZE: u64 = 64*1024; - -impl Readable for NodeInfo { - fn read(reader: &mut R) -> Result { - let channels_count: u64 = Readable::read(reader)?; - let mut channels = Vec::with_capacity(cmp::min(channels_count, MAX_ALLOC_SIZE / 8) as usize); - for _ in 0..channels_count { - channels.push(Readable::read(reader)?); - } - let lowest_inbound_channel_fees = Readable::read(reader)?; - let announcement_info = Readable::read(reader)?; - Ok(NodeInfo { - channels, - lowest_inbound_channel_fees, - announcement_info, - }) - } -} +impl_writeable_tlv_based!(NodeInfo, {}, { + (0, lowest_inbound_channel_fees), + (2, announcement_info), +}, { + (4, channels), +}); const SERIALIZATION_VERSION: u8 = 1; const MIN_SERIALIZATION_VERSION: u8 = 1; @@ -1140,6 +1067,7 @@ mod tests { use bitcoin::secp256k1::key::{PublicKey, SecretKey}; use bitcoin::secp256k1::{All, Secp256k1}; + use prelude::*; use std::sync::Arc; fn create_net_graph_msg_handler() -> (Secp256k1, NetGraphMsgHandler, Arc>) { diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 1f77681b..46fe93e7 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -21,8 +21,10 @@ use routing::network_graph::{NetworkGraph, RoutingFees}; use util::ser::{Writeable, Readable}; use util::logger::Logger; +use prelude::*; +use alloc::collections::BinaryHeap; use core::cmp; -use std::collections::{HashMap, BinaryHeap}; +use std::collections::HashMap; use core::ops::Deref; /// A hop in a route @@ -1193,6 +1195,7 @@ mod tests { use bitcoin::secp256k1::key::{PublicKey,SecretKey}; use bitcoin::secp256k1::{Secp256k1, All}; + use prelude::*; use std::sync::Arc; // Using the same keys for LN and BTC ids @@ -3857,8 +3860,8 @@ mod tests { use util::ser::Readable; /// Tries to open a network graph file, or panics with a URL to fetch it. pub(super) fn get_route_file() -> Result { - let res = File::open("net_graph-2021-02-12.bin") // By default we're run in RL/lightning - .or_else(|_| File::open("lightning/net_graph-2021-02-12.bin")) // We may be run manually in RL/ + let res = File::open("net_graph-2021-05-27.bin") // By default we're run in RL/lightning + .or_else(|_| File::open("lightning/net_graph-2021-05-27.bin")) // We may be run manually in RL/ .or_else(|_| { // Fall back to guessing based on the binary location // path is likely something like .../rust-lightning/target/debug/deps/lightning-... let mut path = std::env::current_exe().unwrap(); @@ -3867,7 +3870,7 @@ mod tests { path.pop(); // debug path.pop(); // target path.push("lightning"); - path.push("net_graph-2021-02-12.bin"); + path.push("net_graph-2021-05-27.bin"); eprintln!("{}", path.to_str().unwrap()); File::open(path) }); @@ -3890,7 +3893,7 @@ mod tests { let mut d = match get_route_file() { Ok(f) => f, Err(_) => { - eprintln!("Please fetch https://bitcoin.ninja/ldk-net_graph-05f0c5a0d772-2020-02-12.bin and place it at lightning/net_graph-2021-02-12.bin"); + eprintln!("Please fetch https://bitcoin.ninja/ldk-net_graph-45d86ead641d-2021-05-27.bin and place it at lightning/net_graph-2021-05-27.bin"); return; }, }; @@ -3917,7 +3920,7 @@ mod tests { let mut d = match get_route_file() { Ok(f) => f, Err(_) => { - eprintln!("Please fetch https://bitcoin.ninja/ldk-net_graph-05f0c5a0d772-2020-02-12.bin and place it at lightning/net_graph-2021-02-12.bin"); + eprintln!("Please fetch https://bitcoin.ninja/ldk-net_graph-45d86ead641d-2021-05-27.bin and place it at lightning/net_graph-2021-05-27.bin"); return; }, }; @@ -3945,6 +3948,7 @@ mod benches { use super::*; use util::logger::{Logger, Record}; + use prelude::*; use test::Bencher; struct DummyLogger {} @@ -3955,7 +3959,7 @@ mod benches { #[bench] fn generate_routes(bench: &mut Bencher) { let mut d = tests::get_route_file() - .expect("Please fetch https://bitcoin.ninja/ldk-net_graph-05f0c5a0d772-2020-02-12.bin and place it at lightning/net_graph-2021-02-12.bin"); + .expect("Please fetch https://bitcoin.ninja/ldk-net_graph-45d86ead641d-2021-05-27.bin and place it at lightning/net_graph-2021-05-27.bin"); let graph = NetworkGraph::read(&mut d).unwrap(); // First, get 100 (source, destination) pairs for which route-getting actually succeeds... @@ -3987,7 +3991,7 @@ mod benches { #[bench] fn generate_mpp_routes(bench: &mut Bencher) { let mut d = tests::get_route_file() - .expect("Please fetch https://bitcoin.ninja/ldk-net_graph-05f0c5a0d772-2020-02-12.bin and place it at lightning/net_graph-2021-02-12.bin"); + .expect("Please fetch https://bitcoin.ninja/ldk-net_graph-45d86ead641d-2021-05-27.bin and place it at lightning/net_graph-2021-05-27.bin"); let graph = NetworkGraph::read(&mut d).unwrap(); // First, get 100 (source, destination) pairs for which route-getting actually succeeds... diff --git a/lightning/src/util/chacha20.rs b/lightning/src/util/chacha20.rs index e8c6e229..69e4ed8d 100644 --- a/lightning/src/util/chacha20.rs +++ b/lightning/src/util/chacha20.rs @@ -318,6 +318,7 @@ impl<'a, R: io::Read> io::Read for ChaChaReader<'a, R> { #[cfg(test)] mod test { + use prelude::*; use core::iter::repeat; use super::ChaCha20; diff --git a/lightning/src/util/enforcing_trait_impls.rs b/lightning/src/util/enforcing_trait_impls.rs index 55e45d30..26f9d87b 100644 --- a/lightning/src/util/enforcing_trait_impls.rs +++ b/lightning/src/util/enforcing_trait_impls.rs @@ -11,6 +11,7 @@ use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, HolderCommitment use ln::{chan_utils, msgs}; use chain::keysinterface::{Sign, InMemorySigner, BaseSign}; +use prelude::*; use core::cmp; use std::sync::{Mutex, Arc}; diff --git a/lightning/src/util/errors.rs b/lightning/src/util/errors.rs index b47e134e..ddcc693b 100644 --- a/lightning/src/util/errors.rs +++ b/lightning/src/util/errors.rs @@ -9,6 +9,7 @@ //! Error types live here. +use alloc::string::String; use core::fmt; /// Indicates an error on the client's part (usually some variant of attempting to use too-low or diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index 013e3c4e..650df285 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -23,8 +23,9 @@ use bitcoin::blockdata::script::Script; use bitcoin::secp256k1::key::PublicKey; +use prelude::*; use core::time::Duration; -use std::ops::Deref; +use core::ops::Deref; /// An Event which you should probably take some action in response to. /// diff --git a/lightning/src/util/message_signing.rs b/lightning/src/util/message_signing.rs index 1ad1ea5e..c39da1d5 100644 --- a/lightning/src/util/message_signing.rs +++ b/lightning/src/util/message_signing.rs @@ -20,6 +20,7 @@ //! https://lightning.readthedocs.io/lightning-signmessage.7.html //! https://api.lightning.community/#signmessage +use prelude::*; use crate::util::zbase32; use bitcoin::hashes::{sha256d, Hash}; use bitcoin::secp256k1::recovery::{RecoverableSignature, RecoveryId}; diff --git a/lightning/src/util/poly1305.rs b/lightning/src/util/poly1305.rs index c6dbb43d..73db1577 100644 --- a/lightning/src/util/poly1305.rs +++ b/lightning/src/util/poly1305.rs @@ -205,6 +205,7 @@ impl Poly1305 { #[cfg(test)] mod test { + use prelude::*; use core::iter::repeat; use util::poly1305::Poly1305; diff --git a/lightning/src/util/ser.rs b/lightning/src/util/ser.rs index 66c89aa8..a52ba09c 100644 --- a/lightning/src/util/ser.rs +++ b/lightning/src/util/ser.rs @@ -10,6 +10,7 @@ //! A very simple serialization framework which is used to serialize/deserialize messages as well //! as ChannelsManagers and ChannelMonitors. +use prelude::*; use std::io::{Read, Write}; use std::collections::HashMap; use core::hash::Hash; @@ -222,6 +223,40 @@ pub trait MaybeReadable fn read(reader: &mut R) -> Result, DecodeError>; } +pub(crate) struct OptionDeserWrapper(pub Option); +impl Readable for OptionDeserWrapper { + fn read(reader: &mut R) -> Result { + Ok(Self(Some(Readable::read(reader)?))) + } +} + +const MAX_ALLOC_SIZE: u64 = 64*1024; + +pub(crate) struct VecWriteWrapper<'a, T: Writeable>(pub &'a Vec); +impl<'a, T: Writeable> Writeable for VecWriteWrapper<'a, T> { + fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + (self.0.len() as u64).write(writer)?; + for ref v in self.0.iter() { + v.write(writer)?; + } + Ok(()) + } +} +pub(crate) struct VecReadWrapper(pub Vec); +impl Readable for VecReadWrapper { + fn read(reader: &mut R) -> Result { + let count: u64 = Readable::read(reader)?; + let mut values = Vec::with_capacity(cmp::min(count, MAX_ALLOC_SIZE / (core::mem::size_of::() as u64)) as usize); + for _ in 0..count { + match Readable::read(reader) { + Ok(v) => { values.push(v); }, + Err(e) => return Err(e), + } + } + Ok(Self(values)) + } +} + pub(crate) struct U48(pub u64); impl Writeable for U48 { #[inline] diff --git a/lightning/src/util/ser_macros.rs b/lightning/src/util/ser_macros.rs index 87f990a6..b8119ddd 100644 --- a/lightning/src/util/ser_macros.rs +++ b/lightning/src/util/ser_macros.rs @@ -115,8 +115,12 @@ macro_rules! decode_tlv { _ => {}, } // As we read types, make sure we hit every required type: - $(if (last_seen_type.is_none() || last_seen_type.unwrap() < $reqtype) && typ.0 > $reqtype { - Err(DecodeError::InvalidValue)? + $({ + #[allow(unused_comparisons)] // Note that $reqtype may be 0 making the second comparison always true + let invalid_order = (last_seen_type.is_none() || last_seen_type.unwrap() < $reqtype) && typ.0 > $reqtype; + if invalid_order { + Err(DecodeError::InvalidValue)? + } })* last_seen_type = Some(typ.0); @@ -146,8 +150,12 @@ macro_rules! decode_tlv { s.eat_remaining()?; } // Make sure we got to each required type after we've read every TLV: - $(if last_seen_type.is_none() || last_seen_type.unwrap() < $reqtype { - Err(DecodeError::InvalidValue)? + $({ + #[allow(unused_comparisons)] // Note that $reqtype may be 0 making the second comparison always true + let missing_req_type = last_seen_type.is_none() || last_seen_type.unwrap() < $reqtype; + if missing_req_type { + Err(DecodeError::InvalidValue)? + } })* } } } @@ -246,7 +254,7 @@ macro_rules! write_ver_prefix { /// This is the preferred method of adding new fields that old nodes can ignore and still function /// correctly. macro_rules! write_tlv_fields { - ($stream: expr, {$(($type: expr, $field: expr)),*}, {$(($optional_type: expr, $optional_field: expr)),*}) => { + ($stream: expr, {$(($type: expr, $field: expr)),* $(,)*}, {$(($optional_type: expr, $optional_field: expr)),* $(,)*}) => { encode_varint_length_prefixed_tlv!($stream, {$(($type, $field)),*} , {$(($optional_type, $optional_field)),*}); } } @@ -267,7 +275,7 @@ macro_rules! read_ver_prefix { /// Reads a suffix added by write_tlv_fields. macro_rules! read_tlv_fields { - ($stream: expr, {$(($reqtype: expr, $reqfield: ident)),*}, {$(($type: expr, $field: ident)),*}) => { { + ($stream: expr, {$(($reqtype: expr, $reqfield: ident)),* $(,)*}, {$(($type: expr, $field: ident)),* $(,)*}) => { { let tlv_len = ::util::ser::BigSize::read($stream)?; let mut rd = ::util::ser::FixedLengthReader::new($stream, tlv_len.0); decode_tlv!(&mut rd, {$(($reqtype, $reqfield)),*}, {$(($type, $field)),*}); @@ -275,8 +283,104 @@ macro_rules! read_tlv_fields { } } } +// If we naively create a struct in impl_writeable_tlv_based below, we may end up returning +// `Self { ,,vecfield: vecfield }` which is obviously incorrect. Instead, we have to match here to +// detect at least one empty field set and skip the potentially-extra comma. +macro_rules! _init_tlv_based_struct { + ({}, {$($field: ident),*}, {$($vecfield: ident),*}) => { + Ok(Self { + $($field),*, + $($vecfield: $vecfield.unwrap().0),* + }) + }; + ({$($reqfield: ident),*}, {}, {$($vecfield: ident),*}) => { + Ok(Self { + $($reqfield: $reqfield.0.unwrap()),*, + $($vecfield: $vecfield.unwrap().0),* + }) + }; + ({$($reqfield: ident),*}, {$($field: ident),*}, {}) => { + Ok(Self { + $($reqfield: $reqfield.0.unwrap()),*, + $($field),* + }) + }; + ({$($reqfield: ident),*}, {$($field: ident),*}, {$($vecfield: ident),*}) => { + Ok(Self { + $($reqfield: $reqfield.0.unwrap()),*, + $($field),*, + $($vecfield: $vecfield.unwrap().0),* + }) + } +} + +// If we don't have any optional types below, but do have some vec types, we end up calling +// `write_tlv_field!($stream, {..}, {, (vec_ty, vec_val)})`, which is obviously broken. +// Instead, for write and read we match the missing values and skip the extra comma. +macro_rules! _write_tlv_fields { + ($stream: expr, {$(($type: expr, $field: expr)),* $(,)*}, {}, {$(($optional_type: expr, $optional_field: expr)),* $(,)*}) => { + write_tlv_fields!($stream, {$(($type, $field)),*} , {$(($optional_type, $optional_field)),*}); + }; + ($stream: expr, {$(($type: expr, $field: expr)),* $(,)*}, {$(($optional_type: expr, $optional_field: expr)),* $(,)*}, {$(($optional_type_2: expr, $optional_field_2: expr)),* $(,)*}) => { + write_tlv_fields!($stream, {$(($type, $field)),*} , {$(($optional_type, $optional_field)),*, $(($optional_type_2, $optional_field_2)),*}); + } +} +macro_rules! _read_tlv_fields { + ($stream: expr, {$(($reqtype: expr, $reqfield: ident)),* $(,)*}, {}, {$(($type: expr, $field: ident)),* $(,)*}) => { + read_tlv_fields!($stream, {$(($reqtype, $reqfield)),*}, {$(($type, $field)),*}); + }; + ($stream: expr, {$(($reqtype: expr, $reqfield: ident)),* $(,)*}, {$(($type: expr, $field: ident)),* $(,)*}, {$(($type_2: expr, $field_2: ident)),* $(,)*}) => { + read_tlv_fields!($stream, {$(($reqtype, $reqfield)),*}, {$(($type, $field)),*, $(($type_2, $field_2)),*}); + } +} + +/// Implements Readable/Writeable for a struct storing it as a set of TLVs +/// First block includes all the required fields including a dummy value which is used during +/// deserialization but which will never be exposed to other code. +/// The second block includes optional fields. +/// The third block includes any Vecs which need to have their individual elements serialized. +macro_rules! impl_writeable_tlv_based { + ($st: ident, {$(($reqtype: expr, $reqfield: ident)),* $(,)*}, {$(($type: expr, $field: ident)),* $(,)*}, {$(($vectype: expr, $vecfield: ident)),* $(,)*}) => { + impl ::util::ser::Writeable for $st { + fn write(&self, writer: &mut W) -> Result<(), ::std::io::Error> { + _write_tlv_fields!(writer, { + $(($reqtype, self.$reqfield)),* + }, { + $(($type, self.$field)),* + }, { + $(($vectype, Some(::util::ser::VecWriteWrapper(&self.$vecfield)))),* + }); + Ok(()) + } + } + + impl ::util::ser::Readable for $st { + fn read(reader: &mut R) -> Result { + $( + let mut $reqfield = ::util::ser::OptionDeserWrapper(None); + )* + $( + let mut $field = None; + )* + $( + let mut $vecfield = Some(::util::ser::VecReadWrapper(Vec::new())); + )* + _read_tlv_fields!(reader, { + $(($reqtype, $reqfield)),* + }, { + $(($type, $field)),* + }, { + $(($vectype, $vecfield)),* + }); + _init_tlv_based_struct!({$($reqfield),*}, {$($field),*}, {$($vecfield),*}) + } + } + } +} + #[cfg(test)] mod tests { + use prelude::*; use std::io::{Cursor, Read}; use ln::msgs::DecodeError; use util::ser::{Readable, Writeable, HighZeroBytesDroppedVarInt, VecWriter}; diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index c167c341..60aafd91 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -28,6 +28,7 @@ use bitcoin::blockdata::constants::genesis_block; use bitcoin::blockdata::transaction::{Transaction, TxOut}; use bitcoin::blockdata::script::{Builder, Script}; use bitcoin::blockdata::opcodes; +use bitcoin::blockdata::block::BlockHeader; use bitcoin::network::constants::Network; use bitcoin::hash_types::{BlockHash, Txid}; @@ -36,6 +37,7 @@ use bitcoin::secp256k1::recovery::RecoverableSignature; use regex; +use prelude::*; use core::time::Duration; use std::sync::{Mutex, Arc}; use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; @@ -200,9 +202,18 @@ impl channelmonitor::Persist for TestPersis pub struct TestBroadcaster { pub txn_broadcasted: Mutex>, + pub blocks: Arc>>, } impl chaininterface::BroadcasterInterface for TestBroadcaster { fn broadcast_transaction(&self, tx: &Transaction) { + assert!(tx.lock_time < 1_500_000_000); + if tx.lock_time > self.blocks.lock().unwrap().len() as u32 + 1 && tx.lock_time < 500_000_000 { + for inp in tx.input.iter() { + if inp.sequence != 0xffffffff { + panic!("We should never broadcast a transaction before its locktime ({})!", tx.lock_time); + } + } + } self.txn_broadcasted.lock().unwrap().push(tx.clone()); } } diff --git a/lightning/src/util/transaction_utils.rs b/lightning/src/util/transaction_utils.rs index 34d0fb27..5c02fe15 100644 --- a/lightning/src/util/transaction_utils.rs +++ b/lightning/src/util/transaction_utils.rs @@ -14,6 +14,7 @@ use bitcoin::consensus::encode::VarInt; use ln::msgs::MAX_VALUE_MSAT; +use prelude::*; use core::cmp::Ordering; pub fn sort_outputs Ordering>(outputs: &mut Vec<(TxOut, T)>, tie_breaker: C) { @@ -83,6 +84,8 @@ mod tests { use hex::decode; + use alloc::vec; + #[test] fn sort_output_by_value() { let txout1 = TxOut { diff --git a/lightning/src/util/zbase32.rs b/lightning/src/util/zbase32.rs index e17ac3e7..454fe4b5 100644 --- a/lightning/src/util/zbase32.rs +++ b/lightning/src/util/zbase32.rs @@ -8,6 +8,8 @@ * at your option. */ +use prelude::*; + const ALPHABET: &'static [u8] = b"ybndrfg8ejkmcpqxot1uwisza345h769"; /// Encodes some bytes as a zbase32 string