Thanks for the write-up!
Attributable Failures
I think changing the attr failure encoding to enforce hold_time related attributes isn’t that absolute, routing nodes could manipulate the “protected” encoding to signal lower delays, e.g if we used uint8 hold times then 10001000
could be some slang for 16ms
, and this could break a theoretical floor of 100ms
. The sender of the payment also has to opt-in to this custom value interpretation.
We need to keep in mind that the reporting of the hold times as part of the attributable failures upgrade was just a placeholder that can prove useful in the future. It’s not precise and certainly not reliable. Routing nodes can choose to lie or trim their hold times to make themselves look more attractive, and this inaccuracy would definitely be factored into the sender’s pathfinding/scoring algorithm.
Seems as if we rushed ahead to assume that hold times are going to be the primary attribute to score a node by? This is definitely not covered by attr failure spec and I’m not sure if any discussion has started around how the values would be incorporated into pathfinding feedback.
We could have senders interpret all values below a threshold as if they were the same, so 87ms / 42ms / 99ms
would all be considered as 100ms / 100ms / 100ms
. Routing nodes are free to race to the bottom, but for the majority of the network which defaults to the above behavior it wouldn’t make a difference.
Off path adversary
Doing the LND-style commitment batching (maybe with greater & randomized intervals?) is attractive, but would definitely contribute towards slower payment attempts.
Since the cost of having timing related defenses is equally paid by payment senders, it’s wiser to focus on the data/traffic obfuscation vector. Cover traffic sounds very promising, and can definitely help with muddying the waters for the adversary. This could also be an opt-in feature, controllable by the sender.
A sender-controlled approach could be having a mock path which doesn’t change the commitment tx and follows an onion route which only triggers a mock_add_htlc
message. This way for every real payment there would be X “mock payments” travelling over a somewhat related route, solely for the purpose of misleading the network-level adversary. A node receiving a mock_add_htlc
knows that the only purpose of the message is to forward it to another peer.
Another simple approach could be having empty mock_add_htlc
messages (no onion layers of any kind) with a TTL
field, that nodes along the real payment path optimistically transmit (random receiver and delay included). A node receiving the mock message forwards to another random peer if TTL>0, decreasing the TTL by 1. The longest possible route here could also be a mock_add_htlc
chain triggered by the last hop before the receiver.
All mock/obfuscation related messages should of course have their own processing budget and not interfere with channel related messages that are of higher priority.
On path adversary
I don’t have much to add here, the sender/receiver controlled delays seem to be a very nice angle to tackle the issue.