@arbitrum/nitro-contracts 1.0.0-beta.5 → 1.0.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)));
|