From 07e5a9ef9fa02db9ca2de5793e39f1f9e39216d4 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Wed, 8 Nov 2017 14:34:11 +0100 Subject: [PATCH] htlc: Allow for exactly min_final_cltv_expiry cltv delta We are announcing that we are willing to accept incoming payments with current_height + min_final_cltv_expiry + slack, assuming that the sender adds some slack. In particular we'd reject the payment if slack=0 which is allowed by the spec. Signed-off-by: Christian Decker --- lightningd/peer_htlcs.c | 4 +-- tests/test_lightningd.py | 62 ++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 691739731..723d47973 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -359,9 +359,9 @@ static void handle_localpay(struct htlc_in *hin, * If the `cltv_expiry` is too low, the final node MUST fail the HTLC: */ if (get_block_height(ld->topology) + ld->config.cltv_final - >= cltv_expiry) { + > cltv_expiry) { log_debug(hin->key.peer->log, - "Expiry cltv %u too close to current %u + %u", + "Expiry cltv too soon %u < %u + %u", cltv_expiry, get_block_height(ld->topology), ld->config.cltv_final); diff --git a/tests/test_lightningd.py b/tests/test_lightningd.py index 1a8846f25..803398984 100644 --- a/tests/test_lightningd.py +++ b/tests/test_lightningd.py @@ -299,7 +299,7 @@ class LightningDTests(BaseLightningDTests): assert b11['description'] == 'description' assert b11['expiry'] == 3600 assert b11['payee'] == l1.info['id'] - + def test_connect(self): l1,l2 = self.connect() @@ -329,9 +329,9 @@ class LightningDTests(BaseLightningDTests): # BOLT #11: # > ### Please make a donation of any amount using payment_hash 0001020304050607080900010203040506070809000102030405060708090102 to me @03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad # > lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w - # + # # Breakdown: - # + # # * `lnbc`: prefix, lightning on bitcoin mainnet # * `1`: Bech32 separator # * `pvjluez`: timestamp (1496314658) @@ -350,13 +350,13 @@ class LightningDTests(BaseLightningDTests): assert b11['description'] == 'Please consider supporting this project' assert b11['expiry'] == 3600 assert b11['payee'] == '03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad' - + # BOLT #11: # > ### Please send $3 for a cup of coffee to the same peer, within 1 minute # > lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuaztrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rspfj9srp - # + # # Breakdown: - # + # # * `lnbc`: prefix, lightning on bitcoin mainnet # * `2500u`: amount (2500 micro-bitcoin) # * `1`: Bech32 separator @@ -382,9 +382,9 @@ class LightningDTests(BaseLightningDTests): # BOLT #11: # > ### Now send $24 for an entire list of things (hashed) # > lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqscc6gd6ql3jrc5yzme8v4ntcewwz5cnw92tz0pc8qcuufvq7khhr8wpald05e92xw006sq94mg8v2ndf4sefvf9sygkshp5zfem29trqq2yxxz7 - # + # # Breakdown: - # + # # * `lnbc`: prefix, lightning on bitcoin mainnet # * `20m`: amount (20 milli-bitcoin) # * `1`: Bech32 separator @@ -405,9 +405,9 @@ class LightningDTests(BaseLightningDTests): # > ### The same, on testnet, with a fallback address mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP # > lntb20m1pvjluezhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfpp3x9et2e20v6pu37c5d9vax37wxq72un98kmzzhznpurw9sgl2v0nklu2g4d0keph5t7tj9tcqd8rexnd07ux4uv2cjvcqwaxgj7v4uwn5wmypjd5n69z2xm3xgksg28nwht7f6zspwp3f9t - # + # # Breakdown: - # + # # * `lntb`: prefix, lightning on bitcoin testnet # * `20m`: amount (20 milli-bitcoin) # * `1`: Bech32 separator @@ -428,12 +428,12 @@ class LightningDTests(BaseLightningDTests): assert b11['payee'] == '03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad' assert b11['fallback']['type'] == 'P2PKH' assert b11['fallback']['addr'] == 'mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP' - + # > ### On mainnet, with fallback address 1RustyRX2oai4EYYDpQGWvEL62BBGqN9T with extra routing info to go via nodes 029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255 then 039e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255 # > lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqqqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqqqqqqq7qqzqfnlkwydm8rg30gjku7wmxmk06sevjp53fmvrcfegvwy7d5443jvyhxsel0hulkstws7vqv400q4j3wgpk4crg49682hr4scqvmad43cqd5m7tf - # + # # Breakdown: - # + # # * `lnbc`: prefix, lightning on bitcoin mainnet # * `20m`: amount (20 milli-bitcoin) # * `1`: Bech32 separator @@ -470,12 +470,12 @@ class LightningDTests(BaseLightningDTests): assert b11['routes'][0][1]['short_channel_id'] == '197637:395016:2314' assert b11['routes'][0][1]['fee'] == 30 assert b11['routes'][0][1]['cltv_expiry_delta'] == 4 - + # > ### On mainnet, with fallback (P2SH) address 3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX # > lnbc20m1pvjluezhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppj3a24vwu6r8ejrss3axul8rxldph2q7z9kmrgvr7xlaqm47apw3d48zm203kzcq357a4ls9al2ea73r8jcceyjtya6fu5wzzpe50zrge6ulk4nvjcpxlekvmxl6qcs9j3tz0469gq5g658y - # + # # Breakdown: - # + # # * `lnbc`: prefix, lightning on bitcoin mainnet # * `20m`: amount (20 milli-bitcoin) # * `1`: Bech32 separator @@ -499,7 +499,7 @@ class LightningDTests(BaseLightningDTests): # > ### On mainnet, with fallback (P2WPKH) address bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4 # > lnbc20m1pvjluezhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppqw508d6qejxtdg4y5r3zarvary0c5xw7kepvrhrm9s57hejg0p662ur5j5cr03890fa7k2pypgttmh4897d3raaq85a293e9jpuqwl0rnfuwzam7yr8e690nd2ypcq9hlkdwdvycqa0qza8 - # + # # * `lnbc`: prefix, lightning on bitcoin mainnet # * `20m`: amount (20 milli-bitcoin) # * `1`: Bech32 separator @@ -507,7 +507,7 @@ class LightningDTests(BaseLightningDTests): # * `p`: payment hash... # * `f`: tagged field: fallback address. # * `pp`: `data_length` (`p` = 1. 1 * 32 + 1 == 33) - # * `q`: 0, so witness version 0. + # * `q`: 0, so witness version 0. # * `qw508d6qejxtdg4y5r3zarvary0c5xw7k`: 160 bits = P2WPKH. # * `h`: tagged field: hash of description... # * `gw6tk8z0p0qdy9ulggx65lvfsg3nxxhqjxuf2fvmkhl9f4jc74gy44d5ua9us509prqz3e7vjxrftn3jnk7nrglvahxf7arye5llphgq`: signature @@ -524,7 +524,7 @@ class LightningDTests(BaseLightningDTests): # > ### On mainnet, with fallback (P2WSH) address bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3 # > lnbc20m1pvjluezhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfp4qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q28j0v3rwgy9pvjnd48ee2pl8xrpxysd5g44td63g6xcjcu003j3qe8878hluqlvl3km8rm92f5stamd3jw763n3hck0ct7p8wwj463cql26ava - # + # # * `lnbc`: prefix, lightning on bitcoin mainnet # * `20m`: amount (20 milli-bitcoin) # * `1`: Bech32 separator @@ -1426,12 +1426,12 @@ class LightningDTests(BaseLightningDTests): # B # / \ # / \ - # A C + # A C # \ / # \ / # D # ``` - # + # # Each advertises the following `cltv_expiry_delta` on its end of every # channel: # @@ -1482,7 +1482,7 @@ class LightningDTests(BaseLightningDTests): 'Received channel_update for channel {}\\(1\\)'.format(c2)]) # BOLT #7: - # + # # If B were to send 4,999,999 millisatoshi directly to C, it wouldn't # charge itself a fee nor add its own `cltv_expiry_delta`, so it would # use C's requested `cltv_expiry` of 9. We also assume it adds a @@ -1510,14 +1510,14 @@ class LightningDTests(BaseLightningDTests): # If A were to send an 4,999,999 millisatoshi to C via B, it needs to # pay B the fee it specified in the B->C `channel_update`, calculated as # per [HTLC Fees](#htlc_fees): - # + # # 200 + 4999999 * 2000 / 1000000 = 10199 - # + # # Similarly, it would need to add the `cltv_expiry` from B->C's # `channel_update` (20), plus C's requested minimum (9), plus 42 for the # "shadow route". Thus the `update_add_htlc` message from A to B would # be: - # + # # * `amount_msat`: 5010198 # * `cltv_expiry`: current-block-height + 20 + 9 + 42 # * `onion_routing_packet`: @@ -1566,7 +1566,7 @@ class LightningDTests(BaseLightningDTests): l2.daemon.wait_for_log('WIRE_GOSSIPCTL_HANDLE_PEER') l3.daemon.wait_for_log('WIRE_GOSSIPCTL_HANDLE_PEER') - + c1 = self.fund_channel(l1, l2, 10**6) c2 = self.fund_channel(l2, l3, 10**6) @@ -1631,9 +1631,9 @@ class LightningDTests(BaseLightningDTests): # Takes 6 blocks to timeout (cltv-final + 1), but we also give grace period of 1 block. bitcoind.rpc.generate(5 + 1) assert not l1.daemon.is_in_log('hit deadline') - bitcoind.rpc.generate(1) + bitcoind.rpc.generate(2) - l1.daemon.wait_for_log('Offered HTLC 0 SENT_ADD_ACK_REVOCATION cltv {} hit deadline'.format(bitcoind.rpc.getblockcount()-1)) + l1.daemon.wait_for_log('Offered HTLC 0 SENT_ADD_ACK_REVOCATION cltv .* hit deadline') l1.daemon.wait_for_log('sendrawtx exit 0') l1.bitcoin.rpc.generate(1) l1.daemon.wait_for_log('-> ONCHAIND_OUR_UNILATERAL') @@ -1668,12 +1668,12 @@ class LightningDTests(BaseLightningDTests): # l1 will drop to chain, not reconnect. l1.daemon.wait_for_log('dev_disconnect: -WIRE_REVOKE_AND_ACK') - # Deadline HTLC expity minus 1/2 cltv-expiry delta (rounded up) (== cltv - 3). ctlv is 5+1. + # Deadline HTLC expiry minus 1/2 cltv-expiry delta (rounded up) (== cltv - 3). ctlv is 5+1. bitcoind.rpc.generate(2) assert not l2.daemon.is_in_log('hit deadline') - bitcoind.rpc.generate(1) + bitcoind.rpc.generate(2) - l2.daemon.wait_for_log('Fulfilled HTLC 0 SENT_REMOVE_COMMIT cltv {} hit deadline'.format(bitcoind.rpc.getblockcount()+3)) + l2.daemon.wait_for_log('Fulfilled HTLC 0 SENT_REMOVE_COMMIT cltv .* hit deadline') l2.daemon.wait_for_log('sendrawtx exit 0') l2.bitcoin.rpc.generate(1) l2.daemon.wait_for_log('-> ONCHAIND_OUR_UNILATERAL')