# NEBRA <> Axelar ## Axelar Protocol Brief Description - Axelar General Message Passing (GMP) is a cross-chain messaging system. It is secured by a multisig of staked signers. - The core API for the Axelar's GMP system is given by: ```solidity // Initiate a cross-chain contract call function callContract(string calldata destinationChain, string calldata contractAddress, bytes calldata payload) external; // Record approvals for a set of messages, signed off by Axelar verifiers function approveMessages(Message[] calldata messages, Proof calldata proof) external; // Validate a message approval, and mark it as used function validateMessage(string calldata sourceChain, string calldata messageId, string calldata sourceAddress, bytes32 payloadHash) external returns (bool); // Query if a message is approved function isMessageApproved(string calldata sourceChain, string calldata messageId, string calldata sourceAddress, address contractAddress, bytes32 payloadHash) external view returns (bool); // Query if a message has been executed function isMessageExecuted(string calldata sourceChain, string calldata messageId) external view returns (bool); // Rotate to a new set of Axelar verifiers, signed off by the current Axelar verifiers function rotateSigners(WeightedSigners memory newSigners, Proof calldata proof) external; // Called by relayer to execute payload for approved message function execute(string calldata sourceChain, string calldata messageId, string calldata sourceAddress, bytes calldata payload) external; ``` - A source contract calls a destination contract on a different chain via the following flow: - `callContract` function is called on source contract. This function call has the payload to be executed on the destination contract. A`CallContract` event is emitted, indicating there is a message to be signed. - Signers in multisig pickup this and other `CallContract` events and sign a batch of associated messages. - The resulting signature, along with the underlying batch of messages, is submitted to `approveMessages` function on the destination chain. `approveMessages` verifies the signature and marks the messages as approved. - A relayer can then call `execute` for a signed message on the destination contract. This will execute the bytecode payload associated with the message. Inside this process, the destination contract will call `validateMessage` to check whether the message was approved, and if so, mark it as executed to prevent replay attacks. - The entire flow (taken from [Axelar docs](https://github.com/axelarnetwork/axelar-gmp-sdk-solidity/blob/v5.9.0/contracts/gateway/INTEGRATION.md)) is shown in the diagram below: ![image](https://hackmd.io/_uploads/SJPgMd3CC.png) ## How Axelar Wants to Use ZKPs/NEBRA - Suppose a batch of messages was signed by `S` signers. Then, `approveMessages` consists of verifying `S` signatures on the destination chain. - Axelar would like to know whether verifying the `S` signatures inside a ZKP is *cheaper* than verifying them directly. ## TODOs for NEBRA Team - [ ] Benchmark the gas cost of Axelar's `approveMessages` function for $S \in \{1,2,...,100\}$. - [ ] Write a circuit that does batch signature verification (and perhaps some other Axelar specific logic). - [ ] Update Axelar's `approveMessages` function to use this circuit. - [ ] Benchmark gas cost of this updated `approveMessages` function (which now uses ZKPs) for $S \in \{1,2,...,100\}$. | S | gas cost now | gas cost (with zk) | gas cost (zk + UPA) | gas cost (zk + UPA offchain) | | -------- | -------- | -------- | -------- |-----| | 4 | | | | | | 8|||| | 16 |||| | 32||||