lnpeer: maybe_send_commitment: impl batching updates
This commit is contained in:
+8
-4
@@ -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))
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user