How do trustlines operate in GEO Protocol?
In our previous article, we described the GEO node’s trustline-related database structure in detail. We encourage you to read it first, so can better understand the actual trustline operation mechanics described in this article. Alternatively, you can simply refer to that article while reading this one, when you see a reference to database tables and fields.
We will now consider the actual trustline operation processes, which include opening, setting, and closing a trustline, as well as changing it during the course of payment operations.
But before we start, we need to make a small but important remark. It might seem that a trustline is a single entity, but from a technical point of view, it is a bit more complicated. First, there is a communication channel that enables all the operations with a trustline, bears communication cryptography etc. And second, there is a trustline itself, which is essentially a set of basic numbers: Incoming Trust Amount (ITA), Outgoing Trust Amount (OTA), and Current Balance (CB). The trustline also contains a part of the cryptography responsible for ensuring trustline data integrity. That’s why, before opening an actual trustline, we need to open a communication channel.
Opening a communication channel
First of all, a communication channel between two nodes must be open, that will allow these nodes to open any number of trustlines between them in different equivalents.
Suppose node A wants to open a channel to node B. To do so, node A has to know B’s GEO node address. This could be obtained in several different ways outside the protocol, so we won’t describe them here.
Then node A calls the command to open the communication channel to node B. During the course of this, an entry that contains information about node B is created and recorded in the contractors table of node’s A database. And the result of this command will be a generated cryptographic secret key that node A has to pass to node B in this or some other way (there are several possible options to do so, which won’t be described here).
Note that, in the course of the secret key exchange process, A and B also exchange each other’s identification values (since each node has its own identification sequence number with which it identifies its counterparty). These values will be recorded into the id_on_contractor_side field of each node’s trustlines table.
Having received this secret key, node B creates a similar set of entries about its counterparty and the trustline and records them into its own database. After that, B sends a confirmation to A encrypted with the secret key that it has just received. In fact, from this moment on all communication between these two nodes will be encrypted with this secret key.
Opening a trustline
A trustline can be opened only if a communication channel (see above) is already opened between these two nodes. A single trustline can be opened in only one equivalent.
To open a trustline, the user of node A has to call a command. The command must contain the contractor’s ID and an equivalent in which this trustline will perform its transactions.
As a result of this command, node A creates an entry in the trustlines table that will be linked to the trustline contractor (the node B). The relevant information about the contractor is stored in the contractors table.
After that, A generates a particular number of Lamport key pairs (this number is 1024 by default but could be changed in the node’s configuration), saves them into the own_keys table with the link to the newly created trustline, and marks all these keys as valid. After that, A sends all the public keys to node B and waits for the confirmation. It is worth mentioning that each key is sent with a separate message.
From this point, every private key will be used only once to sign every new data set, and after that will be marked as invalid. For the counterparty to be able to check the sender’s signature validity, the sender must submit a sequence number pertaining to its key pair along with the signature, so the recipient can use the correct corresponding public key to validate it. After the check has been performed, the recipient also marks the used public key of the sender as invalid.
Node B gets A’s first public keys and performs an operation of trustline creation on its side (which is similar to that described above), stores the key in its contractor_keys table and waits for the rest of the keys. When node B gets all of A’s keys, it performs a similar key generation and exchange process.
After the mutual key generation and exchange are complete, A forms an initial audit, signs it with the first valid key from its key pool, and submits the audit to B. ITA, OTA, and CB values equal zero in the initial audit.
Also, the initial audit contains the address hash of the network-wide Registry of Equivalents, so that both nodes can be sure that the equivalent ID from the registry they are using corresponds to the same actual equivalent. If the address does not match for both nodes, the trustline cannot be opened (see the “How the GEO Protocol’s trustline-related database is organized” article).
As node B gets the initial audit, it checks its data, as well as A’s signature, for validity. If everything is okay, B signs the same audit with its private key, stores it and sends it back to A. At node’s B side, the trustline opening is now concluded, so B changes its state from “Init” to “Active”.
As node A gets the response from B, it performs similar checks, stores the audit in case of success, and sets the trustline’s status to “Active” as well.
Note that payments and trustline changing operations are possible only when the trustline’s state is set to “Active”.
That concludes the trustline’s opening sequence.
Operations with a trustline
In fact, all a particular node can do with a trustline is to change (increase or decrease, including decreasing it down to 0) its outgoing trust (OTA), and to close its incoming trust (ITA), rejecting the incoming trust. Despite the different economic meanings, all of these operations are done in a similar way. Now we’ll move on and describe the mechanics.
The node that initiates an operation with a trustline first of all records the changes to the ITA and/or OTA values (depending on current TL balance) on its own side. Then it sends all three values (ITA, OTA, CB) with its signature to its trustline counterparty. The other node checks the sender’s signature, and if it is okay, changes its own corresponding values to the new ones that it just received before sending its signature back to the initiator. When the first node gets the reply, it knows that the new values are accepted (the audit is complete).
We just want to stress here that in the course of operations with a trustline, a node can only make any changes to its OTA, a particular change to its ITA (close it), and no change to CB, since Current Balance can be changed only as a result of a payment (see below). Technically, of course, a node can make any changes to its own database, even changes to the Current Balance, but (and this is really important) due to the two-sided validation procedure, a one-sided change would be rejected by the counterparty node on the same trustline.
Now it’s time to explain what an audit is and when it happens.
Essentially, an audit is the current state fixation of the three basic trustline properties: ITA, OTA, CB. This fixation is complete when both sides have signed it. Along with this data, an audit also contains a sequence number (stored in the number field of the audits table) that is the same for both trustline counterparties. Also, it contains the Registry of Equivalents address hash.
During an audit process, a trustline’s status is set to “AuditPending” (see the How the GEO Protocol’s trustline-related database is an organized article).
An audit is performed in the following three cases:
- During a trustline opening process (initial audit).
- When a change to a trustline occurs.
- And/or when triggered by an audit rule.
Audit rules are connected with payments. Every node can set its own audit rule for each of its trustlines.
These rules could be the following:
- Time is up: a certain time period could be set and an audit will be performed at the end of this period.
- The number of payment transactions is reached: a user can set a certain number of payment transactions and an audit will be performed after the number is reached.
- The total sum of outgoing payment receipts exceeds the Outgoing Trust Amount or the total sum of incoming payment receipts exceeds the Incoming Trust Amount.
Now, for a better understating of what the audit is, how it is done, and what audit rules are, we will consider an example. In this example, we will also explain how the Current Balance is calculated since an audit is directly related to this particular trustline property.
While ITA and OTA are not dependent on any other trustline component (since they are user-defined), the Current Balance (CB) value is calculated by adding all incoming receipt values and deducting all outgoing receipt values to and from the value of the last signed audit’s CB.
CB = CBa + ΣIRP — ΣOPR
CBa — value of the last signed audit’s CB
IRP — incoming payment receipts
OPR — outgoing payment receipts
Suppose node A opens a trustline channel to node B (Fig. 1). Initially all values of all the properties of both sides of this trustline equal 0, and the audit number is also 0 (see the Opening a trustline channel section above).
Now, node B opens a trustline for 100 units (Fig. 2). So its OTA value becomes 100, and the ITA value of node A becomes 100 as well. This action triggers an audit that fixes the current state of the trustline properties.
Also, one of the nodes sets a second audit rule with a value of three transactions.
Now node A makes a payment of 50 units to node B (Fig. 3). This will be reflected in entries in the outgoing_payment_receipts table of node A, as well as in the incoming_payment_receipts table of node B.
As you can see, the Current Balance hasn’t changed yet. But this means that it is still unchanged in the database, and will remain so until the next audit is done. However, for the end user and for other internal processes the CB value will be immediately shown as up-to-date, calculated according to the above-mentioned formula.
So, in our case, the CB of node A will be:
CB = 0 + 0–50 = -50
and CB for node B will be:
CB = 0 + 50–0 = 50
That means that node B now has the possibility of paying to node A within a limit of 50 units (despite the fact that there is no Incoming Trust Amount for B, but such payment is made possible because now B owes A 50 units on this trustline).
So, node B uses this possibility by repaying 20 units to A (Fig. 4). Now we have a new receipt for 20 units in the incoming_payment_receipts table of node A, and another 20 units receipt in the outgoing_payment_receiptstable of node B.
And here are the new current CB values for the nodes:
CB = 0 + 20–50 = -30 (for node A)
CB = 0 + 50–20 = 30 (for node B)
And now we have another payment of 60 units from A to B that will also be reflected in the payment receipt tables accordingly. And the current CB value of the nodes will be:
CB = 0 + 20 — (50 + 60) = -90 (for node A)
CB = 0 + (50+60) — 20 = 90 (for node B)
Now, we can see that we have three transactions. That means the set audit rule (see above) must be triggered.
An audit means a final Current Balance calculation according to the formula, signing the resulting value of CB, as well as the current values of ITA and OTA by both parties, and storing all of this data in the database.
The audit also allows us to drop all the receipts that were used for the latest CB calculation, i.e. previous records from the incoming_payment_receiptsand outgoing_payment_receipts tables that were accumulated since the latest audit (Fig. 6).
Finally, we will do another payment to demonstrate how the new CB value is calculated based on a non-zero previous CB value.
So, B pays 70 units to A. Here’s how it will affect the values:
CB = -90 + 70–0 = -20 (for node A)
CB = 90 + 0–70 = 20 (for node B)
As we mentioned above, a node generates a particular number of Lamport key pairs during the trustline channel opening process. In the course of its work, a node constantly uses these keys (for signing receipts and audits).
When a node’s number of unused own keys reaches a critical number (three by default), the process for new own key pool generation is initiated. It consists of the following actions:
- Node marks all remaining unused own private keys as invalid.
- It generates a new set of key pairs (1024 key pairs by default) and saves them into its own_keys table.
- Sends the public key from the first newly generated pair to the counterparty of this particular trustline, and waits for confirmation.
- Having received the confirmation, it repeats action 3 for the next generated key until it sends all of them.
The contractor on its side performs the following actions:
- Having received the first message with the new key, it marks all remaining public keys of its contractor as invalid.
- Saves the received contractor’s public key into its the contractor_keystable.
- Sends the confirmation to the trustline counterparty about the key receipt.
- Repeats action 2 and 3 for every subsequent key it receives.
If for some reason the new key pool generation automation wasn’t triggered, a node could use all its keys from the current pool. So, it won’t be able to make any new changes and/or payments on this trustline. In this case, the user has the ability to launch the needed key pool generation command manually.
When a cryptography check is performed (during an action like an audit, for instance) a situation could happen where the check fails (for instance, when audit data is incorrect or a signature is invalid). We call this a conflict. In this case, the trustline state is changed to “ConflictResolving”.
A node that finds such a discrepancy initiates a conflict resolving process. It consists of the following actions:
- Node synchronizes the trustline’s data that is stored in its operative memory with the relevant data from its database.
- It forms a message that contains all the data relevant to the current audit: it is the audit itself and all corresponding debt receipts. Then it sends the message to its contractor on this trustline.
- Having received this message, the contractor node also synchronizes its operative memory with its own database.
- Then the contractor compares its own data with the data that it just got from its counterparty, in a bid to figure out the source of the conflict.
- When the conflict source is identified, it tries to judge whose data is correct.
- Variant 1: If the receiving node decides that the sending node data is correct, then it implements this data version on its side and sends back the confirmation. Variant 2: Otherwise, it sends back its own version of the data.
- If the sending node gets the confirmation (see step 6, variant 1), the conflict is resolved. The trustline state is changed back to “Active”. If it gets the new data (see step 6, variant 2), it tries to perform its correctness check. If the data is correct, it implements it and sends the confirmation to its counterparty. Otherwise the trustline state changes to “Conflict”. The “Conflict” state can only be resolved outside of the protocol.
Closing a trustline
Closing a trustline essentially means that all three of its basic properties — ITA, OTA, CB — equal 0, and this state is confirmed by an audit. Now let’s discuss how this could happen.
Every user can only close two of these properties: ITA and/or OTA. Both of these properties could be closed by one of the two parties, or by both of them. But even if Incoming and Outgoing Trust Amounts are closed (equal 0), a trustline could remain active if the Current Balance (CB) is anything other than 0. In this case, the trustline will continue to function until the payments and/or possible clearing cycles bring it to 0 (the outstanding balance will be repaid in this or another way).
So, when all three trustline properties equal 0, the trustline state will be set to “Archived”, but the trustline channel won’t be deleted from the database. It will only contain data for the last audit. Thus, if the two users want to renew this trustline, the channel will be there already, so there will be no need to create it again.
Now you should know how trustlines in GEO Protocol operate. Our next articles will describe the procedures that should be performed before the payment can be completed.
If you who like watching more than reading, Dima Chizhevsky will explaining all this in the video on our YouTube channel: