ptarmigan
ptarmigan copied to clipboard
Message Retransmission
#525
再接続の要件と実装については再確認すること。
#525 と同じ状況を、c-lightningを相手にして確認した。
c-lightningはcommitment_signed
を送信した方になるが、再接続時に同じcommitment_signed
を再送してきた。
BOLT仕様に明記されていない動作のように思うが、どうなのだろうか?
- ptarmiganがc-lightningに送金し、
commitment_signed
受信によってabort() - 再接続し、
channel_reestablish
送信- [ptarm]next_local_commitment_number: 7 / next_remote_revocation_number: 7
- [cln]next_local_commitment_number: 8 / next_remote_revocation_number: 6
- [cln]前回ptarmが受信に失敗した
commitment_signed
を再送
上記のログ fail_comsig_log.zip
BOLT#02の、一番下が該当すると思われる。
A node:
- MUST NOT assume that previously-transmitted messages were lost,
- if it has sent a previous
commitment_signed
message:- MUST handle the case where the corresponding commitment transaction is
broadcast at any time by the other side,
- Note: this is particularly important if the node does not simply
retransmit the exact
update_
messages as previously sent.
- Note: this is particularly important if the node does not simply
retransmit the exact
- MUST handle the case where the corresponding commitment transaction is
broadcast at any time by the other side,
- if it has sent a previous
- upon reconnection:
- if it has sent a previous
shutdown
:- MUST retransmit
shutdown
.
- MUST retransmit
- if it has sent a previous
該当するのか、よくわからなくなってきた。 c-lightningにissueで確認中。
commitment_signed
は再送とは呼ばない再送を行うと判断した。
commitment numberが不一致の場合の commitment_signed の再送受信には対応したが、再送ができていない。 unilateral closeしてしまっている。
理想型
- regtest
- node
- our node[funder]
- disconnect if node receive
commitment_signed
- disconnect if node receive
- their[fundee]
- normal
- our node[funder]
- already channel established
1. (disconnect after established)
2. connect
3. exchange `init`
4. exchange `channel_reestablish`
* `next_local_commitment_number`: 1
* `next_remote_revocation_number`: 0
5. `./cli/lightning-cli invoice`
6. [our --> their]`update_add_htlc`
7. [our --> their]`commitment_signed`
8. [their --> our]`revoke_and_ack`
9. [their --> our]`commitment_signed`
10. ★ our node disconnect before processing `commitment_signed`
11. connect
12. exchange `init`
13. exchange `channel_reestablish`
* our node send:
* `next_local_commitment_number`: 1
* `next_remote_revocation_number`: 1
* their send:
* `next_local_commitment_number`: 2
* `next_remote_revocation_number`: 0
14. [their --> our]`commitment_signed`
15. [our-->their]`revoke_and_ack`
16. [their --> our]`update_fulfill_htlc`
17. [their --> our]`commitment_signed`
18. [our-->their]`revoke_and_ack`
19. [our-->their]`commitment_signed`
20. [their --> our]`revoke_and_ack`
#618 も類件ではあるが、commitment_signed
の再送はおこなっているので、closeでよい。
commitment_signed
/ revoke_and_ack
交換を4状態に分け、状態2以降であればどちらか片方でもirrevocably committedになっているので再送などを行う。
- 安定
- 状態1:
update_add_htlc
側がcommitment_signed
を送信後 - 状態2: それに対して
revoke_and_ack
返信後 - 状態3: 続けて
commitment_signed
送信後 - 安定: それに対して
revoke_and_ack
送信後
もっと汎用的な見分け方はできないだろうか? P2Pなのにシーケンスに依存しすぎている気がする。
もう1つ。
状態1から元に戻す場合、HTLCのid
をどこに戻して良いのかが簡単に決められそうな感じがしていない。
DBに保存すれば可能なのか? それとも前回の「状態」という考え方を見直す必要があるのか?