106 lines
3.0 KiB
Solidity
106 lines
3.0 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
/**
|
|
* @title MirrorRegistry
|
|
* @notice Stores Merkle commitment roots for DBIS/Alltra transaction mirroring to public mainnets.
|
|
* @dev submitCommit(chainId, startBlock, endBlock, root, uri, ts) + event CommitSubmitted.
|
|
* Publisher allowlist and optional rate limiting.
|
|
*/
|
|
contract MirrorRegistry {
|
|
address public admin;
|
|
bool public paused;
|
|
|
|
mapping(address => bool) public publishers;
|
|
uint256 public commitsCount;
|
|
uint256 public constant MAX_COMMITS_PER_BLOCK = 5;
|
|
uint256 public commitsThisBlock;
|
|
uint256 public lastBlock;
|
|
|
|
event CommitSubmitted(
|
|
uint256 indexed sourceChainId,
|
|
uint64 startBlock,
|
|
uint64 endBlock,
|
|
bytes32 root,
|
|
string uri,
|
|
uint64 ts
|
|
);
|
|
event AdminChanged(address indexed newAdmin);
|
|
event Paused();
|
|
event Unpaused();
|
|
event PublisherSet(address indexed publisher, bool allowed);
|
|
|
|
modifier onlyAdmin() {
|
|
require(msg.sender == admin, "only admin");
|
|
_;
|
|
}
|
|
|
|
modifier whenNotPaused() {
|
|
require(!paused, "paused");
|
|
_;
|
|
}
|
|
|
|
modifier onlyPublisher() {
|
|
require(publishers[msg.sender], "not publisher");
|
|
_;
|
|
}
|
|
|
|
constructor(address _admin) {
|
|
require(_admin != address(0), "zero admin");
|
|
admin = _admin;
|
|
publishers[_admin] = true;
|
|
}
|
|
|
|
function setAdmin(address newAdmin) external onlyAdmin {
|
|
require(newAdmin != address(0), "zero admin");
|
|
admin = newAdmin;
|
|
emit AdminChanged(newAdmin);
|
|
}
|
|
|
|
function pause() external onlyAdmin {
|
|
paused = true;
|
|
emit Paused();
|
|
}
|
|
|
|
function unpause() external onlyAdmin {
|
|
paused = false;
|
|
emit Unpaused();
|
|
}
|
|
|
|
function setPublisher(address publisher, bool allowed) external onlyAdmin {
|
|
publishers[publisher] = allowed;
|
|
emit PublisherSet(publisher, allowed);
|
|
}
|
|
|
|
/**
|
|
* @notice Submit a Merkle commitment for a block range on source chain (138 or 651940).
|
|
* @param sourceChainId Chain ID (e.g. 138, 651940).
|
|
* @param startBlock Start block (inclusive).
|
|
* @param endBlock End block (inclusive).
|
|
* @param root Merkle root of leaves (tx_hash, block_number, receipt_root, payload_hash, sal_hash).
|
|
* @param uri URI to leaf set (e.g. S3 or API).
|
|
* @param ts Timestamp of commit (epoch seconds).
|
|
*/
|
|
function submitCommit(
|
|
uint256 sourceChainId,
|
|
uint64 startBlock,
|
|
uint64 endBlock,
|
|
bytes32 root,
|
|
string calldata uri,
|
|
uint64 ts
|
|
) external onlyPublisher whenNotPaused {
|
|
require(startBlock <= endBlock, "invalid range");
|
|
require(root != bytes32(0), "zero root");
|
|
|
|
if (block.number != lastBlock) {
|
|
lastBlock = block.number;
|
|
commitsThisBlock = 0;
|
|
}
|
|
require(commitsThisBlock < MAX_COMMITS_PER_BLOCK, "rate limit");
|
|
commitsThisBlock++;
|
|
commitsCount++;
|
|
|
|
emit CommitSubmitted(sourceChainId, startBlock, endBlock, root, uri, ts);
|
|
}
|
|
}
|