The 1Money Protocol
Last updated
Last updated
The 1Money Network is built on a unique messaging based consensus protocol that enables instant payments at scale. Its core design features Byzantine Consistent Broadcast (BCB) to ensure consistency and validity of messages underpinned by a Byzantine Fault Tolerant (BFT) system. The protocol enables horizontal node level sharding that scales with each additional node as well as hardware improvements over time.
Transactions process within milliseconds with instant finality, while offering advantages in terms of security over traditional blockchains.
The protocol has a built-in governance mechanism that provides for committee-based validator sets to update validator sets, fee setting, and account compliance rulesets. Governance updates can be formed with each epoch that consists of a series of checkpoints set by a quorum of permissioned validators. Each checkpoint consists of a set of transactions, that are persisted in memory for the duration of the checkpoint.
Certificates, signed by quorums, are used to authenticate and verify information within the network. Both identifiable and anonymous aggregation techniques can be used to create certificates, with each approach offering distinct advantages in terms of monitoring and performance.
With the fundamental assumption that a majority of permissioned validators (more than two-thirds) will always adhere to the protocol's rules, the protocol also addresses limitations of existing broadcast-based systems, including liveness vulnerabilities and fixed validator sets.
This section covers how payment and other features such as processing a payment, minting/burning, checkpoints, and collecting transaction fees work.
A committee or a set of validators or nodes (we use these terms interchangeably) is always valid for an epoch. We make the standard assumption that > 2/3 of the validators in any epoch are always correct in adhering to the protocol. We index epochs by e, we refer to the validator set for an epoch as Ve and the maximum allowed number of faulty nodes as fe, or f where the context is clear. We refer to any subset of at least 2fe+1 validators for an epoch as a quorum, and any subset of at least fe+1 validators as a sub-quorum. We generally use the term certificate to refer to any message that includes signatures by a quorum of validators for the contents of the message. In the context of creating certificates, we talk about aggregating signatures in general. In practice, one can distinguish between identifiable aggregation, which allows identifying the validators who contributed to a certificate, and anonymous aggregation, which does not.
Payment transaction sends native token funds from the sender to a list of recipients
Sign: A sender initiates a payment by creating and signing a payment message.
Broadcast: The sender, or anyone on their behalf, sends the signed payment message to all validators.
Countersign: Validators who receive a payment message verify that it is valid:
It must be correctly formatted.
The nonce must be exactly one greater than the last nonce.
The account must have a sufficient balance to pay for all amounts sent plus all transaction fees, according to the governance certificate for the current epoch.
If the message is valid, and no other transactions with the same nonce by that sender are currently stored as pending, the validator signs the message and together with the current checkpoint ID and epoch ID, and sends it back to the sender.
Signed transactions and transactions with an insufficient amount or a too high nonce are stored in [Pending
].
If nodes see a too high nonce, they query random other nodes to confirm whether they have missed any transactions.
Finalize: The message is final as soon as the sender, or anyone, sees a quorum of signatures. They aggregate the signatures, creating a payment certificate and send it to all validators.
Accept: Validators accept a payment when they see a certificate. They add it to their Transactions
array. Record the effects of the payment and the transaction fees in their Accounts
. If they had previously stored the message as pending, they remove the pending message.
Minting and burning the native token takes the same form as regular payment transactions. Mint transactions are payments where P.Sender == G.Mint
and burn transactions are payments where P.Recipients[i] == G.Mint
for some i
. The processing of mint and burn transaction differs from regular payments in that the balance of the mint wallet is always zero, so burn transactions do not increase it and mint transactions of any amounts are valid despite the balance being zero. No transaction fees are deducted or distributed to validators for mint and burn transactions.
In a checkpoint, validators collectively agree on the current system state. This agreement allows them to discard older transactions from their memory, preventing storage requirements from growing indefinitely.
This concept is akin to a 'consistent global snapshot' in literature, but our system introduces additional complexities. These complexities arise from the asynchronous nature of our payment system, the need for payment finality to be independent of consensus mechanisms, and the potential for changes in validator committees.
Initiate: Any node observing that length of the [Transactions
] array in its local state matches G.MinTxToCheckpoint
for the current epoch creates a checkpoint proposal. It signs the hash of [Transactions
] concatenated with the current checkpoint and epoch IDs. It sends this signed proposal to all validators, including transactions it signed but lack certificates. The node stops signing with the current checkpoint ID and seamlessly transitions to the next.
Propose: A node who has not yet sent out a checkpoint proposal and receives the first such proposal first verifies it for syntactical correctness: at least G.MinTxToCheckpoint
transactions; Increments the last checkpoint ID by one; and Includes only transactions with correct certificates and IDs up to the last checkpoint. They then creates the union set of the transactions in its own [Transactions
] array and of those in the received proposal. This becomes its own version of [Transactions’
], for which it sends out its own signed proposal. In the first proposal, validators also include a copy of each transaction they have signed, but for which they have not yet seen a certificate
Re-propose: Nodes continuously monitor and process incoming proposals. If a proposal contains transactions not in their [Transactions'
], they Add those transactions to [Transactions'
] and send a new checkpoint proposal (must contain a superset of the previous one). Validators apply the effects of new transactions to their Accounts
state.
Process: Validators process a checkpoint with a quorum of signatures. Apply transactions to the last Checkpoint
state, creating Checkpoint'
. Distribute transaction fees to designated wallets.
Lock: After having processed the checkpoint, validators hash the state of the accounts in the Checkpoint’
and sign it. They send out a lock message containing their signature of the checkpoint hash, as well as the aggregated signatures for the proposal and the transactions contained therein.
[if required] Unlock: If a validator sees that different lock messages have gathered enough signatures each, such that neither can reach a quorum, they construct an unlock message. Unlock messages contain a proof that a quorum is impossible, analogous to a recovery certificate. They also attach a new checkpoint proposal containing the union set of all transactions in the unlock message.
Confirm: a node considers a checkpoint confirmed as soon as it sees a quorum for a lock message, or a certificate containing such a quorum. If a node has not yet seen a certificate, it creates one and sends it to all nodes.
Finish: Validators process the transactions without a certificate that they have received in the initiate and propose steps and union all such transactions. There are three possible cases for those transactions:
They have already received a quorum of signatures, in this case they aggregate the signatures and add the certificate to their own [Transactions
] array.
They may see different transactions with the same nonce, in this case they consider the account Byzantine and will only accept cancellation or recovery messages from this account going forward.
They may see that a transaction has gathered some signatures in the previous period, but not enough for a quorum. In this case, they sign that transaction with the new checkpoint ID and, if the confirmed proposal included a governance certificate, the new epoch ID.
After they have finished processing all transactions, they send out the newly signed transactions to all validators and to the sender.
Upon confirmation of a checkpoint, validators replace their Checkpoint
with the new Checkpoint’
, apply the effects of fee distribution and any transactions in the checkpoint that were not yet reflected in their state to the Accounts
in their state and discard the checkpointed transactions from their [Transactions
] array; archive nodes add them to their [Archive
]. They immediately stop signing messages with the old checkpoint ID and start signing with the new one. Validators may sign transactions that they have already signed with an old checkpoint ID, but for which they have not yet seen a certificate, again with a new checkpoint ID. This helps ensure liveness, but it may result in multiple certificates existing for the same transaction.
Transaction fees are collected from the sender (or the receiver when applicable) into a designated 1Money Network account. The protocol streamlines fee management by using the same token being transferred to pay the fees, eliminating the need for users to hold a separate "gas token." This approach makes transaction fees predictable, ensuring greater transparency and fairness.
Cancellation allows cancelling payments that have not yet reached a quorum (typically because the sender does not have sufficient funds)
Signatures for different transactions with the same counter are not the only reason why an account might be unable to effect new transactions. This could also happen if they have signed a transaction with a payment higher than their current balance – in this case they could not effect new transactions until they have a sufficient balance and the transaction can be processed. If account owners do not want to wait for this, our protocol offers a different option: they can send a cancellation message C.
A cancellation message has the same fields as a payment message, except for Recipients
and Amount
. Validators treat it similarly to a payment message, signing it if it is correct, and it becomes a final certificate once it has reached a quorum. The fee for cancelling a transaction, G.CancellationFee
, would typically be higher than for a payment transaction, to reflect the fact that it likely generated more network traffic (but again, very low in absolute terms, typically). Cancellation message take precedence over any pending payment messages – validators can sign a cancellation message, even if they already have pending messages with the same counter for the same account. But they cannot sign a cancellation message if they have already signed some message with the same nonce with any epoch. Cancellation messages may also be included in a recovery message, so there is always a path to unlocking a stalled account (as long as the account has a sufficient balance to pay the fees).
In Byzantine behavior, if a sender signs different transactions with the same nonce and send to different validators, can lead to the account getting locked. Account recovery transaction allows recovering such accounts.
A recovery
certificate R
contains an array of messages with the same nonce, together with their signatures, that proves that it is impossible to reach a quorum for any of the messages. Concretely, this means that for each member of the recovery transaction set, it must hold true that the the unique signatures, with the same epoch, for all the other messages combined form a . Similar to payment certificates, valid recovery certificates are immediately final.
Validators who see such a valid recovery message increase the nonce for the affected account and remove any pending transactions they might have for that nonce, thereby making it possible for new transactions by that account to be signed again. That is, if the account has a sufficient balance to pay for the associated fees, G.RecoveryFee
(for the last epoch in the set) times the total number of recipients across all messages in R
(cancellation messages are counted as having one recipient). The resulting fee is higher than for an honest payment transaction, to acknowledge the fact that it is due to Byzantine behavior by the sender and has created more network load than an honest transaction, but it would usually still be very low in absolute terms.