0038 XLS-38d: Cross-Chain Bridge (side chains) #92
Replies: 13 comments 74 replies
-
Love to see movement still on this initiative well done to all involved! Have some questions.
|
Beta Was this translation helpful? Give feedback.
-
Thank you for this standards draft! Following from the sidelines, the design and terminology has changed a lot over the last year – so in advance sorry if some of my questions and observations are mixed up and refer to previous and now abandoned design choices.
|
Beta Was this translation helpful? Give feedback.
-
I planned on writing a pretty long comment and I'm halfway finished but I didn't want to write under the assumption that there are benefits to using a normal transaction with a multi-sig list on it, coordinated by the bridge's own layer-2 network (Appendix B) than using the proposed There are noted complex issues with using a separate distributed system as a service (L2) to coordinate and distribute signatures and I'm personally faced with that, mainly:
It would be nice if you could also share on how you mitigated these issues or how you planned on mitigating them if we were to go for the L2 designed ❤️ ! |
Beta Was this translation helpful? Give feedback.
-
Why not go with the light client approach for bridging between XRPL chains? Any XRPL chain can directly verify (on chain) whether a transaction was validated on another chain simply by knowing the other chain's UNL. If chain A knows chain B's UNL, chain A can be fed a ledger header from chain B, as well as sufficient validations for said header from validators on chain B's UNL. Then, for any cross chain transfer from chain B, all that's needed is the SHAMap proof path for the transaction, proving the transaction is in the ledger. You can store the UNL on ledger as a ledger object to make this process simple for other chains. If we did this, there would be no need to trust witness servers or any entity besides the two chains involved in bridging. As it stands right now, the witness servers are an attack vector. If the witness servers collude, or if their private keys are compromised (as has happened in many multi million dollar bridge hacks in the past few years), millions of dollars of funds will be lost. The light client approach eliminates this common attack vector, and is thus a far more secure bridge. The reason all bridges are not light clients is because it is hard to build a light client for most chains. But for XRPL chains, it is incredibly easy, because of the way XRPL consensus works. Given this, it just seems like a bad design decision to go with a design that allows for the hack we've seen so often in the bridge space. Even from an infrastructure standpoint, the light client approach is easier. All that's needed is a relayer to pass transactions between the two chains, which is not trusted and only provides liveness, and could really be run by anyone, or even done by the wallet itself. This approach would also be useful when XRPL (hopefully) starts bridging to other chains. Any remote chain can verify a transaction was validated by an XRPL chain using the same approach described here. |
Beta Was this translation helpful? Give feedback.
-
When would there ever not be a UNL? As to the UNL expiring or changing, the light client can handle that in the same way that rippled handles UNLs expiring or changing.
The validators could mount the same attack, but this is unlikely and I would argue violates the trust assumption we already have for the ledger. We trust that more than 80% of the mainnet validators will not collude in a malicious way. The attack I'm actually concerned with though is not collusion but a separate entity compromising the private keys of the witness servers. This is the bridge attack we've seen in practice several times already. In the light client approach, an attacker would need to compromise the private keys of the validators, which I think is much less likely, and would enable them to mount all sorts of attacks beyond just attacking the sidechain bridge. Furthermore, I would argue that both of these attacks (validator collusion or validator key compromise) would work with the existing bridge architecture anyways. If the validators collude to validate malicious transactions and change the state of the ledger, they can probably fool the witness servers (as well as centralized exchanges). All in all, I think the validators colluding or their keys being compromised is an all bets are off scenario, in which case the whole security assumption of the network is violated. So the light client approach is basically just not adding additional security assumptions (such as the witness servers not colluding or not getting their keys compromised). |
Beta Was this translation helpful? Give feedback.
-
Thank you for this open draft! Witnesses have to somehow coordinate off-chain. A consumer of such a bridge may see them as a kind of "centralized group" instead of a single centralized entity. The trust needed seems similar to me. I would like to read about specific aspects where the benefits of this proposal outweigh a bridge provided by a single centralized entity without this amendment. Right now, it's hard for me to see how this amendment outweighs the downsides. |
Beta Was this translation helpful? Give feedback.
-
Hi folks: per the new XLS Contributing process, it is my opinion that we have reached a "well-refined standard." As such, I propose that we move this discussion to a file (via #109) and work on final changes using additional PRs, for better change-tracking. Please comment here if you would like to object to moving this spec/discussion forward in the process into a DRAFT spec. (Note that per the Contributing guidelines, moving a spec into the DRAFT state does not mean any kind of endorsement, nor does it mean that this specification will become adopted. It is solely meant as a mechanism to enable better change tracking using PRs.) |
Beta Was this translation helpful? Give feedback.
-
A recent case that needs to be discussed is the The hackers utilized a multi-sig bridge powered by Orbit to launder the funds to other chains to avoid regulations & AML efforts put in place. With the bridge, the hackers swapped the stolen $XRP to $KLAY, then swapped to $ETH, then moved to Avalanche and then moved them to Bitcoin.
This brings up an additional case to discuss about the regulatory aspect of bringing native implementation of layer-2 bridges and its practicality. My personal concerns:
|
Beta Was this translation helpful? Give feedback.
-
Proposed implementation: XRPLF/rippled#4292 |
Beta Was this translation helpful? Give feedback.
-
I'd like to propose that we move this spec to the next step in our development process. I understand there are still legal concerns, and I don't want to minimize these. Since many people and groups help develop the ledger, making decisions is challenging. We try to have a good development process that helps us make good decisions. Our current process with phases for discussion, draft spec, and candidate spec are reasonable and help us make good technical decisions. I'm not sure what the best process is to resolve legal concerns. Still, I think we're in a good place technically I think it's reasonable to move from the discussion phase to a draft spec phase even with the outstanding legal concerns. I'd like to close this discussion on Tuesday, July 4th and open a pull request for a draft standard. I appreciate all of the great feedback everyone has provided. Thank you everyone. |
Beta Was this translation helpful? Give feedback.
-
I to would prefer this move forward, both as a technical solutions provide forward progress. I would prefer a competing solution to a single option offered to the the market. My only impetus, is simple "get to dev" instances are available at every step, something I would prefer the xumm team would be more proficient at, which they have not delivered an equivalent/better than the "existing team". I would call for further review on the xumm solution (pending their public release) vs a speedy vote to public opinion. I have no technical issue the approach, but do not agree on need to "burn to mint". This could be achieved via multiple other options. +1 to this moving forward and a -1 to xumm to find a equilibrium. |
Beta Was this translation helpful? Give feedback.
-
Burn to Mint isn’t mutually exclusive with XLS38. These are decentralised public blockchains anyone can use. More than one bridge mechanism is possible. As @WietseWind has pointed out, our solution is based on legal constraints. If you are lucky enough to live and work somewhere where you can run a custodial two way bridge with legal immunity and without a money services business license + AML/KYC reporting then please, by all means do. For us this is simply legally impossible. |
Beta Was this translation helpful? Give feedback.
-
I am now closing this discussion as I have opened a PR for the draft spec: #118 If you have any additional comments please post them in the PR or open your own PR with proposed changes. |
Beta Was this translation helpful? Give feedback.
-
Latest version: XLS-38 Cross-Chain Bridge
The initial version follows:
Cross-Chain Bridge
Abstract
A bridge connects two blockchains: a locking chain and an issuing chain (also called a mainchain and a sidechain). Both are independent ledgers, with their own validators and potentially their own custom transactions. Importantly, there is a way to move assets from the locking chain to the issuing chain and a way to return those assets from the issuing chain back to the locking chain: the bridge. This key operation is called a cross-chain transfer. In this proposal, a cross-chain transfer is not a single transaction. It happens on two chains, requires multiple transactions, and involves an additional server type called a "witness".
A bridge does not exchange assets between two ledgers. Instead, it locks assets on one ledger (the "locking chain") and represents those assets with wrapped assets on another chain (the "issuing chain"). A good model to keep in mind is a box with an infinite supply of wrapped assets. Putting an asset from the locking chain into the box will release a wrapped asset onto the issuing chain. Putting a wrapped asset from the issuing chain back into the box will release one of the existing locking chain assets back onto the locking chain. There is no other way to get assets into or out of the box. Note that there is no way for the box to "run out of" wrapped assets - it has an infinite supply.
1. Introduction
1.1. Terminology
1.2. The Witness Server
A witness server is an independent server that helps provide proof that an event happened on either the locking chain or the issuing chain. It listens to transactions on one side of the bridge and submits attestations on the other side. This helps affirm that a transaction on the source chain occurred. The witness server is acting as an oracle, providing information to help prove that the assets were moved to the door account on the source chain (to be locked or burned). This then allows the recipient of those assets to claim the equivalent funds on the destination chain.
Since submitting a signature requires submitting a transaction and paying a fee, supporting rewards for signatures is an important requirement. The reward could be higher than the fee, providing an incentive for running a witness server.
1.3. Design Overview
This design proposes: 1 new server type, 3 new ledger objects, and 8 new transactions.
The new server type is:
The new ledger objects are:
Bridge
XChainOwnedClaimID
XChainOwnedCreateAccountClaimID
The new transactions are:
XChainCreateBridge
XChainModifyBridge
XChainCreateClaimID
XChainCommit
XChainAddClaimAttestation
XChainClaim
XChainAccountCreateCommit
XChainAddAccountCreateAttestation
1.3.1. A Cross-Chain Transfer
1.3.1.1. Primitives
A cross-chain transfer moves assets from the locking chain to the issuing chain, or returns those assets from the issuing chain back to the locking chain. These transfers need some primitives:
Put assets into trust (lock assets) on the locking chain.
Issue or mint wrapped assets on the issuing chain.
Return or burn the wrapped assets on the issuing chain.
On the issuing chain, prove that assets were put into trust on the locking chain.
On the locking chain, prove that assets were returned or burned on the issuing chain.
A way to prevent the same assets from being wrapped multiple times (prevent transaction replay). The proofs that certain events happened on the different chains are public and can therefore theoretically be submitted multiple times. This must be valid only once to wrap or unlock assets.
1.3.1.2. Process
In this scenario, a user is trying to transfer funds from their account on the source chain to their account on the destination chain.
XChainCreateClaimID
transaction. This creates aXChainOwnedClaimID
ledger object. The ledger object must specify the source account on the source chain.XChainCommit
transaction on the source chain, attaching the claimed cross-chain claim ID and including a reward amount (SignatureReward
) for the witness servers. This locks or burns the asset on the source chain, depending on whether the source chain is a locking or issuing chain. This transaction must be submitted from the same account that was specified when creating the claim ID.XChainAddClaimAttestation
transaction on the destination chain.XChainClaim
transaction for the transferred value on the destination chain.1.3.2. Setting Up a Cross-Chain Bridge
XChainCreateBridge
transactions sent by the door accounts, which creates aBridge
ledger object on each chain. Each chain has a door account that controls that end of the bridge on-chain. On one chain, currency is locked and unlocked (the locking chain). On the other chain, currency is minted and burned, or issued and reclaimed (the issuing chain).Bridge
ledger object can be modified via theXChainModifyBridge
transaction.SignerListSet
transaction) using the witness servers’ signing keys, so that they control the funds that the bridge controls.AccountSet
transaction), so that the witness servers as a collective have total control of the bridge.1.3.3. Account Creation
Account creation must happen via a different means. This is because the cross-chain transfer process requires an existing account on the destination chain, so if the user does not have an account on the destination chain, they have no way to transfer funds.
XChainAccountCreateCommit
transaction on the source chain. This locks or burns the asset on the source chain, depending on whether the source chain is a locking or issuing chain.XChainAddAccountCreateAttestation
transactions. Since there is noXChainOwnedClaimID
object on the destination chain to keep track of the attestations, the ledger instead creates aXChainOwnedCreateAccountClaimID
object upon receiving the first attestation.2. Changes to the XRPL
2.1. On-Ledger Objects
We propose three new objects:
A
Bridge
is a new object that describes a single cross-chain bridge.A
XChainOwnedClaimID
is a new object that describes a single cross-chain claim ID.A
XChainOwnedCreateAccountClaimID
is a new object that describes an account to be created on the issuing chain.2.1.1. The
Bridge
objectThe
Bridge
object represents one end of a cross-chain bridge and holds data associated with the cross-chain bridge. Bridges are created using theXChainCreateBridge
transaction.The ledger object is owned by the door account and defines the bridge parameters. It is created with a
XChainCreateBridge
transaction, and modified with aXChainModifyBridge
transaction (only the
MinAccountCreateAmount
andSignaturesReward
may be changed). It cannot be deleted. A door account may not own more than oneBridge
object.Note: The signatures used to attest to chain events are on the
XChainOwnedClaimID
andXChainOwnedAccountCreateClaimID
ledger objects, not on this ledger object.2.1.1.1. Fields
A
Bridge
object has the following fields:LedgerIndex
string
HASH256
XChainBridge
XChainBridge
XCHAIN_BRIDGE
SignatureReward
Currency Amount
AMOUNT
MinAccountCreateAmount
Currency Amount
AMOUNT
XChainAccountCreateCount
number
UINT64
XChainAccountClaimCount
number
UINT64
XChainClaimID
number
UINT64
2.1.1.1.1.
LedgerIndex
The ledger index is a hash of a unique prefix for a bridge object, and the fields in
XChainBridge
.2.1.1.1.2.
XChainBridge
The bridge that this object correlates to - namely, the door accounts and the currencies.
This is the identity of the bridge and cannot be changed, as if it were to change, the object would be representing a different bridge.
It is used everywhere where a
XChainBridge
field exists. This is easier for users instead of expecting them to use the ledger object ID.LockingChainDoor
string
ACCOUNT
LockingChainIssue
Issue
ISSUE
IssuingChainDoor
string
ACCOUNT
IssuingChainIssue
Issue
ISSUE
LockingChainDoor
The door account on the locking chain.
LockingChainIssue
The asset that is locked and unlocked on the locking chain.
IssuingChainDoor
The door account on the issuing chain. For a XRP-XRP bridge, this must be the genesis account (the account that is created when the network is first started, which contains all of the XRP).
IssuingChainIssue
The asset that is minted and burned on the issuing chain. For an IOU-IOU bridge, the issuer of the asset must be the door account on the issuing chain, to avoid supply issues.
2.1.1.1.3.
SignatureReward
The total amount, in XRP, to be rewarded for providing a signature for a cross-chain transfer or for signing for the cross-chain reward. This will be split among the signers.
2.1.1.1.4.
MinAccountCreateAmount
The minimum amount, in XRP, required for a
XChainAccountCreateCommit
transaction. If this is not present, theXChainAccountCreateCommit
transaction will fail. This field can only be present on XRP-XRP bridges.2.1.1.1.5.
XChainAccountCreateCount
A counter used to order the execution of account create transactions. It is incremented every time a successful
XChainAccountCreateCommit
transaction is run for the source chain.2.1.1.1.6.
XChainAccountClaimCount
A counter used to order the execution of account create transactions. It is incremented every time a
XChainAccountCreateCommit
transaction is "claimed" on the destination chain. When the "claim" transaction is run on the destination chain, theXChainAccountClaimCount
must match the value that theXChainAccountCreateCount
had at the time theXChainAccountClaimCount
was run on the source chain. This orders the claims so that they run in the same order that theXChainAccountCreateCommit
transactions ran on the source chain, to prevent transaction replay.2.1.1.1.7.
XChainClaimID
The value of the next
XChainClaimID
to be created.2.1.2. The
XChainOwnedClaimID
objectThe
XChainOwnedClaimID
ledger object represents a unique ID for each cross-chain transfer. It must be acquired on the destination chain before submitting aXChainCommit
on the source chain. Its purpose is to prevent transaction replay attacks and is also used as a place to collect attestations from witness servers.A
XChainCreateClaimID
transaction is used to create a newXChainOwnedClaimID
. The ledger object is destroyed when the funds are successfully claimed on the destination chain.2.1.2.1. Fields
A
XChainOwnedClaimID
object may have the following fields:LedgerIndex
string
HASH256
XChainBridge
XChainBridge
XCHAIN_BRIDGE
OtherChainSource
string
ACCOUNT
SignatureReward
Currency Amount
AMOUNT
XChainClaimAttestations
array
ARRAY
XChainClaimID
string
UINT64
2.1.2.1.1.
LedgerIndex
The ledger index is a hash of a unique prefix for
XChainOwnedClaimID
s, the actualXChainClaimID
value, and the fields inXChainBridge
.2.1.2.1.2.
XChainBridge
Which bridge the
XChainClaimID
correlates to.2.1.2.1.3.
OtherChainSource
The account that must send the corresponding
XChainCommit
on the source chain. The destination may be specified in theXChainCommit
transaction, which means that if theOtherChainSource
isn't specified, another account can try to specify a different destination and steal the funds. This also allows tracking only a single set of signatures, since we know which account will send theXChainCommit
transaction.2.1.2.1.4.
SignatureReward
The total amount to pay the witness servers for their signatures. It must be at least the value of
SignatureReward
in theBridge
ledger object.2.1.2.1.5.
XChainClaimAttestations
Attestations collected from the witness servers. This includes the parameters needed to recreate the message that was signed, including the amount, which chain (locking or issuing), optional destination, and reward account for that signature.
See the
XChainAddClaimAttestation
section for more details on what this looks like.2.1.2.1.6.
XChainClaimID
The unique sequence number for a cross-chain transfer.
2.1.3. The
XChainOwnedCreateAccountClaimID
objectThe
XChainOwnedCreateAccountClaimID
ledger object is used to collect attestations for creating an account via a cross-chain transfer. It is created when aXChainAddAccountCreateAttestation
transaction adds a signature attesting to aXChainAccountCreateCommit
transaction and theXChainAccountCreateCount
is greater than or equal to the currentXChainAccountClaimCount
on theBridge
ledger object. It is destroyed when all the attestations have been received and the funds have transferred to the new account.2.1.3.1. Fields
A
XChainOwnedCreateAccountClaimID
object may have the following fields:LedgerIndex
string
HASH256
XChainBridge
XChainBridge
XCHAIN_BRIDGE
XChainAccountCreateCount
number
UINT64
XChainCreateAccountAttestations
array
ARRAY
2.1.3.1.1.
LedgerIndex
The ledger index is a hash of a unique prefix for
XChainOwnedCreateAccountClaimID
s, theXChainAccountCreateCount
, and the fields inXChainBridge
.2.1.3.1.2.
XChainBridge
Door accounts and assets.
2.1.3.1.3.
XChainAccountCreateCount
An integer that determines the order that accounts created through cross-chain transfers must be performed. Smaller numbers must execute before larger numbers.
2.1.3.1.4.
XChainCreateAccountAttestations
Attestations collected from the witness servers. This includes the parameters needed to recreate the message that was signed, including the amount, destination, signature reward amount, and reward account for that signature. With the exception of the reward account, all signatures must sign the message created with common parameters.
See the
XChainAddAccountCreateAttestation
section for more details on what this looks like.2.2. Transactions Controlling The Bridge
2.2.1. The
XChainCreateBridge
transactionThe
XChainCreateBridge
transaction creates a newBridge
ledger object. This tells one chain (whichever chain the transaction is submitted on) the details of the bridge.The transaction must be submitted by the door account. It must also be submitted on both chains that form the bridge in order to be a valid bridge. A door account may own at most one bridge object.
2.2.1.1. Fields
The
XChainCreateBridge
transaction contains the following fields:XChainBridge
XChainBridge
XCHAIN_BRIDGE
SignatureReward
Currency Amount
AMOUNT
MinAccountCreateAmount
Currency Amount
AMOUNT
2.2.1.1.1.
XChainBridge
Which bridge (door accounts and issues) to create.
2.2.1.1.2.
SignatureReward
The signature reward split between the witnesses for submitting attestations.
2.2.1.1.3.
MinAccountCreateAmount
The minimum amount, in XRP, required for a
XChainAccountCreateCommit
transaction. If this is not present, theXChainAccountCreateCommit
transaction will fail. This field can only be present on XRP-XRP bridges.2.2.2. The
XChainModifyBridge
transactionThe
XChainModifyBridge
transaction allows bridge managers to modify the parameters of the bridge. They can only change theSignatureReward
and theMinAccountCreateAmount
. This is because changing the door accounts or assets would essentially be creating a new bridge as opposed to modifying an existing one.Note that this is a regular transaction that is sent by the
door account and requires the entities that control the witness servers to coordinate and provide the signatures for this transaction. This coordination happens outside the ledger.
Note that the signer list for the bridge is not modified through this transaction. The signer list is on the door account itself and is changed in the same way signer lists are changed on accounts (via a
SignerListSet
transaction).2.2.2.1. Fields
The
XChainModifyBridge
transaction contains the following fields:XChainBridge
XChainBridge
XCHAIN_BRIDGE
SignatureReward
Currency Amount
AMOUNT
MinAccountCreateAmount
Currency Amount
AMOUNT
Flags
number
UINT32
2.2.2.1.1.
XChainBridge
Which bridge (door accounts and issues) to modify.
2.2.2.1.2.
SignatureReward
The signature reward split between the witnesses for submitting attestations.
2.2.2.1.3.
MinAccountCreateAmount
The minimum amount, in XRP, required for a
XChainAccountCreateCommit
transaction. If this is not present, theXChainAccountCreateCommit
transaction will fail. This field can only be present on XRP-XRP bridges.2.2.2.1.4.
Flags
Specifies the flags for this transaction. In addition to the universal transaction flags that are applicable to all transactions (e.g.,
tfFullyCanonicalSig
), the following transaction-specific flags are defined:tfClearAccountCreateAmount
0x00010000
MinAccountCreateAmount
of the bridge.2.3. Transactions for Cross-Chain Transfers
2.3.1. The
XChainCreateClaimID
transactionThe
XChainCreateClaimID
transaction is the first step in a cross-chain transfer. The claim ID must be created on the destination chain before theXChainCommit
transaction (which must reference this number) can be sent on the source chain. The account that will send theXChainCommit
on the source chain must be specified in this transaction (see note on theOtherChainSource
field in theXChainOwnedClaimID
ledger object forjustification). The actual claim ID must be retrieved from a validated ledger.
2.3.1.1. Fields
The
XChainCreateClaimID
transaction contains the following fields:XChainBridge
XChainBridge
XCHAIN_BRIDGE
SignatureReward
Currency Amount
AMOUNT
OtherChainSource
string
ACCOUNT
2.3.1.1.1.
XChainBridge
Which bridge to create the
XChainOwnedClaimID
for.2.3.1.1.2.
SignatureReward
The amount, in XRP, to be used to reward the witness servers for providing signatures. This must match the amount on the
Bridge
ledger object.This could be optional, but it is required so the sender can be made positively aware that these funds will be deducted from their account.
2.3.1.1.3.
OtherChainSource
The account that must send the
XChainCommit
transaction on the source chain.Since the destination may be specified in the
XChainCommit
transaction, if theOtherChainSource
wasn't specified, another account could try to specify a different destination and steal the funds.This also allows us to limit the number of attestations that would be considered valid, since we know which account will send the
XChainCommit
transaction.2.3.2. The
XChainCommit
transactionThe
XChainCommit
transaction is the second step in a cross-chain transfer. It puts assets into trust on the locking chain so that they may be wrapped on the issuing chain, or burns wrapped assets on the issuing chain so that they may be returned on the locking chain.2.3.2.1. Fields
The
XChainCommit
transaction contains the following fields:XChainBridge
XChainBridge
XCHAIN_BRIDGE
XChainClaimID
string
UINT64
Amount
Currency Amount
AMOUNT
OtherChainDestination
string
ACCOUNT
2.3.2.1.1.
XChainBridge
Which bridge to use to transfer funds.
2.3.2.1.2.
XChainClaimID
The unique integer ID for a cross-chain transfer.
This must be acquired on the destination chain (via a
XChainCreateClaimID
transaction) and checked from a validated ledger before submitting this transaction.If an incorrect sequence number is specified, the funds will be lost.
2.3.2.1.3.
Amount
The asset to commit, and the quantity.
This must match the door account's
LockingChainIssue
(if on the locking chain) or the door account'sIssuingChainIssue
(if on the issuing chain).2.3.2.1.4.
OtherChainDestination
The destination account on the destination chain.
If this is not specified, the account that submitted the
XChainCreateClaimID
transaction on the destination chain will need to submit aXChainClaim
transaction to claim the funds.2.3.3. The
XChainAddClaimAttestation
transactionThe
XChainAddClaimAttestation
transaction provides an attestation from a witness server attesting to aXChainCommit
transaction on the other chain.The signature must be from one of the keys on the door's signer list at the time the signature was provided. However, if the signature list changes between the time the signature was submitted and the quorum is reached, the new signature set is used and some of the currently collected signatures may be removed. Note that the reward is only sent to accounts that have keys on the current list.
Note: Any account can submit signatures. This is important to support witness servers that work on the "subscription" model (see the
Witness Server
section for more details).Note: A quorum of signers need to agree on the
SignatureReward
, the same way they need to agree on the other data. A single witness server cannot provide an incorrect value for this in an attempt to collect a larger reward.2.3.3.1. Fields
The
XChainAddClaimAttestation
transaction contains the following fields:Amount
Currency Amount
AMOUNT
AttestationRewardAccount
string
ACCOUNT
AttestationSignerAccount
string
ACCOUNT
Destination
string
ACCOUNT
OtherChainSource
string
ACCOUNT
PublicKey
string
BLOB
Signature
string
BLOB
WasLockingChainSend
number
UINT8
XChainBridge
XChainBridge
XCHAIN_BRIDGE
XChainClaimID
string
UINT64
2.3.3.1.1.
Amount
The amount committed via the
XChainCommit
transaction on the source chain.2.3.3.1.2.
AttestationRewardAccount
The account that should receive this signer's share of the
SignatureReward
.2.3.3.1.3.
AttestationSignerAccount
The account on the door account's signer list that is signing the transaction. Normally, the public key would be equivalent to the master key of the account. However, there is also the option of creating the account on the chain and setting a regular key, and using that key to sign attestations on behalf of the signer account.
2.3.3.1.4.
Destination
The destination account for the funds on the destination chain (taken from the
XChainCommit
transaction).2.3.3.1.5.
OtherChainSource
The account on the source chain that submitted the
XChainCommit
transaction that triggered the event associated with the attestation.2.3.3.1.6.
PublicKey
The public key used to verify the attestation signature.
2.3.3.1.7.
Signature
The signature attesting to the event on the other chain.
2.3.3.1.8.
WasLockingChainSend
A boolean representing the chain where the event occurred.
2.3.3.1.9.
XChainBridge
The bridge associated with the attestations.
2.3.3.1.10.
XChainClaimID
The
XChainClaimID
associated with the transfer, which was included in theXChainCommit
transaction.2.3.3.2. Implementation Details
To add an attestation to a
XChainOwnedClaimID
, that ledger object must already exist.2.3.4. The
XChainClaim
transactionThe
XChainClaim
transaction allows the user to claim funds on the destination chain from aXChainCommit
transaction.This is normally not needed, but may be used to handle transaction failures or if the destination account was not specified in the
XChainCommit
transaction. It may only be used after a quorum of signatures have been sent from the witness servers.If the transaction succeeds in moving funds, the referenced
XChainOwnedClaimID
ledger object will be destroyed. This prevents transaction replay. If the transaction fails, theXChainOwnedClaimID
will not be destroyed and the transaction may be re-run with different parameters.2.3.4.1. Fields
The
XChainClaim
transaction contains the following fields:XChainBridge
XChainBridge
XCHAIN_BRIDGE
XChainClaimID
string
UINT64
Destination
string
ACCOUNT
DestinationTag
int
UINT32
Amount
Currency Amount
AMOUNT
2.3.4.1.1.
XChainBridge
The bridge associated with this transfer.
2.3.4.1.2.
XChainClaimID
The unique integer ID for a cross-chain transfer that was referenced in the relevant
XChainCommit
transaction.2.3.4.1.3.
Destination
The destination account on the destination chain. It must exist or the transaction will fail. However, if the transaction fails in this case, the sequence number and collected signatures will not be destroyed and the transaction may be rerun with a different destination address.
2.3.4.1.4.
DestinationTag
An integer destination tag.
2.3.4.1.5.
Amount
The amount to claim on the destination chain.
This must match the amount attested to on the attestations associated with this
XChainClaimID
.2.4. Transactions for Account Creation
Since the cross-chain transfer process requires an existing account on the destination chain, if the user does not have an account on the destination chain, they have no way to transfer funds. With a sidechain, there are no user accounts when the chain is first created. Therefore, account creation requires a special mechanism and special transactions.
2.4.1. The
XChainAccountCreateCommit
transactionThe
XChainAccountCreateCommit
transaction is a special transaction used for creating accounts through a cross-chain transfer.A normal cross-chain transfer requires a
XChainClaimID
(which requires an existing account on the destination chain). One purpose of theXChainClaimID
is to prevent transaction replay. For this transaction, we use a different mechanism: the accounts must be claimed on the destination chain in the same order that theXChainAccountCreateCommit
transactions occurred on the source chain.This transaction can only be used for XRP-XRP bridges.
IMPORTANT: This transaction should only be enabled if the witness attestations will be reliably delivered to the destination chain. If the signatures are not delivered, then account creation will be blocked until the one waiting on attestations receives its attestations. This could be used maliciously. To disable this transaction on XRP-XRP bridges, the bridge's
MinAccountCreateAmount
should not be present.Note: If this account already exists, the XRP is transferred to the existing account. However, note that unlike the
XChainCommit
transaction, there is no error handling mechanism. If the claim transaction fails, there is no mechanism for refunds (except manually, via the witness signing keys on the door accounts' signer list). The funds are essentially permanently lost. This transaction should therefore only be used for account creation.2.4.1.1. Fields
The
XChainAccountCreateCommit
transaction contains the following fields:XChainBridge
XChainBridge
XCHAIN_BRIDGE
SignatureReward
Currency Amount
AMOUNT
Destination
string
ACCOUNT
Amount
Currency Amount
AMOUNT
2.4.1.1.1.
XChainBridge
The bridge to use to transfer funds.
2.4.1.1.2.
SignatureReward
The amount, in XRP, to be used to reward the witness servers for providing signatures.
This must match the amount on the
Bridge
ledger object.This could be optional, but it is required so the sender can be made positively aware that these funds will be deducted from their account.
2.4.1.1.3.
Amount
The amount, in XRP, to use for account creation. This must be greater than or equal to the
MinAccountCreateAmount
specified in theBridge
ledger object.2.4.1.1.4.
Destination
The destination account on the destination chain.
2.4.2. The
XChainAddAccountCreateAttestation
transactionThe
XChainAddAccountCreateAttestation
transaction provides an attestation from a witness server attesting to aXChainAccountCreateCommit
transaction on the other chain.The signature must be from one of the keys on the door's signer list at the time the signature was provided. However, if the signature list changes between the time the signature was submitted and the quorum is reached, the new signature set is used and some of the currently collected signatures may be removed. Note that the reward is only sent to accounts that have keys on the current list.
Note: Any account can submit signatures. This is important to support witness servers that work on the "subscription" model (see the
Witness Server
section for more details).Note: A quorum of signers need to agree on the
SignatureReward
, the same way they need to agree on the other data. A single witness server cannot provide an incorrect value for this in an attempt to collect a larger reward.2.4.2.1. Fields
The
XChainAddAccountCreateAttestation
transaction contains the following fields:Amount
Currency Amount
AMOUNT
AttestationRewardAccount
string
ACCOUNT
AttestationSignerAccount
string
ACCOUNT
Destination
string
ACCOUNT
OtherChainSource
string
ACCOUNT
PublicKey
string
BLOB
Signature
string
BLOB
SignatureReward
Currency Amount
AMOUNT
WasLockingChainSend
number
UINT8
XChainAccountCreateCount
string
UINT64
XChainBridge
XChainBridge
XCHAIN_BRIDGE
2.4.2.1.1.
Amount
The amount committed via the
XChainAccountCreateCommit
transaction on the source chain.2.4.2.1.2.
AttestationRewardAccount
The account that should receive this signer's share of the
SignatureReward
.2.4.2.1.3.
AttestationSignerAccount
The account on the door account's signer list that is signing the transaction. Normally, the public key would be equivalent to the master key of the account. However, there is also the option of creating the account on the chain and setting a regular key, and using that key to sign attestations on behalf of the signer account.
2.4.2.1.4.
Destination
The destination account for the funds on the destination chain.
2.4.2.1.5.
OtherChainSource
The account on the source chain that submitted the
XChainAccountCreateCommit
transaction that triggered the event associated with the attestation.2.4.2.1.6.
PublicKey
The public key used to verify the signature.
2.4.2.1.7.
Signature
The signature attesting to the event on the other chain.
2.4.2.1.8.
SignatureReward
The signature reward paid in the
XChainAccountCreateCommit
transaction.2.4.2.1.9.
WasLockingChainSend
A boolean representing the chain where the event occurred.
2.4.2.1.10.
XChainAccountCreateCount
The counter that represents the order that the claims must be processed in.
2.4.2.1.11.
XChainBridge
The bridge associated with the attestation.
2.4.2.2. Implementation Details
Since
XChainOwnedCreateAccountClaimID
is ordered, it's possible for this object to collect a quorum of signatures but not be able to execute yet. As a result, the witness servers are designed to always deliver attestations in order. Therefore, in practice, this object should not be able to collect a quorum of attestations without being able to execute yet.However, if this situation should occur (e.g. via a buggy witness server), then the object will not execute yet and another attestation will need to be sent to the object in order to execute it. In this case, it is okay to send an attestation that is already on the object.
3. The Witness Server
A witness server helps provide proof that some event happened on either the locking chain or the issuing chain. It does not validate transactions and does not need to coordinate with other witness servers. Instead, it listens to transactions from the chains. When it detects an event of interest on the source chain, it creates an attestation (a signed message) and uses the
XChainAddClaimAttestation
orXChainAddAccountCreateAttestation
transactions to submit their attestation for the event to the destination chain. When a quorum of signatures are collected on the destination chain, the funds are released.Since submitting a signature requires submitting a transaction and paying a fee, supporting rewards for signatures is an important requirement. The reward could be higher than the fee, providing an incentive for running a witness server.
It is possible for a witness server to provide attestations for one chain only - and it is possible for the door account on the locking chain to have a different signer's list than the door account on the issuing chain. The initial implementation of the witness server assumes it is providing attestation for both chains, however it is desirable to allow witness servers that only know about one of the chains.
The current design envisions two models for how witness servers are used:
The servers are completely private. They submit transactions to the chains themselves and collect the rewards themselves. Allowing the servers to be private has the advantage of greatly reducing the attack surface on these servers. They won't have to deal with adversarial input to their RPC commands, and since their ip address will be unknown, it will be hard to mount an DOS attack.
The witness server monitors events on a chain, but does not submit their signatures themselves. Instead, another party will pay the witness server for their signature (for example, through a subscription fee), and the witness server allows that party to collect the signer's reward. The account that receives the signature reward is part of the message that the witness server signs.
Note: since submitting a signature requires submitting a transaction and paying a fee, supporting rewards for signatures is an important requirement. Of course, the reward can be higher than the fee, providing an incentive to run a witness server.
3.1. The Server Code
The witness server code is currently available here. However, the official repo will likely move to the XRPLF Github org if this proposal is accepted.
3.2. Witness Configuration
The witness configuration is stored in a file called
witness.json
.3.2.1. Fields
LockingChain
object
IssuingChain
object
RPCEndpoint
object
LogFile
string
LogLevel
string
DBDir
string
SigningKeySeed
string
SigningKeyType
string
XChainBridge
XChainBridge
3.2.1.1.
LockingChain
The parameters for interacting with the locking chain.
Endpoint
object
TxnSubmit
object
RewardAccount
string
3.2.1.1.1.
Endpoint
The websocket endpoint of a
rippled
node synced with the locking chain.The fields are as follows:
IP
string
Port
string
IP
The IP address of the
rippled
node.Note: This does not accept URLs right now.
Port
The port used for the websocket endpoint.
3.2.1.1.2.
TxnSubmit
The parameters for transaction submission on the locking chain.
ShouldSubmit
boolean
SigningKeySeed
string
SigningKeyType
string
SubmittingAccount
string
ShouldSubmit
A boolean indicating whether or not the witness server should submit transactions on the locking chain.
For the subscription model, the witness server should not submit transactions.
SigningKeySeed
The seed that the witness server should use to sign its transactions on the locking chain. This is required if
ShouldSubmit
istrue
.SigningKeyType
The algorithm used to encode the
SigningKeySeed
. The options aresecp256k1
anded25519
. This is required ifShouldSubmit
istrue
.SubmittingAccount
The account from which the
XChainAddClaimAttestation
andXChainAddAccountCreateAttestation
transactions should be sent. This is required ifShouldSubmit
istrue
.3.2.1.1.1.
RewardAccount
The account that should receive the witness's share of the
SignatureReward
on the locking chain.3.2.1.2.
IssuingChain
The parameters for interacting with the issuing chain. This is identical to the
LockingChain
section.3.2.1.3.
RPCEndpoint
The endpoint for RPC requests to the witness server.
IP
string
Port
string
3.2.1.3.1.
IP
The IP address for the endpoint.
3.2.1.3.2.
Port
The port for the endpoint.
3.2.1.4.
LogFile
The location of the log file.
3.2.1.5.
LogLevel
The level of logs to store in the log file. The options are
["All", "Trace", "Debug", "Info", "Warning", "Error", "Fatal", "Disabled","None"]
.3.2.1.6.
DBDir
The location of the directory where the databases are stored.
3.2.1.7.
SigningKeySeed
The seed that the witness server should use to sign its attestations.
3.2.1.8.
SigningKeyType
The algorithm used to encode the
SigningKeySeed
. The options aresecp256k1
anded25519
.3.2.1.9.
XChainBridge
The bridge that the witness server is monitoring. This is identical to the
XChainBridge
params in every transaction and ledger object.3.3. Running a Witness Server
After downloading and building the code, run:
Further details are available in the README of the repo.
3.3.1. Server Specs
The witness server is pretty lightweight, so it likely doesn't need very high specs. However, this has not been tested.
3.3.2. Best Practices
In a production environment, a witness server should use different keys for each of signing attestations, signing locking chain transactions, and signing issuing chain transactions. This adds security and helps avoid transaction replay attack issues.
4. How to Build a Bridge
4.1. Setting Up a New Sidechain (AKA Building a XRP-XRP Bridge)
Setting up a new issuing chain with a XRP-XRP bridge is somewhat complex, because there are no accounts on the issuing chain, even for witnesses. As a result, witnesses cannot directly submit
XChainAddClaimAttestation
orXChainAddAccountCreateAttestation
transactions.Once the new network is set up and active (in other words, the validators are running and are successfully closing ledgers):
XChainCreateBridge
transaction on the locking chain from the door account.SignerListSet
for ease of setup.MinAccountCreateAmount
value should be at minimum the account reserve on the issuing chain.SignerListSet
transaction on the locking chain from the door account, with the witnesses' signing keys as the signers.AccountSet
transaction.XChainCreateBridge
transaction on the issuing chain from the door account. This door account already exists, since it must be the genesis account.XChainAccountCreateCommit
transactions from account(s) that have enough funds, to create each of the witnesses' submission accounts on the issuing chain.XChainAccountCreateCommit
transactions in step 6. These attestations should be signed by the genesis seed, since that is currently what controls the genesis account.XChainAddAccountCreateAttestation
transaction for each of the attestations from step 7 on the issuing chain, with the genesis account.SignerListSet
transaction on the issuing chain from the door account, with the witnesses' signing keys as the signers.AccountSet
transaction.The bridge is now set up and can be used normally.
4.2. Building an IOU-IOU Bridge
Any two networks that have an IOU-IOU bridge between them should already have a XRP-XRP bridge between them, as a sidechain will need XRP for account reserves and transaction fees (while this could be changed, in that case the
XChainBridge
amendment code could also be modified). This makes it simpler to set up an IOU-IOU bridge.To set up an IOU-IOU bridge:
XChainCreateBridge
transaction on the locking chain from the door account.SignerListSet
for ease of setup.MinAccountCreateAmount
value should not be included.SignerListSet
transaction on the locking chain from the door account, with the witnesses' signing keys as the signers.AccountSet
transaction.XChainCreateBridge
transaction on the issuing chain from the door account.SignerListSet
transaction on the issuing chain from the door account, with the witnesses' signing keys as the signers.AccountSet
transaction.The bridge is now set up and can be used normally.
5. Security
5.1. Trust Assumptions
The witness servers are trusted, and if a quorum of them collude they can steal funds from the door account.
5.1.1. Use of the Signer List
The public keys that the witness servers use must match the public keys on that door's signer's list. But this isn't the only way to implement this. A bridge ledger object could contain a signer list that's independent from the door account. The reasons for using the door account's signers list are:
The bridge signers list can be used to move funds from the account. Putting this list on the door account emphasizes this trust model.
It allows for emergency action. If something goes very, very wrong, funds could still be moved if the entities on the signer list sign a regular
Payment
transaction.It's a more natural way to modify bridge parameters.
5.2. Transaction Replay Attacks
Normally, account sequence numbers prevent transaction replay on the XRP Ledger. However, this bridge design allows funds to move from an account via transactions not sent by that account (namely, the attestations submitted by the witness servers). All the information to replay these transactions are publicly available. This section describes how the different transactions prevent certain attacks - including transaction replay attacks.
To successfully run a
XChainClaim
transaction, the account sending the transaction must own theXChainOwnedClaimID
ledger object referenced in the witness server's attestation. Since this ledger object is destroyed when the funds are successfully moved, the transaction cannot be replayed.To successfully create an account with the
XChainAccountCreateCommit
transaction, the ordering number must match the current order number on the bridge ledger object. After the transaction runs, the order number on the bridge ledger object is incremented. Since this number is incremented, the transaction can not be replayed since the order number in the transaction will never match again.Since the
XChainCommit
can contain an optional destination account on the destination chain, and the funds will move when the destination chain collects enough signatures, one attack would be for an account to watch for aXChainCommit
to be sent and then send their ownXChainCommit
for a smaller amount. This attack doesn't steal funds, but it does result in the original sender losing their funds. To prevent this, when aXChainOwnedClaimID
is created on the destination chain, the account that will send theXChainCommit
on the source chain must be specified. Only the attestations from this transaction will be accepted on theXChainOwnedClaimID
.5.3. Error Handling
5.3.1. Error Handling for Cross-Chain Transfers
Error handling for cross-chain transfers is straightforward. The
XChainOwnedClaimID
is only destroyed when a claim succeeds. If it fails for any reason (for example, if the destination account doesn't exist or has deposit auth set), then an explicitXChainClaim
transaction may be submitted to redirect the funds.5.3.2. Error Handling for Cross-Chain Account Creates
If a cross-chain account create fails, the recovery of funds must happen outside the rules of the bridge system. The only way to recover them would be if the witness servers created a
Payment
transaction themselves. This is unlikely to happen and should not be relied upon. TheMinAccountCreateAmount
on theBridge
object is meant to prevent these transactions from failing due to having too little XRP.5.3.3. Error Handling for Signature Reward Delivery
If the signature reward cannot be delivered to the specified account, that portion of the signature reward is kept by the account that owns the
XChainOwnedClaimID
.Appendix
Appendix A: Alternate Account Create Design: Undeletable Accounts
In a normal cross-chain transfer, the claim ID is used to prevent transaction replay. However, the account create design does not use claim IDs. Instead, it requires that accounts be created in the same order as the "commit" transactions.
There is another way to prevent transaction replay - check if the account to be created already exists. If it does, reject the transaction. The only problem with this is that accounts on the XRP ledger are deletable, and an easy attack would be to delete the account and replay the transaction.
To prevent this, a design was considered where accounts created through cross-chain "account create" transactions would be undeletable. This has the nice property that the attestations no longer need to be added in order. However, it also introduces a new property on
AccountRoot
s that interacts with existing functionality.In the end, this proposal chose to pursue the "execution ordering" strategy. However, the undeletable account strategy is a viable solution with a different set of tradeoffs.
Appendix B: Alternate Designs
One alternate design that was implemented involved a set of servers similar to the witness servers called "federators". These servers communicated among themselves, collected signatures needed to submit transactions on behalf of the door accounts directly, and submitted those transactions.
This design is attractive from a usability point of view. There is no "cross-chain sequence number" that needs to be obtained on the destination chain, and creating accounts using cross-chain transfers is straightforward.
The main disadvantage of this design is the complexity in the federators. In order to submit a transaction, the federators need to agree on a transaction's sequence number and fees. This requires the federators to stay in "sync" with each other and requires that these federators be much more complex than the "witness" servers proposed in this design.
In addition, handling fee escalation, failed transactions, and servers falling behind was much more complex.
Finally, because all the transactions were submitted from the same account (the door account), this presented a challenge for transaction throughput as the XRP ledger limits the number of transactions an account can submit in a single ledger.
Beta Was this translation helpful? Give feedback.
All reactions