Aere Network public source. Everything here can be checked against the live chain (chain id 2800, https://rpc.aere.network). Scope note, stated up front rather than buried: consensus on chain 2800 is classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at the signature, precompile, account and transport layers. Nothing here makes the consensus post-quantum, and no document in it should be read as claiming so.
80 lines
3.5 KiB
Solidity
80 lines
3.5 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.23;
|
|
|
|
import "./IHypMailbox.sol";
|
|
|
|
/**
|
|
* @title MockHypMailbox — in-memory Mailbox used by the warp-route tests
|
|
* @notice Simulates Hyperlane's interchain dispatch/handle flow inside a
|
|
* single Hardhat test runner. Two mock-mailbox instances can be
|
|
* paired (setSister) so that a dispatch on instance A triggers a
|
|
* handle() call on instance B's enrolled recipient.
|
|
*
|
|
* @dev Only used in tests, never deployed to mainnet. Exposes:
|
|
* - quoteDispatch → returns a configurable flat fee
|
|
* - dispatch → forwards body to the sister Mailbox's
|
|
* recipient.handle() with origin = this.localDomain
|
|
* - localDomain → configurable per instance
|
|
*/
|
|
contract MockHypMailbox is IHypMailbox {
|
|
uint32 public override localDomain;
|
|
uint256 public fee = 0.001 ether;
|
|
|
|
MockHypMailbox public sister;
|
|
address public localRecipient; // The application contract on THIS Mailbox's chain that receives inbound messages.
|
|
|
|
event Dispatched(uint32 indexed destination, bytes32 indexed recipient, bytes body);
|
|
event Handled(uint32 indexed origin, bytes32 indexed sender, bytes body);
|
|
|
|
constructor(uint32 _localDomain) {
|
|
localDomain = _localDomain;
|
|
}
|
|
|
|
/// @notice Pair the two MockHypMailbox instances.
|
|
/// @param _sister The OTHER Mailbox (on the other "chain").
|
|
/// @param _localRecipient The application contract on OUR side that
|
|
/// should receive inbound .handle() calls.
|
|
function setSister(MockHypMailbox _sister, address _localRecipient) external {
|
|
sister = _sister;
|
|
localRecipient = _localRecipient;
|
|
}
|
|
|
|
function setFee(uint256 _fee) external { fee = _fee; }
|
|
|
|
function quoteDispatch(uint32, bytes32, bytes calldata) external view override returns (uint256) {
|
|
return fee;
|
|
}
|
|
|
|
function dispatch(
|
|
uint32 destinationDomain,
|
|
bytes32 recipientAddress,
|
|
bytes calldata messageBody
|
|
) external payable override returns (bytes32 messageId) {
|
|
require(msg.value >= fee, "MockMailbox: insufficient fee");
|
|
emit Dispatched(destinationDomain, recipientAddress, messageBody);
|
|
|
|
messageId = keccak256(abi.encode(localDomain, destinationDomain, recipientAddress, messageBody, block.timestamp));
|
|
|
|
// Delivery: msg.sender of dispatch is the application on OUR chain;
|
|
// we pass its bytes32-padded address as the `sender` field that the
|
|
// sister's recipient will check against its enrolled routers. The
|
|
// sister Mailbox actually performs the call so that recipient.handle()
|
|
// sees msg.sender == sister Mailbox (matching production behaviour).
|
|
if (address(sister) != address(0)) {
|
|
bytes32 ourSenderB32 = bytes32(uint256(uint160(msg.sender)));
|
|
sister.deliverInbound(localDomain, ourSenderB32, messageBody);
|
|
}
|
|
}
|
|
|
|
/// @dev Internal-cross-mailbox hook. Called by the SOURCE Mailbox; we
|
|
/// forward to our locally-configured recipient so it sees
|
|
/// msg.sender == us (the destination Mailbox), per production
|
|
/// Hyperlane semantics.
|
|
function deliverInbound(uint32 origin, bytes32 sender, bytes calldata body) external {
|
|
require(msg.sender == address(sister), "MockMailbox: not from sister");
|
|
require(localRecipient != address(0), "MockMailbox: no local recipient");
|
|
IHypMessageRecipient(localRecipient).handle(origin, sender, body);
|
|
emit Handled(origin, sender, body);
|
|
}
|
|
}
|