forked from scroll-tech/scroll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMultipleVersionRollupVerifier.sol
130 lines (100 loc) · 4.25 KB
/
MultipleVersionRollupVerifier.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-License-Identifier: MIT
pragma solidity =0.8.16;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IScrollChain} from "./IScrollChain.sol";
import {IRollupVerifier} from "../../libraries/verifier/IRollupVerifier.sol";
import {IZkEvmVerifier} from "../../libraries/verifier/IZkEvmVerifier.sol";
contract MultipleVersionRollupVerifier is IRollupVerifier, Ownable {
/**********
* Events *
**********/
/// @notice Emitted when the address of verifier is updated.
/// @param startBatchIndex The start batch index when the verifier will be used.
/// @param verifier The address of new verifier.
event UpdateVerifier(uint256 startBatchIndex, address verifier);
/***********
* Structs *
***********/
struct Verifier {
// The start batch index for the verifier.
uint64 startBatchIndex;
// The address of zkevm verifier.
address verifier;
}
/*************
* Variables *
*************/
/// @notice The list of legacy zkevm verifier, sorted by batchIndex in increasing order.
Verifier[] public legacyVerifiers;
/// @notice The lastest used zkevm verifier.
Verifier public latestVerifier;
/// @notice The address of ScrollChain contract.
address public scrollChain;
/***************
* Constructor *
***************/
constructor(address _verifier) {
require(_verifier != address(0), "zero verifier address");
latestVerifier.verifier = _verifier;
}
function initialize(address _scrollChain) external onlyOwner {
require(scrollChain == address(0), "initialized");
scrollChain = _scrollChain;
}
/*************************
* Public View Functions *
*************************/
/// @notice Return the number of legacy verifiers.
function legacyVerifiersLength() external view returns (uint256) {
return legacyVerifiers.length;
}
/// @notice Compute the verifier should be used for specific batch.
/// @param _batchIndex The batch index to query.
function getVerifier(uint256 _batchIndex) public view returns (address) {
// Normally, we will use the latest verifier.
Verifier memory _verifier = latestVerifier;
if (_verifier.startBatchIndex > _batchIndex) {
uint256 _length = legacyVerifiers.length;
// In most case, only last few verifier will be used by `ScrollChain`.
// So, we use linear search instead of binary search.
unchecked {
for (uint256 i = _length; i > 0; --i) {
_verifier = legacyVerifiers[i - 1];
if (_verifier.startBatchIndex <= _batchIndex) break;
}
}
}
return _verifier.verifier;
}
/*****************************
* Public Mutating Functions *
*****************************/
/// @inheritdoc IRollupVerifier
function verifyAggregateProof(
uint256 _batchIndex,
bytes calldata _aggrProof,
bytes32 _publicInputHash
) external view override {
address _verifier = getVerifier(_batchIndex);
IZkEvmVerifier(_verifier).verify(_aggrProof, _publicInputHash);
}
/************************
* Restricted Functions *
************************/
/// @notice Update the address of zkevm verifier.
/// @param _startBatchIndex The start batch index when the verifier will be used.
/// @param _verifier The address of new verifier.
function updateVerifier(uint64 _startBatchIndex, address _verifier) external onlyOwner {
require(_startBatchIndex > IScrollChain(scrollChain).lastFinalizedBatchIndex(), "start batch index finalized");
Verifier memory _latestVerifier = latestVerifier;
require(_startBatchIndex >= _latestVerifier.startBatchIndex, "start batch index too small");
require(_verifier != address(0), "zero verifier address");
if (_latestVerifier.startBatchIndex < _startBatchIndex) {
legacyVerifiers.push(_latestVerifier);
_latestVerifier.startBatchIndex = _startBatchIndex;
}
_latestVerifier.verifier = _verifier;
latestVerifier = _latestVerifier;
emit UpdateVerifier(_startBatchIndex, _verifier);
}
}