Multisig prover contract
Not used on the XRPL side. XRPL outbound transactions are built by the XRPL Multisig Prover, which builds XRPL-native transactions (
Payment,SignerListSet,TicketCreate,TrustSet), manages tickets and the XRP fee reserve, and uses the XRPLSMT\0-prefixed SHA-512-half multi-signing digest. The genericmultisig-proverdocumented here is the template deployed for most other connected amplifier chains.
The prover contract is responsible for transforming gateway messages into a payload that is ready to be sent to the destination gateway. It calls the multisig contract to generate the signature proof and finally encodes both the data and proof so that relayers can take it and send it to the destination chain gateway.
Interface
pub enum ExecuteMsg {
// Start building a proof that includes specified messages. Permission: Any.
// Queries the gateway for actual message contents.
ConstructProof(Vec<CrossChainId>),
// Triggers a verifier set rotation if the registered set has diverged from the current
// one by more than `verifier_set_diff_threshold`. Permission: Elevated (admin or governance).
UpdateVerifierSet,
// Promotes a previously-prepared NextVerifierSet to be the current set, once a poll on
// the destination chain's SignersRotated event has confirmed it. Permission: Any.
ConfirmVerifierSet,
// Updates the signing threshold used for future verifier sets. The threshold currently
// in use does not change; the verifier set must be updated and confirmed for the change
// to take effect. Permission: Governance.
UpdateSigningThreshold {
new_signing_threshold: MajorityThreshold,
},
// Replaces the contract's admin address. Permission: Governance.
UpdateAdmin {
new_admin_address: String,
},
}
#[derive(QueryResponses)]
pub enum QueryMsg {
// Returns the current proof for a given multisig session, including the encoded
// execute_data once signing completes.
#[returns(ProofResponse)]
Proof { multisig_session_id: Uint64 },
// Returns the current active verifier set, or None if uninitialized.
#[returns(Option<VerifierSetResponse>)]
CurrentVerifierSet,
// Returns the next (pending) verifier set, or None if no rotation is in progress.
#[returns(Option<VerifierSetResponse>)]
NextVerifierSet,
}
pub enum ProofStatus {
Pending,
Completed { execute_data: HexBinary }, // encoded data and proof sent to destination gateway
}
pub struct ProofResponse {
pub multisig_session_id: Uint64,
pub message_ids: Vec<CrossChainId>,
pub payload: Payload,
pub status: ProofStatus,
}
pub struct VerifierSetResponse {
pub id: String,
pub verifier_set: multisig::verifier_set::VerifierSet,
}
Events
pub enum Event {
ProofUnderConstruction {
destination_chain: ChainName,
payload_id: PayloadId,
multisig_session_id: Uint64,
msg_ids: Vec<CrossChainId>,
},
}
Proof construction graph
graph TD r[Relayer] subgraph Axelar b[Prover] g[Gateway] m[Multisig] end s[Signer] r--ConstructProof-->b b--OutgoingMessages-->g g-.->b b--StartSigningSession-->m b--Multisig-->m s--SubmitSignature-->m
Proof construction sequence diagram
sequenceDiagram
autonumber
participant Relayer
box LightYellow Axelar
participant Prover
participant Gateway
participant Multisig
end
actor Signers
Relayer->>+Prover: ExecuteMsg::ConstructProof
alt payload not created previously
Prover->>+Gateway: QueryMsg::OutgoingMessages
Gateway-->>-Prover: query result
alt newer VerifierSet exists
Prover->>Prover: update next VerifierSet
end
else previously created payload found
Prover->>Prover: retrieves payload from storage
end
Prover->>+Multisig: ExecuteMsg::StartSigningSession
Multisig-->>Signers: emit SigningStarted event
Multisig->>-Prover: reply with session ID
Prover-->>Relayer: emit ProofUnderConstruction event
deactivate Prover
loop Collect signatures
Signers->>+Multisig: signature collection
end
Multisig-->>-Relayer: emit SigningCompleted event
Relayer->>+Prover: QueryMsg::Proof
Prover->>+Multisig: QueryMsg::Multisig
Multisig-->>-Prover: reply with status, current signatures vector and snapshot
Prover-->>-Relayer: returns ProofResponse
- Relayer asks Prover contract to construct proof providing a list of cross chain ids.
- If no payload for the given messages was previously created, it queries the gateway for the messages to construct it.
- With the retrieved messages, the Prover contract transforms them into a payload digest that needs to be signed by the multisig.
- If a previous payload was found for the given message ids, the Prover retrieves it from storage instead of querying the gateway and building it again.
- The Multisig contract is called asking to sign the payload digest.
- Multisig emits event
SigningStartedindicating a new multisig session has started. - Multisig triggers a reply in Prover returning the newly created session ID which is then stored with the payload for reference.
- Prover contract emits event
ProofUnderConstructionwhich includes the ID of the proof being constructed. - Signers submit their signatures until threshold is reached.
- Multisig emits event indicating the multisig session has been completed.
- Relayer queries Prover for the proof, using the multisig session ID.
- Prover queries Multisig for the multisig session.
- Multisig replies with the multisig state, the list of collected signatures so far and the snapshot of participants.
- If the Multisig state is
Completed, the Prover finalizes constructing the proof and returns theProofResponsestruct which includes the proof itself and the data to be sent to the destination gateway. If the state is not completed, the Prover returns theProofResponsestruct with thestatusfield set toPending.
Update and confirm VerifierSet graph
graph TD r[Relayer] subgraph Axelar b[Prover] v[Voting Verifier] m[Multisig] s[Service Registry] end r--UpdateVerifierSet-->b b--ActiveVerifiers-->s b--RegisterVerifierSet-->m r--ConfirmVerifierSet-->b b--VerifierSetStatus-->v
Update and confirm VerifierSet sequence diagram
sequenceDiagram autonumber participant External Gateway participant Relayer box LightYellow Axelar participant Prover participant Service Registry participant Voting Verifier participant Multisig end actor Verifier actor Signers Relayer->>+Prover: ExecuteMsg::UpdateVerifierSet alt existing VerifierSet stored Prover->>+Service Registry: QueryMsg::ActiveVerifiers Service Registry-->>-Prover: save new VerifierSet as next VerifierSet Prover->>+Multisig: ExecuteMsg::StartSigningSession (for rotate signers message) loop Collect signatures Signers->>+Multisig: signature collection end end Relayer->>+Prover: QueryMsg::Proof Prover-->>-Relayer: returns ProofResponse (new verifier set signed by old verifier set) Relayer-->>External Gateway: send new VerifierSet to the gateway, signed by old VerifierSet External Gateway-->>+Relayer: emit SignersRotated event Relayer->>+Voting Verifier: ExecuteMsg::VerifyVerifierSet Verifier->>+External Gateway: look up SignersRotated event, verify event matches verifier set in poll Verifier->>+Voting Verifier: ExecuteMsg::Vote Relayer->>+Voting Verifier: ExecuteMsg::EndPoll Relayer->>+Prover: ExecuteMsg::ConfirmVerifierSet Prover->>+Voting Verifier: QueryMsg::VerifierSetStatus Voting Verifier-->>-Prover: true Prover->>+Multisig: ExecuteMsg::RegisterVerifierSet
- The Relayer calls Prover to update the
VerifierSet. - The Prover calls Service Registry to get a
VerifierSet. - If a newer
VerifierSetwas found, the newVerifierSetis stored as the nextVerifierSet. The prover creates payload for the new verifier set. - The Multisig contract is called asking to sign the binary message.
- Signers submit their signatures until threshold is reached.
- Relayer queries Prover for the proof, using the multisig session id.
- If the Multisig state is
Completed, the Prover finalizes constructing the proof and returns theProofResponsestruct which includes the proof itself and the data to be sent to the External Chain's gateway. If the state is not completed, the Prover returns theProofResponsestruct with thestatusfield set toPending. - Relayer sends proof and data to the External Gateway.
- The gateway on the External Gateway processes the commands in the data and emits event
SignersRotated. - The event
SignersRotatedpicked up by the Relayer, the Relayer calls Voting Verifier to create a poll. - The Verifiers see the
PollStartedevent and look up theSignersRotatedevent on the External Gateway and verify the event matches the verifier set in the poll. - The Verifiers then vote on whether the event matches the verifiers or not.
- The Relayer calls the Voting Verifier to end the poll and emit
PollEndedevent. - Once the poll is completed, the Relayer calls the Prover to confirm if the
VerifierSetwas updated. - The Prover queries the Voting Verifier to check if the
VerifierSetis confirmed. - The Voting Verifier returns that the
VerifierSetis confirmed. - The Prover stores the
VerifierSetin itself and in Multisig.