-
Notifications
You must be signed in to change notification settings - Fork 7
Payment Principles
The sender chooses a random path through the network and creates an appropriate packet according to the SPHINX packet format. In that packet, the sender embeds a transaction that transfers the relay fees required for forwarding the packet along the chosen path to the first node. The protocol then incentivizes that first node to pick only its share of the total relay fees and forward the remaining fees to the next node.
The aim of the payment layer is to reward relay nodes along the path for their forwarding services. As the sender only wants to pay them in case they have indeed forwarded the message to the next hop, there needs to be a way to reach consensus between sender and receiver whether a message has been forwarded to the next hop or not. In case both of them agree that the message has been forwarded as intended, there should be a money transfer towards the relayer.
The two parties may now engage in some sophisticated protocol that minimizes the possible loss in case one of the parties becomes unresponsive. Still, there will always be some fraction of the desired outcome that depends on the very last message of the protocol and withholding that message increases the outcome of one of the parties. It has been shown, that a fair solution of the underlying problem, which is known as the fair exchange problem, requires a trusted third party that acts as an arbiter. Newer research has shown that blockchains can fulfill this task.
Since on-chain operations are not only quite expensive but also take a long time to become final, it is reasonable to interact with the blockchain as rarely as possible. The idea is to switch to so-called optimistic fair exchange. The word optimistic meaning, in the context of that the protocol gets along, if both parties acted honestly and without any action of the arbiter.
Instead of sending the transaction directly to the relayer, the sender encrypts it by using a key that is shared between relayer and next hop. So, whenever a relay node receives a packet and tries to decrypt the embedded transaction, that node needs the key half of the next (subsequent) hop to derive the required decryption key to redeem the embedded transaction. Since the next node is also interested in some compensation for its relaying service, it will only accept, or acknowledge, the reception of a packet in case it includes a valid embedded transaction.
The repeated application of that mechanism along the chosen path yields that the nodes between sender and receiver only get payed if they have forwarded the packet as intended by the sender.
It remains to show that both parties are able to detect bad behavior and that there is a fair mechanism to resolve that dispute. Both aspects are not easy to achieve since the nodes always receive encrypted transactions and the corresponding output only after they have successfully forwarded the packet, so they cannot check whether an embedded transaction contains a valid signature.
For that reason, the protocol gives nodes the opportunity to prove to a smart contract that they have derived the required decryption key correctly and that the key derivation led to an invalid embedded transaction, see a more precise description of that functionality below.
A problem of that mechanism is that it has to deal with a second instance of the fair exchange problem. This is the case because the subsequent node (next hop) will not acknowledge a packet before it receives a packet which includes a valid embedded transaction. That receiving node (next hop) might withhold the acknowledgement of the incoming message. Meaning the sending node (relayer) will not be able to derive the decryption key and not receive compensation for their relaying service. Even worse, the sending node (relayer) would have payed the relay fees from its own staked account without having the opportunity to rebalance the incoming payment channel from the previous sender and the outgoing payment channel to the subsequent node (next hop).
To solve this issue, there must be a way for the relay node to force the downstream node (next hop) to reply with an acknowledgement that includes the required key half to derive the decryption. By doing this, there must be distinction made between the case when the packet has not reached the downstream node due to network problems and the case that the subsequent is withholding the acknowledgement message deliberately. Or, in other words, packet loss should not lead to disadvantages for the subsequent node. Therefore, the protocol gives the relay node the opportunity to withdraw an embedded transaction in case that it has not received an acknowledgement for the message. To do this, the relay node triggers an on-chain function that gives the subsequent node a reasonable amount of time to respond with an acknowledgement before the payment is withdrawn.
In addition to the previous problem it might happen that the subsequent node decides to respond with a wrong acknowledgement. To mitigate this, the creator of the message embeds the hash of the required key half in the packet such that the relayer can easily verify whether the received key half yields to the required decryption key.
Furthermore, the relayer can use an on-chain verifiable challenge-response mechanism that allows the relay node to prove that it has received an incorrect key half. To do this, the relay extracts the hash of the key half, signs it with the node's key pair and forwards it to the subsequent node. This node then checks whether the information embedded in the packet allows that node to derive the requested key half, and if this is the case, the node responds with the requested key half and a signature over the key half and the received challenge. Otherwise, the subsequent node drops the packet.
Upon receiving that response, the relay node checks by comparing the hash values whether the embedded key half matches the requested one. If this is not the case, it call a smart contract with the received response. That smart contract then repeats the verification of the acknowledgement and if it detects that the response is invalid, it punishes the subsequent node for its bad behavior by withdrawing the embedded transaction and burning some amount of the staked money of that party.
Since there are multiple parties engaging in that protocol, it might happen that some of these parties have conflicting interest while others collude to increase their outcome. For that reason, it is necessary to implement a protection against collusion attacks within the protocol.
During the creation of the protocol, the following assumptions have been made:
- the creator of the packet is interested in a correct and privacy-preserving delivery of the packet through the network. For that reason, that node has no incentive to collude with other nodes to harm the delivery through the network. And since, the node itself is the party that has payed for the message delivery, it won't collude with other participants in order to pull out more relay fees as specified in the protocol definition.
- in each path, there is always at least one node on that path that does not collude with the other nodes of that path.
The aim of the protocol is to make it unprofitable for multiple subsequent node to collude in order to grab the remaining money without forwarding it to the next hop. To mitigate this, each payment includes not only the amount of money transferred to the next hop but also a virtual token that flows the path backwards. Once a node tries to close a payment channel for a cashout of the staked money, the managing smart contract will restrict the cashout to the amount of virtual tokens a party has gained the previous protocol executions.
So, each time, a node alters a payment channel in order to transfer money to the next node, it increases the corresponding counter value and signs not only the amount of money that is transferred but also the value of the increased counter. Once the subsequent node aims to close that payment channel, it publishes the latest transaction and the managing smart contract transfers the gained tokens from the account of the previous node the one of that node. And to make sure that this node still owes other nodes money respectively virtual tokens, the smart contract will grant cashouts of the staked money only when all outgoing payment channels are closed - and the counter values of the incoming and outgoing transactions sum up to zero. To make sure that the parties are always able to cashout all of the earned relay fees, they will only accept incoming transactions that increase the counter of the corresponding payment channel appropriately.
This does not prevent nodes along path from grabbing excessive moneies from the incoming embedded transaction, but it makes it unprofitable to do subsequent nodes a favor by sending them transactions with inappropriately increased counter values. Nodes may still do this but they will not be able to cashout the gained relay fees since the sum of the counter values will add up to a value that is unequal to zero.
It may happen that the creator of the packet finds it more attractive to drop the payment to the first node and encrypt a random string instead of a valid transaction. Therefore, the protocol empowers the first node to make the previous node liable in case they detect that decryption of the message leads to an invalid embedded transaction. For that reason, each node need to be able to prove that it has correctly derived the corresponding decryption key.
To be able to do this, the creator of a packet includes the hash value of several intermediate values that are required to derive the decryption. The sender of a transaction then concatenates these values and signs the whole bit string. Once a node detects that a transaction is invalid after it has forwarded it to the next node and that node finally responded with the requested key half, that node takes the intermediate values and uses them to call a smart contract that recomputes the key derivation and checks whether it leads to valid signature. In case these computations reveal that the embedded transaction is invalid, it will subtract not only the requested amount of money from the sender's staked account but also burn some additional amount of coins to punish that bad behavior.