lnpeer: maybe_send_commitment: impl batching updates

This commit is contained in:
SomberNight
2026-03-11 17:04:45 +00:00
parent 93f0452406
commit 7e3af72ad6
2 changed files with 13 additions and 4 deletions
+8 -4
View File
@@ -77,6 +77,7 @@ class Peer(Logger, EventListener):
'query_short_channel_ids', 'reply_short_channel_ids', 'reply_short_channel_ids_end') 'query_short_channel_ids', 'reply_short_channel_ids', 'reply_short_channel_ids_end')
DELAY_INC_MSG_PROCESSING_SLEEP = 0.01 DELAY_INC_MSG_PROCESSING_SLEEP = 0.01
MIN_TIME_BETWEEN_SENDING_COMMITSIGS = 0.05
RECV_GOSSIP_QUEUE_SOFT_MAXSIZE = 2000 RECV_GOSSIP_QUEUE_SOFT_MAXSIZE = 2000
RECV_GOSSIP_QUEUE_HARD_MAXSIZE = 5000 RECV_GOSSIP_QUEUE_HARD_MAXSIZE = 5000
@@ -132,6 +133,7 @@ class Peer(Logger, EventListener):
self.register_callbacks() self.register_callbacks()
self._num_gossip_messages_forwarded = 0 self._num_gossip_messages_forwarded = 0
self._processed_onion_cache = LRUCache(maxsize=100) # type: LRUCache[bytes, ProcessedOnionPacket] self._processed_onion_cache = LRUCache(maxsize=100) # type: LRUCache[bytes, ProcessedOnionPacket]
self._last_commitsig_sent_time = time.monotonic()
def send_message(self, message_name: str, **kwargs): def send_message(self, message_name: str, **kwargs):
assert util.get_running_loop() == util.get_asyncio_loop(), f"this must be run on the asyncio thread!" assert util.get_running_loop() == util.get_asyncio_loop(), f"this must be run on the asyncio thread!"
@@ -1870,10 +1872,12 @@ class Peer(Logger, EventListener):
# if there are no changes, we will not (and must not) send a new commitment # if there are no changes, we will not (and must not) send a new commitment
if not chan.has_pending_changes(REMOTE): if not chan.has_pending_changes(REMOTE):
return False return False
# TODO possible optimisation: we could explicitly allow batching updates we send. e.g.: now = time.monotonic()
# - store timestamp of last "send_commitment" in a field if now - self._last_commitsig_sent_time < self.MIN_TIME_BETWEEN_SENDING_COMMITSIGS:
# - if prev timestamp is recent, early "return False" here # We recently sent "commitment_signed". Delay sending again, to allow batching updates.
# note: no need for a timer to delay "send_commitment", existing htlc_switch polling is sufficient # No need to set a timer, htlc_switch polling will call us again.
return False
self._last_commitsig_sent_time = now
self.logger.info(f'send_commitment. chan {chan.short_channel_id}. ctn: {chan.get_next_ctn(REMOTE)}.') self.logger.info(f'send_commitment. chan {chan.short_channel_id}. ctn: {chan.get_next_ctn(REMOTE)}.')
sig_64, htlc_sigs = chan.sign_next_commitment() sig_64, htlc_sigs = chan.sign_next_commitment()
self.send_message("commitment_signed", channel_id=chan.channel_id, signature=sig_64, num_htlcs=len(htlc_sigs), htlc_signature=b"".join(htlc_sigs)) self.send_message("commitment_signed", channel_id=chan.channel_id, signature=sig_64, num_htlcs=len(htlc_sigs), htlc_signature=b"".join(htlc_sigs))
+5
View File
@@ -734,6 +734,8 @@ class TestPeerDirect(TestPeer):
# note: we don't start peer.htlc_switch() so that the fake htlcs are left alone. # note: we don't start peer.htlc_switch() so that the fake htlcs are left alone.
async def f(): async def f():
p1, p2, w1, w2 = self.prepare_peers(chan_AB, chan_BA) p1, p2, w1, w2 = self.prepare_peers(chan_AB, chan_BA)
p1.MIN_TIME_BETWEEN_SENDING_COMMITSIGS = 0
p2.MIN_TIME_BETWEEN_SENDING_COMMITSIGS = 0
async with OldTaskGroup() as group: async with OldTaskGroup() as group:
await group.spawn(p1._message_loop()) await group.spawn(p1._message_loop())
await group.spawn(p2._message_loop()) await group.spawn(p2._message_loop())
@@ -753,6 +755,8 @@ class TestPeerDirect(TestPeer):
# simulating disconnection. recreate transports. # simulating disconnection. recreate transports.
self.logger.info("simulating disconnection. recreating transports.") self.logger.info("simulating disconnection. recreating transports.")
p1, p2, w1, w2 = self.prepare_peers(chan_AB, chan_BA) p1, p2, w1, w2 = self.prepare_peers(chan_AB, chan_BA)
p1.MIN_TIME_BETWEEN_SENDING_COMMITSIGS = 0
p2.MIN_TIME_BETWEEN_SENDING_COMMITSIGS = 0
for chan in (chan_AB, chan_BA): for chan in (chan_AB, chan_BA):
chan.peer_state = PeerState.DISCONNECTED chan.peer_state = PeerState.DISCONNECTED
async with OldTaskGroup() as group: async with OldTaskGroup() as group:
@@ -1607,6 +1611,7 @@ class TestPeerDirect(TestPeer):
payment_hash=lnaddr.paymenthash, payment_hash=lnaddr.paymenthash,
min_final_cltv_delta=lnaddr.get_min_final_cltv_delta(), min_final_cltv_delta=lnaddr.get_min_final_cltv_delta(),
payment_secret=lnaddr.payment_secret) payment_secret=lnaddr.payment_secret)
await p2.received_commitsig_event.wait()
# alice closes # alice closes
await p1.close_channel(alice_channel.channel_id) await p1.close_channel(alice_channel.channel_id)
gath.cancel() gath.cancel()