@arbitrum/nitro-contracts 1.0.0-beta.5 → 1.0.0-beta.8
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +6 -2
- package/src/bridge/Bridge.sol +138 -32
- package/src/bridge/IBridge.sol +34 -14
- package/src/bridge/IDelayedMessageProvider.sol +15 -0
- package/src/bridge/IInbox.sol +8 -19
- package/src/bridge/IOutbox.sol +43 -23
- package/src/bridge/IOwnable.sol +10 -0
- package/src/bridge/ISequencerInbox.sol +30 -32
- package/src/bridge/Inbox.sol +133 -35
- package/src/bridge/Outbox.sol +145 -33
- package/src/bridge/SequencerInbox.sol +179 -60
- package/src/challenge/ChallengeLib.sol +0 -2
- package/src/challenge/ChallengeManager.sol +4 -8
- package/src/challenge/IChallengeManager.sol +1 -1
- package/src/libraries/Error.sol +113 -0
- package/src/libraries/IGasRefunder.sol +15 -14
- package/src/libraries/MerkleLib.sol +11 -2
- package/src/libraries/MessageTypes.sol +1 -0
- package/src/mocks/BridgeStub.sol +69 -21
- package/src/mocks/InboxStub.sol +2 -0
- package/src/mocks/SequencerInboxStub.sol +10 -8
- package/src/mocks/Simple.sol +8 -0
- package/src/node-interface/NodeInterface.sol +62 -4
- package/src/osp/IOneStepProver.sol +1 -2
- package/src/osp/OneStepProver0.sol +1 -87
- package/src/osp/OneStepProverHostIo.sol +5 -6
- package/src/osp/OneStepProverMath.sol +37 -27
- package/src/osp/OneStepProverMemory.sol +3 -4
- package/src/precompiles/ArbAggregator.sol +23 -33
- package/src/precompiles/ArbBLS.sol +1 -43
- package/src/precompiles/ArbGasInfo.sol +10 -19
- package/src/precompiles/ArbOwner.sol +21 -15
- package/src/precompiles/ArbRetryableTx.sol +10 -1
- package/src/precompiles/ArbSys.sol +4 -4
- package/src/precompiles/ArbosActs.sol +9 -2
- package/src/rollup/BridgeCreator.sol +23 -28
- package/src/rollup/IRollupCore.sol +3 -3
- package/src/rollup/{IRollupEventBridge.sol → IRollupEventInbox.sol} +2 -2
- package/src/rollup/IRollupLogic.sol +21 -18
- package/src/rollup/RollupAdminLogic.sol +72 -34
- package/src/rollup/RollupCore.sol +20 -9
- package/src/rollup/RollupCreator.sol +21 -11
- package/src/rollup/{RollupEventBridge.sol → RollupEventInbox.sol} +10 -10
- package/src/rollup/RollupLib.sol +21 -5
- package/src/rollup/RollupUserLogic.sol +10 -18
- package/src/rollup/ValidatorWallet.sol +125 -8
- package/src/rollup/ValidatorWalletCreator.sol +11 -6
- package/src/state/Deserialize.sol +3 -22
- package/src/state/GlobalState.sol +7 -0
- package/src/state/Instructions.sol +2 -10
- package/src/state/Machine.sol +0 -4
- package/src/state/ModuleMemory.sol +2 -1
- package/src/state/Value.sol +2 -3
- package/src/test-helpers/BridgeTester.sol +233 -0
- package/src/test-helpers/InterfaceCompatibilityTester.sol +11 -0
- package/src/test-helpers/OutboxWithoutOptTester.sol +214 -0
- package/src/test-helpers/RollupMock.sol +21 -0
- package/src/bridge/IMessageProvider.sol +0 -11
- package/src/state/PcStack.sol +0 -32
package/src/mocks/BridgeStub.sol
CHANGED
@@ -14,19 +14,28 @@ contract BridgeStub is IBridge {
|
|
14
14
|
bool allowed;
|
15
15
|
}
|
16
16
|
|
17
|
-
mapping(address => InOutInfo) private
|
17
|
+
mapping(address => InOutInfo) private allowedDelayedInboxesMap;
|
18
18
|
//mapping(address => InOutInfo) private allowedOutboxesMap;
|
19
19
|
|
20
|
-
address[] public
|
20
|
+
address[] public allowedDelayedInboxList;
|
21
21
|
address[] public allowedOutboxList;
|
22
22
|
|
23
23
|
address public override activeOutbox;
|
24
24
|
|
25
25
|
// Accumulator for delayed inbox; tail represents hash of the current state; each element represents the inclusion of a new message.
|
26
|
-
bytes32[] public override
|
26
|
+
bytes32[] public override delayedInboxAccs;
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
bytes32[] public override sequencerInboxAccs;
|
29
|
+
|
30
|
+
address public sequencerInbox;
|
31
|
+
|
32
|
+
function setSequencerInbox(address _sequencerInbox) external override {
|
33
|
+
sequencerInbox = _sequencerInbox;
|
34
|
+
emit SequencerInboxUpdated(_sequencerInbox);
|
35
|
+
}
|
36
|
+
|
37
|
+
function allowedDelayedInboxes(address inbox) external view override returns (bool) {
|
38
|
+
return allowedDelayedInboxesMap[inbox].allowed;
|
30
39
|
}
|
31
40
|
|
32
41
|
function allowedOutboxes(address) external pure override returns (bool) {
|
@@ -38,9 +47,9 @@ contract BridgeStub is IBridge {
|
|
38
47
|
address sender,
|
39
48
|
bytes32 messageDataHash
|
40
49
|
) external payable override returns (uint256) {
|
41
|
-
require(
|
50
|
+
require(allowedDelayedInboxesMap[msg.sender].allowed, "NOT_FROM_INBOX");
|
42
51
|
return
|
43
|
-
|
52
|
+
addMessageToDelayedAccumulator(
|
44
53
|
kind,
|
45
54
|
sender,
|
46
55
|
block.number,
|
@@ -50,7 +59,34 @@ contract BridgeStub is IBridge {
|
|
50
59
|
);
|
51
60
|
}
|
52
61
|
|
53
|
-
function
|
62
|
+
function enqueueSequencerMessage(bytes32 dataHash, uint256 afterDelayedMessagesRead)
|
63
|
+
external
|
64
|
+
returns (
|
65
|
+
uint256 seqMessageIndex,
|
66
|
+
bytes32 beforeAcc,
|
67
|
+
bytes32 delayedAcc,
|
68
|
+
bytes32 acc
|
69
|
+
)
|
70
|
+
{
|
71
|
+
seqMessageIndex = sequencerInboxAccs.length;
|
72
|
+
if (sequencerInboxAccs.length > 0) {
|
73
|
+
beforeAcc = sequencerInboxAccs[sequencerInboxAccs.length - 1];
|
74
|
+
}
|
75
|
+
if (afterDelayedMessagesRead > 0) {
|
76
|
+
delayedAcc = delayedInboxAccs[afterDelayedMessagesRead - 1];
|
77
|
+
}
|
78
|
+
acc = keccak256(abi.encodePacked(beforeAcc, dataHash, delayedAcc));
|
79
|
+
sequencerInboxAccs.push(acc);
|
80
|
+
}
|
81
|
+
|
82
|
+
function submitBatchSpendingReport(address batchPoster, bytes32 dataHash)
|
83
|
+
external
|
84
|
+
returns (uint256)
|
85
|
+
{
|
86
|
+
// TODO: implement stub
|
87
|
+
}
|
88
|
+
|
89
|
+
function addMessageToDelayedAccumulator(
|
54
90
|
uint8,
|
55
91
|
address,
|
56
92
|
uint256,
|
@@ -58,7 +94,7 @@ contract BridgeStub is IBridge {
|
|
58
94
|
uint256,
|
59
95
|
bytes32 messageDataHash
|
60
96
|
) internal returns (uint256) {
|
61
|
-
uint256 count =
|
97
|
+
uint256 count = delayedInboxAccs.length;
|
62
98
|
bytes32 messageHash = Messages.messageHash(
|
63
99
|
0,
|
64
100
|
address(uint160(0)),
|
@@ -70,9 +106,9 @@ contract BridgeStub is IBridge {
|
|
70
106
|
);
|
71
107
|
bytes32 prevAcc = 0;
|
72
108
|
if (count > 0) {
|
73
|
-
prevAcc =
|
109
|
+
prevAcc = delayedInboxAccs[count - 1];
|
74
110
|
}
|
75
|
-
|
111
|
+
delayedInboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash));
|
76
112
|
return count;
|
77
113
|
}
|
78
114
|
|
@@ -84,21 +120,23 @@ contract BridgeStub is IBridge {
|
|
84
120
|
revert("NOT_IMPLEMENTED");
|
85
121
|
}
|
86
122
|
|
87
|
-
function
|
88
|
-
InOutInfo storage info =
|
123
|
+
function setDelayedInbox(address inbox, bool enabled) external override {
|
124
|
+
InOutInfo storage info = allowedDelayedInboxesMap[inbox];
|
89
125
|
bool alreadyEnabled = info.allowed;
|
90
126
|
emit InboxToggle(inbox, enabled);
|
91
127
|
if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) {
|
92
128
|
return;
|
93
129
|
}
|
94
130
|
if (enabled) {
|
95
|
-
|
96
|
-
|
131
|
+
allowedDelayedInboxesMap[inbox] = InOutInfo(allowedDelayedInboxList.length, true);
|
132
|
+
allowedDelayedInboxList.push(inbox);
|
97
133
|
} else {
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
134
|
+
allowedDelayedInboxList[info.index] = allowedDelayedInboxList[
|
135
|
+
allowedDelayedInboxList.length - 1
|
136
|
+
];
|
137
|
+
allowedDelayedInboxesMap[allowedDelayedInboxList[info.index]].index = info.index;
|
138
|
+
allowedDelayedInboxList.pop();
|
139
|
+
delete allowedDelayedInboxesMap[inbox];
|
102
140
|
}
|
103
141
|
}
|
104
142
|
|
@@ -109,7 +147,17 @@ contract BridgeStub is IBridge {
|
|
109
147
|
revert("NOT_IMPLEMENTED");
|
110
148
|
}
|
111
149
|
|
112
|
-
function
|
113
|
-
return
|
150
|
+
function delayedMessageCount() external view override returns (uint256) {
|
151
|
+
return delayedInboxAccs.length;
|
152
|
+
}
|
153
|
+
|
154
|
+
function sequencerMessageCount() external view override returns (uint256) {
|
155
|
+
return sequencerInboxAccs.length;
|
114
156
|
}
|
157
|
+
|
158
|
+
function rollup() external pure override returns (IOwnable) {
|
159
|
+
revert("NOT_IMPLEMENTED");
|
160
|
+
}
|
161
|
+
|
162
|
+
function acceptFundsFromOldBridge() external payable {}
|
115
163
|
}
|
package/src/mocks/InboxStub.sol
CHANGED
@@ -8,24 +8,26 @@ import "../bridge/SequencerInbox.sol";
|
|
8
8
|
|
9
9
|
contract SequencerInboxStub is SequencerInbox {
|
10
10
|
constructor(
|
11
|
-
IBridge
|
11
|
+
IBridge bridge_,
|
12
12
|
address sequencer_,
|
13
13
|
ISequencerInbox.MaxTimeVariation memory maxTimeVariation_
|
14
14
|
) {
|
15
|
-
|
16
|
-
rollup = msg.sender;
|
15
|
+
bridge = bridge_;
|
16
|
+
rollup = IOwnable(msg.sender);
|
17
17
|
maxTimeVariation = maxTimeVariation_;
|
18
18
|
isBatchPoster[sequencer_] = true;
|
19
19
|
}
|
20
20
|
|
21
21
|
function addInitMessage() external {
|
22
22
|
(bytes32 dataHash, TimeBounds memory timeBounds) = formEmptyDataHash(0);
|
23
|
-
(
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
(
|
24
|
+
uint256 sequencerMessageCount,
|
25
|
+
bytes32 beforeAcc,
|
26
|
+
bytes32 delayedAcc,
|
27
|
+
bytes32 afterAcc
|
28
|
+
) = addSequencerL2BatchImpl(dataHash, 0, 0);
|
27
29
|
emit SequencerBatchDelivered(
|
28
|
-
|
30
|
+
sequencerMessageCount,
|
29
31
|
beforeAcc,
|
30
32
|
afterAcc,
|
31
33
|
delayedAcc,
|
package/src/mocks/Simple.sol
CHANGED
@@ -4,10 +4,13 @@
|
|
4
4
|
|
5
5
|
pragma solidity ^0.8.0;
|
6
6
|
|
7
|
+
import "../precompiles/ArbRetryableTx.sol";
|
8
|
+
|
7
9
|
contract Simple {
|
8
10
|
uint64 public counter;
|
9
11
|
|
10
12
|
event CounterEvent(uint64 count);
|
13
|
+
event RedeemedEvent(address caller, address redeemer);
|
11
14
|
event NullEvent();
|
12
15
|
|
13
16
|
function increment() external {
|
@@ -19,6 +22,11 @@ contract Simple {
|
|
19
22
|
emit CounterEvent(counter);
|
20
23
|
}
|
21
24
|
|
25
|
+
function incrementRedeem() external {
|
26
|
+
counter++;
|
27
|
+
emit RedeemedEvent(msg.sender, ArbRetryableTx(address(110)).getCurrentRedeemer());
|
28
|
+
}
|
29
|
+
|
22
30
|
function emitNullEvent() external {
|
23
31
|
emit NullEvent();
|
24
32
|
}
|
@@ -11,7 +11,8 @@ pragma solidity >=0.4.21 <0.9.0;
|
|
11
11
|
*/
|
12
12
|
interface NodeInterface {
|
13
13
|
/**
|
14
|
-
* @notice Estimate the cost of putting a message in the L2 inbox that is reexecuted
|
14
|
+
* @notice Estimate the cost of putting a message in the L2 inbox that is reexecuted.
|
15
|
+
* @dev Use eth_estimateGas to call.
|
15
16
|
* @param sender sender of the L1 and L2 transaction
|
16
17
|
* @param deposit amount to deposit to sender in L2
|
17
18
|
* @param to destination L2 contract address
|
@@ -31,7 +32,8 @@ interface NodeInterface {
|
|
31
32
|
) external;
|
32
33
|
|
33
34
|
/**
|
34
|
-
* @notice Constructs an outbox proof of an l2->l1 send's existence in the outbox accumulator
|
35
|
+
* @notice Constructs an outbox proof of an l2->l1 send's existence in the outbox accumulator.
|
36
|
+
* @dev Use eth_call to call.
|
35
37
|
* @param size the number of elements in the accumulator
|
36
38
|
* @param leaf the position of the send in the accumulator
|
37
39
|
* @return send the l2->l1 send's hash
|
@@ -48,8 +50,9 @@ interface NodeInterface {
|
|
48
50
|
);
|
49
51
|
|
50
52
|
/**
|
51
|
-
* @notice Finds the L1 batch containing a requested L2 block, reverting if none does
|
52
|
-
*
|
53
|
+
* @notice Finds the L1 batch containing a requested L2 block, reverting if none does.
|
54
|
+
* Use eth_call to call.
|
55
|
+
* Throws if block doesn't exist, or if block number is 0. Use eth_call
|
53
56
|
* @param blockNum The L2 block being queried
|
54
57
|
* @return batch The L1 block containing the requested L2 block
|
55
58
|
*/
|
@@ -60,8 +63,63 @@ interface NodeInterface {
|
|
60
63
|
* This gets the number of L1 confirmations for the input message producing the L2 block,
|
61
64
|
* which happens well before the L1 rollup contract confirms the L2 block.
|
62
65
|
* Throws if block doesnt exist in the L2 chain.
|
66
|
+
* @dev Use eth_call to call.
|
63
67
|
* @param blockHash The hash of the L2 block being queried
|
64
68
|
* @return confirmations The number of L1 confirmations the sequencer batch has. Returns 0 if block not yet included in an L1 batch.
|
65
69
|
*/
|
66
70
|
function getL1Confirmations(bytes32 blockHash) external view returns (uint64 confirmations);
|
71
|
+
|
72
|
+
/**
|
73
|
+
* @notice Same as native gas estimation, but with additional info on the l1 costs.
|
74
|
+
* @dev Use eth_call to call.
|
75
|
+
* @param data the tx's calldata. Everything else like "From" and "Gas" are copied over
|
76
|
+
* @param to the tx's "To" (ignored when contractCreation is true)
|
77
|
+
* @param contractCreation whether "To" is omitted
|
78
|
+
* @return gasEstimate an estimate of the total amount of gas needed for this tx
|
79
|
+
* @return gasEstimateForL1 an estimate of the amount of gas needed for the l1 component of this tx
|
80
|
+
* @return baseFee the l2 base fee
|
81
|
+
* @return l1BaseFeeEstimate ArbOS's l1 estimate of the l1 base fee
|
82
|
+
*/
|
83
|
+
function gasEstimateComponents(
|
84
|
+
address to,
|
85
|
+
bool contractCreation,
|
86
|
+
bytes calldata data
|
87
|
+
)
|
88
|
+
external
|
89
|
+
payable
|
90
|
+
returns (
|
91
|
+
uint64 gasEstimate,
|
92
|
+
uint64 gasEstimateForL1,
|
93
|
+
uint256 baseFee,
|
94
|
+
uint256 l1BaseFeeEstimate
|
95
|
+
);
|
96
|
+
|
97
|
+
/**
|
98
|
+
* @notice Returns the proof necessary to redeem a message
|
99
|
+
* @param batchNum index of outbox entry (i.e., outgoing messages Merkle root) in array of outbox entries
|
100
|
+
* @param index index of outgoing message in outbox entry
|
101
|
+
* @return proof Merkle proof of message inclusion in outbox entry
|
102
|
+
* @return path Merkle path to message
|
103
|
+
* @return l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)
|
104
|
+
* @return l1Dest destination address for L1 contract call
|
105
|
+
* @return l2Block l2 block number at which sendTxToL1 call was made
|
106
|
+
* @return l1Block l1 block number at which sendTxToL1 call was made
|
107
|
+
* @return timestamp l2 Timestamp at which sendTxToL1 call was made
|
108
|
+
* @return amount value in L1 message in wei
|
109
|
+
* @return calldataForL1 abi-encoded L1 message data
|
110
|
+
*/
|
111
|
+
function legacyLookupMessageBatchProof(uint256 batchNum, uint64 index)
|
112
|
+
external
|
113
|
+
view
|
114
|
+
returns (
|
115
|
+
bytes32[] memory proof,
|
116
|
+
uint256 path,
|
117
|
+
address l2Sender,
|
118
|
+
address l1Dest,
|
119
|
+
uint256 l2Block,
|
120
|
+
uint256 l1Block,
|
121
|
+
uint256 timestamp,
|
122
|
+
uint256 amount,
|
123
|
+
bytes memory calldataForL1
|
124
|
+
);
|
67
125
|
}
|
@@ -12,7 +12,6 @@ import "./IOneStepProver.sol";
|
|
12
12
|
|
13
13
|
contract OneStepProver0 is IOneStepProver {
|
14
14
|
using MerkleProofLib for MerkleProof;
|
15
|
-
using PcStackLib for PcStack;
|
16
15
|
using StackFrameLib for StackFrameWindow;
|
17
16
|
using ValueLib for Value;
|
18
17
|
using ValueStackLib for ValueStack;
|
@@ -51,8 +50,6 @@ contract OneStepProver0 is IOneStepProver {
|
|
51
50
|
ty = ValueType.F32;
|
52
51
|
} else if (opcode == Instructions.F64_CONST) {
|
53
52
|
ty = ValueType.F64;
|
54
|
-
} else if (opcode == Instructions.PUSH_STACK_BOUNDARY) {
|
55
|
-
ty = ValueType.STACK_BOUNDARY;
|
56
53
|
} else {
|
57
54
|
revert("CONST_PUSH_INVALID_OPCODE");
|
58
55
|
}
|
@@ -86,39 +83,6 @@ contract OneStepProver0 is IOneStepProver {
|
|
86
83
|
}
|
87
84
|
}
|
88
85
|
|
89
|
-
function executeBlock(
|
90
|
-
Machine memory mach,
|
91
|
-
Module memory,
|
92
|
-
Instruction calldata inst,
|
93
|
-
bytes calldata
|
94
|
-
) internal pure {
|
95
|
-
uint32 targetPc = uint32(inst.argumentData);
|
96
|
-
require(targetPc == inst.argumentData, "BAD_BLOCK_PC");
|
97
|
-
mach.blockStack.push(targetPc);
|
98
|
-
}
|
99
|
-
|
100
|
-
function executeBranch(
|
101
|
-
Machine memory mach,
|
102
|
-
Module memory,
|
103
|
-
Instruction calldata,
|
104
|
-
bytes calldata
|
105
|
-
) internal pure {
|
106
|
-
mach.functionPc = mach.blockStack.pop();
|
107
|
-
}
|
108
|
-
|
109
|
-
function executeBranchIf(
|
110
|
-
Machine memory mach,
|
111
|
-
Module memory,
|
112
|
-
Instruction calldata,
|
113
|
-
bytes calldata
|
114
|
-
) internal pure {
|
115
|
-
uint32 cond = mach.valueStack.pop().assumeI32();
|
116
|
-
if (cond != 0) {
|
117
|
-
// Jump to target
|
118
|
-
mach.functionPc = mach.blockStack.pop();
|
119
|
-
}
|
120
|
-
}
|
121
|
-
|
122
86
|
function executeReturn(
|
123
87
|
Machine memory mach,
|
124
88
|
Module memory,
|
@@ -419,27 +383,6 @@ contract OneStepProver0 is IOneStepProver {
|
|
419
383
|
);
|
420
384
|
}
|
421
385
|
|
422
|
-
function executeEndBlock(
|
423
|
-
Machine memory mach,
|
424
|
-
Module memory,
|
425
|
-
Instruction calldata,
|
426
|
-
bytes calldata
|
427
|
-
) internal pure {
|
428
|
-
mach.blockStack.pop();
|
429
|
-
}
|
430
|
-
|
431
|
-
function executeEndBlockIf(
|
432
|
-
Machine memory mach,
|
433
|
-
Module memory,
|
434
|
-
Instruction calldata,
|
435
|
-
bytes calldata
|
436
|
-
) internal pure {
|
437
|
-
uint32 cond = mach.valueStack.peek().assumeI32();
|
438
|
-
if (cond != 0) {
|
439
|
-
mach.blockStack.pop();
|
440
|
-
}
|
441
|
-
}
|
442
|
-
|
443
386
|
function executeInitFrame(
|
444
387
|
Machine memory mach,
|
445
388
|
Module memory,
|
@@ -476,20 +419,6 @@ contract OneStepProver0 is IOneStepProver {
|
|
476
419
|
}
|
477
420
|
}
|
478
421
|
|
479
|
-
function executeIsStackBoundary(
|
480
|
-
Machine memory mach,
|
481
|
-
Module memory,
|
482
|
-
Instruction calldata,
|
483
|
-
bytes calldata
|
484
|
-
) internal pure {
|
485
|
-
Value memory val = mach.valueStack.pop();
|
486
|
-
uint32 newContents = 0;
|
487
|
-
if (val.valueType == ValueType.STACK_BOUNDARY) {
|
488
|
-
newContents = 1;
|
489
|
-
}
|
490
|
-
mach.valueStack.push(ValueLib.newI32(newContents));
|
491
|
-
}
|
492
|
-
|
493
422
|
function executeDup(
|
494
423
|
Machine memory mach,
|
495
424
|
Module memory,
|
@@ -519,12 +448,6 @@ contract OneStepProver0 is IOneStepProver {
|
|
519
448
|
impl = executeUnreachable;
|
520
449
|
} else if (opcode == Instructions.NOP) {
|
521
450
|
impl = executeNop;
|
522
|
-
} else if (opcode == Instructions.BLOCK) {
|
523
|
-
impl = executeBlock;
|
524
|
-
} else if (opcode == Instructions.BRANCH) {
|
525
|
-
impl = executeBranch;
|
526
|
-
} else if (opcode == Instructions.BRANCH_IF) {
|
527
|
-
impl = executeBranchIf;
|
528
451
|
} else if (opcode == Instructions.RETURN) {
|
529
452
|
impl = executeReturn;
|
530
453
|
} else if (opcode == Instructions.CALL) {
|
@@ -535,10 +458,6 @@ contract OneStepProver0 is IOneStepProver {
|
|
535
458
|
impl = executeCallerModuleInternalCall;
|
536
459
|
} else if (opcode == Instructions.CALL_INDIRECT) {
|
537
460
|
impl = executeCallIndirect;
|
538
|
-
} else if (opcode == Instructions.END_BLOCK) {
|
539
|
-
impl = executeEndBlock;
|
540
|
-
} else if (opcode == Instructions.END_BLOCK_IF) {
|
541
|
-
impl = executeEndBlockIf;
|
542
461
|
} else if (opcode == Instructions.ARBITRARY_JUMP) {
|
543
462
|
impl = executeArbitraryJump;
|
544
463
|
} else if (opcode == Instructions.ARBITRARY_JUMP_IF) {
|
@@ -557,18 +476,13 @@ contract OneStepProver0 is IOneStepProver {
|
|
557
476
|
impl = executeDrop;
|
558
477
|
} else if (opcode == Instructions.SELECT) {
|
559
478
|
impl = executeSelect;
|
560
|
-
} else if (
|
561
|
-
(opcode >= Instructions.I32_CONST && opcode <= Instructions.F64_CONST) ||
|
562
|
-
opcode == Instructions.PUSH_STACK_BOUNDARY
|
563
|
-
) {
|
479
|
+
} else if (opcode >= Instructions.I32_CONST && opcode <= Instructions.F64_CONST) {
|
564
480
|
impl = executeConstPush;
|
565
481
|
} else if (
|
566
482
|
opcode == Instructions.MOVE_FROM_STACK_TO_INTERNAL ||
|
567
483
|
opcode == Instructions.MOVE_FROM_INTERNAL_TO_STACK
|
568
484
|
) {
|
569
485
|
impl = executeMoveInternal;
|
570
|
-
} else if (opcode == Instructions.IS_STACK_BOUNDARY) {
|
571
|
-
impl = executeIsStackBoundary;
|
572
486
|
} else if (opcode == Instructions.DUP) {
|
573
487
|
impl = executeDup;
|
574
488
|
} else {
|
@@ -10,7 +10,6 @@ import "../state/Deserialize.sol";
|
|
10
10
|
import "./IOneStepProver.sol";
|
11
11
|
import "../bridge/Messages.sol";
|
12
12
|
import "../bridge/IBridge.sol";
|
13
|
-
import "../bridge/ISequencerInbox.sol";
|
14
13
|
|
15
14
|
contract OneStepProverHostIo is IOneStepProver {
|
16
15
|
using GlobalStateLib for GlobalState;
|
@@ -165,13 +164,13 @@ contract OneStepProverHostIo is IOneStepProver {
|
|
165
164
|
bytes32 delayedAcc;
|
166
165
|
|
167
166
|
if (msgIndex > 0) {
|
168
|
-
beforeAcc = execCtx.
|
167
|
+
beforeAcc = execCtx.bridge.sequencerInboxAccs(msgIndex - 1);
|
169
168
|
}
|
170
169
|
if (afterDelayedMsg > 0) {
|
171
|
-
delayedAcc = execCtx.
|
170
|
+
delayedAcc = execCtx.bridge.delayedInboxAccs(afterDelayedMsg - 1);
|
172
171
|
}
|
173
172
|
bytes32 acc = keccak256(abi.encodePacked(beforeAcc, messageHash, delayedAcc));
|
174
|
-
require(acc == execCtx.
|
173
|
+
require(acc == execCtx.bridge.sequencerInboxAccs(msgIndex), "BAD_SEQINBOX_MESSAGE");
|
175
174
|
return true;
|
176
175
|
}
|
177
176
|
|
@@ -185,7 +184,7 @@ contract OneStepProverHostIo is IOneStepProver {
|
|
185
184
|
bytes32 beforeAcc;
|
186
185
|
|
187
186
|
if (msgIndex > 0) {
|
188
|
-
beforeAcc = execCtx.
|
187
|
+
beforeAcc = execCtx.bridge.delayedInboxAccs(msgIndex - 1);
|
189
188
|
}
|
190
189
|
|
191
190
|
bytes32 messageDataHash = keccak256(message[DELAYED_HEADER_LEN:]);
|
@@ -198,7 +197,7 @@ contract OneStepProverHostIo is IOneStepProver {
|
|
198
197
|
);
|
199
198
|
bytes32 acc = Messages.accumulateInboxMessage(beforeAcc, messageHash);
|
200
199
|
|
201
|
-
require(acc == execCtx.
|
200
|
+
require(acc == execCtx.bridge.delayedInboxAccs(msgIndex), "BAD_DELAYED_MESSAGE");
|
202
201
|
return true;
|
203
202
|
}
|
204
203
|
|
@@ -210,38 +210,38 @@ contract OneStepProverMath is IOneStepProver {
|
|
210
210
|
uint64 a,
|
211
211
|
uint64 b,
|
212
212
|
uint16 opcodeOffset
|
213
|
-
) internal pure returns (uint64) {
|
213
|
+
) internal pure returns (uint64, bool) {
|
214
214
|
unchecked {
|
215
215
|
if (opcodeOffset == 0) {
|
216
216
|
// add
|
217
|
-
return a + b;
|
217
|
+
return (a + b, false);
|
218
218
|
} else if (opcodeOffset == 1) {
|
219
219
|
// sub
|
220
|
-
return a - b;
|
220
|
+
return (a - b, false);
|
221
221
|
} else if (opcodeOffset == 2) {
|
222
222
|
// mul
|
223
|
-
return a * b;
|
223
|
+
return (a * b, false);
|
224
224
|
} else if (opcodeOffset == 4) {
|
225
225
|
// div_u
|
226
226
|
if (b == 0) {
|
227
|
-
return 0;
|
227
|
+
return (0, true);
|
228
228
|
}
|
229
|
-
return a / b;
|
229
|
+
return (a / b, false);
|
230
230
|
} else if (opcodeOffset == 6) {
|
231
231
|
// rem_u
|
232
232
|
if (b == 0) {
|
233
|
-
return 0;
|
233
|
+
return (0, true);
|
234
234
|
}
|
235
|
-
return a % b;
|
235
|
+
return (a % b, false);
|
236
236
|
} else if (opcodeOffset == 7) {
|
237
237
|
// and
|
238
|
-
return a & b;
|
238
|
+
return (a & b, false);
|
239
239
|
} else if (opcodeOffset == 8) {
|
240
240
|
// or
|
241
|
-
return a | b;
|
241
|
+
return (a | b, false);
|
242
242
|
} else if (opcodeOffset == 9) {
|
243
243
|
// xor
|
244
|
-
return a ^ b;
|
244
|
+
return (a ^ b, false);
|
245
245
|
} else {
|
246
246
|
revert("INVALID_GENERIC_BIN_OP");
|
247
247
|
}
|
@@ -263,18 +263,18 @@ contract OneStepProverMath is IOneStepProver {
|
|
263
263
|
unchecked {
|
264
264
|
if (opcodeOffset == 3) {
|
265
265
|
// div_s
|
266
|
-
if (b == 0) {
|
267
|
-
|
268
|
-
|
269
|
-
res = uint32(int32(a) / int32(b));
|
266
|
+
if (b == 0 || (int32(a) == -2147483648 && int32(b) == -1)) {
|
267
|
+
mach.status = MachineStatus.ERRORED;
|
268
|
+
return;
|
270
269
|
}
|
270
|
+
res = uint32(int32(a) / int32(b));
|
271
271
|
} else if (opcodeOffset == 5) {
|
272
272
|
// rem_s
|
273
273
|
if (b == 0) {
|
274
|
-
|
275
|
-
|
276
|
-
res = uint32(int32(a) % int32(b));
|
274
|
+
mach.status = MachineStatus.ERRORED;
|
275
|
+
return;
|
277
276
|
}
|
277
|
+
res = uint32(int32(a) % int32(b));
|
278
278
|
} else if (opcodeOffset == 10) {
|
279
279
|
// shl
|
280
280
|
res = a << (b % 32);
|
@@ -291,7 +291,12 @@ contract OneStepProverMath is IOneStepProver {
|
|
291
291
|
// rotr
|
292
292
|
res = rotr32(a, b);
|
293
293
|
} else {
|
294
|
-
|
294
|
+
(uint64 computed, bool err) = genericBinOp(a, b, opcodeOffset);
|
295
|
+
if (err) {
|
296
|
+
mach.status = MachineStatus.ERRORED;
|
297
|
+
return;
|
298
|
+
}
|
299
|
+
res = uint32(computed);
|
295
300
|
}
|
296
301
|
}
|
297
302
|
|
@@ -313,18 +318,18 @@ contract OneStepProverMath is IOneStepProver {
|
|
313
318
|
unchecked {
|
314
319
|
if (opcodeOffset == 3) {
|
315
320
|
// div_s
|
316
|
-
if (b == 0) {
|
317
|
-
|
318
|
-
|
319
|
-
res = uint64(int64(a) / int64(b));
|
321
|
+
if (b == 0 || (int64(a) == -9223372036854775808 && int64(b) == -1)) {
|
322
|
+
mach.status = MachineStatus.ERRORED;
|
323
|
+
return;
|
320
324
|
}
|
325
|
+
res = uint64(int64(a) / int64(b));
|
321
326
|
} else if (opcodeOffset == 5) {
|
322
327
|
// rem_s
|
323
328
|
if (b == 0) {
|
324
|
-
|
325
|
-
|
326
|
-
res = uint64(int64(a) % int64(b));
|
329
|
+
mach.status = MachineStatus.ERRORED;
|
330
|
+
return;
|
327
331
|
}
|
332
|
+
res = uint64(int64(a) % int64(b));
|
328
333
|
} else if (opcodeOffset == 10) {
|
329
334
|
// shl
|
330
335
|
res = a << (b % 64);
|
@@ -341,7 +346,12 @@ contract OneStepProverMath is IOneStepProver {
|
|
341
346
|
// rotr
|
342
347
|
res = rotr64(a, b);
|
343
348
|
} else {
|
344
|
-
|
349
|
+
bool err;
|
350
|
+
(res, err) = genericBinOp(a, b, opcodeOffset);
|
351
|
+
if (err) {
|
352
|
+
mach.status = MachineStatus.ERRORED;
|
353
|
+
return;
|
354
|
+
}
|
345
355
|
}
|
346
356
|
}
|
347
357
|
|
@@ -271,10 +271,9 @@ contract OneStepProverMemory is IOneStepProver {
|
|
271
271
|
uint32 oldPages = uint32(mod.moduleMemory.size / PAGE_SIZE);
|
272
272
|
uint32 growingPages = mach.valueStack.pop().assumeI32();
|
273
273
|
// Safe as the input integers are too small to overflow a uint256
|
274
|
-
uint256 newSize =
|
275
|
-
|
276
|
-
|
277
|
-
mod.moduleMemory.size = uint64(newSize);
|
274
|
+
uint256 newSize = uint256(oldPages) + uint256(growingPages);
|
275
|
+
if (newSize <= mod.moduleMemory.maxSize) {
|
276
|
+
mod.moduleMemory.size = uint64(newSize * PAGE_SIZE);
|
278
277
|
mach.valueStack.push(ValueLib.newI32(oldPages));
|
279
278
|
} else {
|
280
279
|
mach.valueStack.push(ValueLib.newI32(~uint32(0)));
|