@arbitrum/nitro-contracts 1.0.0-beta.5 → 1.0.0-beta.6
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +2 -1
- package/src/bridge/Bridge.sol +127 -32
- package/src/bridge/IBridge.sol +40 -6
- package/src/bridge/{IMessageProvider.sol → IDelayedMessageProvider.sol} +2 -3
- package/src/bridge/IInbox.sol +23 -2
- package/src/bridge/IOwnable.sol +9 -0
- package/src/bridge/ISequencerInbox.sol +36 -9
- package/src/bridge/Inbox.sol +131 -45
- package/src/bridge/Outbox.sol +134 -31
- package/src/bridge/SequencerInbox.sol +159 -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 +6 -0
- package/src/libraries/IGasRefunder.sol +12 -13
- package/src/libraries/MerkleLib.sol +11 -2
- package/src/libraries/MessageTypes.sol +1 -0
- package/src/mocks/BridgeStub.sol +67 -21
- package/src/mocks/InboxStub.sol +3 -9
- package/src/mocks/SequencerInboxStub.sol +10 -8
- package/src/mocks/Simple.sol +8 -0
- package/src/node-interface/NodeInterface.sol +32 -5
- 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 +1 -19
- package/src/precompiles/ArbOwner.sol +12 -15
- package/src/precompiles/ArbRetryableTx.sol +10 -1
- 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 +30 -34
- package/src/rollup/RollupCore.sol +15 -7
- package/src/rollup/RollupCreator.sol +21 -11
- package/src/rollup/{RollupEventBridge.sol → RollupEventInbox.sol} +10 -10
- package/src/rollup/RollupLib.sol +20 -5
- package/src/rollup/RollupUserLogic.sol +9 -18
- package/src/rollup/ValidatorWallet.sol +124 -8
- package/src/rollup/ValidatorWalletCreator.sol +11 -6
- package/src/state/Deserialize.sol +3 -22
- 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 +223 -0
- package/src/test-helpers/OutboxWithoutOptTester.sol +188 -0
- package/src/test-helpers/RollupMock.sol +21 -0
- package/src/state/PcStack.sol +0 -32
@@ -0,0 +1,223 @@
|
|
1
|
+
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
+
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
+
// SPDX-License-Identifier: BUSL-1.1
|
4
|
+
|
5
|
+
pragma solidity ^0.8.4;
|
6
|
+
|
7
|
+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
8
|
+
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
|
9
|
+
|
10
|
+
import "../bridge/IBridge.sol";
|
11
|
+
import "../bridge/Messages.sol";
|
12
|
+
import "../libraries/DelegateCallAware.sol";
|
13
|
+
|
14
|
+
/**
|
15
|
+
* @title Staging ground for incoming and outgoing messages
|
16
|
+
* @notice Holds the inbox accumulator for delayed messages, and is the ETH escrow
|
17
|
+
* for value sent with these messages.
|
18
|
+
* Since the escrow is held here, this contract also contains a list of allowed
|
19
|
+
* outboxes that can make calls from here and withdraw this escrow.
|
20
|
+
*/
|
21
|
+
contract BridgeTester is Initializable, DelegateCallAware, IBridge {
|
22
|
+
using AddressUpgradeable for address;
|
23
|
+
|
24
|
+
struct InOutInfo {
|
25
|
+
uint256 index;
|
26
|
+
bool allowed;
|
27
|
+
}
|
28
|
+
|
29
|
+
mapping(address => InOutInfo) private allowedInboxesMap;
|
30
|
+
mapping(address => InOutInfo) private allowedOutboxesMap;
|
31
|
+
|
32
|
+
address[] public allowedDelayedInboxList;
|
33
|
+
address[] public allowedOutboxList;
|
34
|
+
|
35
|
+
address private _activeOutbox;
|
36
|
+
|
37
|
+
IOwnable public rollup;
|
38
|
+
address public sequencerInbox;
|
39
|
+
|
40
|
+
modifier onlyRollupOrOwner() {
|
41
|
+
if (msg.sender != address(rollup)) {
|
42
|
+
address rollupOwner = rollup.owner();
|
43
|
+
if (msg.sender != rollupOwner) {
|
44
|
+
revert NotRollupOrOwner(msg.sender, address(rollup), rollupOwner);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
_;
|
48
|
+
}
|
49
|
+
|
50
|
+
function setSequencerInbox(address _sequencerInbox) external override onlyRollupOrOwner {
|
51
|
+
sequencerInbox = _sequencerInbox;
|
52
|
+
emit SequencerInboxUpdated(_sequencerInbox);
|
53
|
+
}
|
54
|
+
|
55
|
+
/// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.
|
56
|
+
bytes32[] public override delayedInboxAccs;
|
57
|
+
|
58
|
+
bytes32[] public override sequencerInboxAccs;
|
59
|
+
|
60
|
+
address private constant EMPTY_ACTIVEOUTBOX = address(type(uint160).max);
|
61
|
+
|
62
|
+
function initialize(IOwnable rollup_) external initializer {
|
63
|
+
_activeOutbox = EMPTY_ACTIVEOUTBOX;
|
64
|
+
rollup = rollup_;
|
65
|
+
}
|
66
|
+
|
67
|
+
function activeOutbox() public view returns (address) {
|
68
|
+
if (_activeOutbox == EMPTY_ACTIVEOUTBOX) return address(uint160(0));
|
69
|
+
return _activeOutbox;
|
70
|
+
}
|
71
|
+
|
72
|
+
function allowedDelayedInboxes(address inbox) external view override returns (bool) {
|
73
|
+
return allowedInboxesMap[inbox].allowed;
|
74
|
+
}
|
75
|
+
|
76
|
+
function allowedOutboxes(address outbox) external view override returns (bool) {
|
77
|
+
return allowedOutboxesMap[outbox].allowed;
|
78
|
+
}
|
79
|
+
|
80
|
+
function enqueueSequencerMessage(bytes32 dataHash, uint256 afterDelayedMessagesRead)
|
81
|
+
external
|
82
|
+
returns (
|
83
|
+
uint256 seqMessageIndex,
|
84
|
+
bytes32 beforeAcc,
|
85
|
+
bytes32 delayedAcc,
|
86
|
+
bytes32 acc
|
87
|
+
)
|
88
|
+
{
|
89
|
+
// TODO: implement stub logic
|
90
|
+
}
|
91
|
+
|
92
|
+
function submitBatchSpendingReport(address batchPoster, bytes32 dataHash)
|
93
|
+
external
|
94
|
+
returns (uint256)
|
95
|
+
{
|
96
|
+
// TODO: implement stub
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* @dev Enqueue a message in the delayed inbox accumulator.
|
101
|
+
* These messages are later sequenced in the SequencerInbox, either by the sequencer as
|
102
|
+
* part of a normal batch, or by force inclusion.
|
103
|
+
*/
|
104
|
+
function enqueueDelayedMessage(
|
105
|
+
uint8 kind,
|
106
|
+
address sender,
|
107
|
+
bytes32 messageDataHash
|
108
|
+
) external payable override returns (uint256) {
|
109
|
+
if (!allowedInboxesMap[msg.sender].allowed) revert NotDelayedInbox(msg.sender);
|
110
|
+
return
|
111
|
+
addMessageToDelayedAccumulator(
|
112
|
+
kind,
|
113
|
+
sender,
|
114
|
+
uint64(block.number),
|
115
|
+
uint64(block.timestamp), // solhint-disable-line not-rely-on-time
|
116
|
+
block.basefee,
|
117
|
+
messageDataHash
|
118
|
+
);
|
119
|
+
}
|
120
|
+
|
121
|
+
function addMessageToDelayedAccumulator(
|
122
|
+
uint8 kind,
|
123
|
+
address sender,
|
124
|
+
uint64 blockNumber,
|
125
|
+
uint64 blockTimestamp,
|
126
|
+
uint256 baseFeeL1,
|
127
|
+
bytes32 messageDataHash
|
128
|
+
) internal returns (uint256) {
|
129
|
+
uint256 count = delayedInboxAccs.length;
|
130
|
+
bytes32 messageHash = Messages.messageHash(
|
131
|
+
kind,
|
132
|
+
sender,
|
133
|
+
blockNumber,
|
134
|
+
blockTimestamp,
|
135
|
+
count,
|
136
|
+
baseFeeL1,
|
137
|
+
messageDataHash
|
138
|
+
);
|
139
|
+
bytes32 prevAcc = 0;
|
140
|
+
if (count > 0) {
|
141
|
+
prevAcc = delayedInboxAccs[count - 1];
|
142
|
+
}
|
143
|
+
delayedInboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash));
|
144
|
+
emit MessageDelivered(
|
145
|
+
count,
|
146
|
+
prevAcc,
|
147
|
+
msg.sender,
|
148
|
+
kind,
|
149
|
+
sender,
|
150
|
+
messageDataHash,
|
151
|
+
baseFeeL1,
|
152
|
+
blockTimestamp
|
153
|
+
);
|
154
|
+
return count;
|
155
|
+
}
|
156
|
+
|
157
|
+
function executeCall(
|
158
|
+
address to,
|
159
|
+
uint256 value,
|
160
|
+
bytes calldata data
|
161
|
+
) external override returns (bool success, bytes memory returnData) {
|
162
|
+
if (!allowedOutboxesMap[msg.sender].allowed) revert NotOutbox(msg.sender);
|
163
|
+
if (data.length > 0 && !to.isContract()) revert NotContract(to);
|
164
|
+
address prevOutbox = _activeOutbox;
|
165
|
+
_activeOutbox = msg.sender;
|
166
|
+
// We set and reset active outbox around external call so activeOutbox remains valid during call
|
167
|
+
|
168
|
+
// We use a low level call here since we want to bubble up whether it succeeded or failed to the caller
|
169
|
+
// rather than reverting on failure as well as allow contract and non-contract calls
|
170
|
+
// solhint-disable-next-line avoid-low-level-calls
|
171
|
+
(success, returnData) = to.call{value: value}(data);
|
172
|
+
_activeOutbox = prevOutbox;
|
173
|
+
emit BridgeCallTriggered(msg.sender, to, value, data);
|
174
|
+
}
|
175
|
+
|
176
|
+
function setDelayedInbox(address inbox, bool enabled) external override onlyRollupOrOwner {
|
177
|
+
InOutInfo storage info = allowedInboxesMap[inbox];
|
178
|
+
bool alreadyEnabled = info.allowed;
|
179
|
+
emit InboxToggle(inbox, enabled);
|
180
|
+
if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) {
|
181
|
+
return;
|
182
|
+
}
|
183
|
+
if (enabled) {
|
184
|
+
allowedInboxesMap[inbox] = InOutInfo(allowedDelayedInboxList.length, true);
|
185
|
+
allowedDelayedInboxList.push(inbox);
|
186
|
+
} else {
|
187
|
+
allowedDelayedInboxList[info.index] = allowedDelayedInboxList[
|
188
|
+
allowedDelayedInboxList.length - 1
|
189
|
+
];
|
190
|
+
allowedInboxesMap[allowedDelayedInboxList[info.index]].index = info.index;
|
191
|
+
allowedDelayedInboxList.pop();
|
192
|
+
delete allowedInboxesMap[inbox];
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
function setOutbox(address outbox, bool enabled) external override onlyRollupOrOwner {
|
197
|
+
InOutInfo storage info = allowedOutboxesMap[outbox];
|
198
|
+
bool alreadyEnabled = info.allowed;
|
199
|
+
emit OutboxToggle(outbox, enabled);
|
200
|
+
if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) {
|
201
|
+
return;
|
202
|
+
}
|
203
|
+
if (enabled) {
|
204
|
+
allowedOutboxesMap[outbox] = InOutInfo(allowedOutboxList.length, true);
|
205
|
+
allowedOutboxList.push(outbox);
|
206
|
+
} else {
|
207
|
+
allowedOutboxList[info.index] = allowedOutboxList[allowedOutboxList.length - 1];
|
208
|
+
allowedOutboxesMap[allowedOutboxList[info.index]].index = info.index;
|
209
|
+
allowedOutboxList.pop();
|
210
|
+
delete allowedOutboxesMap[outbox];
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
function delayedMessageCount() external view override returns (uint256) {
|
215
|
+
return delayedInboxAccs.length;
|
216
|
+
}
|
217
|
+
|
218
|
+
function sequencerMessageCount() external view override returns (uint256) {
|
219
|
+
return sequencerInboxAccs.length;
|
220
|
+
}
|
221
|
+
|
222
|
+
receive() external payable {}
|
223
|
+
}
|
@@ -0,0 +1,188 @@
|
|
1
|
+
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
+
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
+
// SPDX-License-Identifier: BUSL-1.1
|
4
|
+
|
5
|
+
pragma solidity ^0.8.4;
|
6
|
+
|
7
|
+
import "../bridge/IBridge.sol";
|
8
|
+
import "../bridge/IOutbox.sol";
|
9
|
+
import "../libraries/MerkleLib.sol";
|
10
|
+
import "../libraries/DelegateCallAware.sol";
|
11
|
+
|
12
|
+
contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
|
13
|
+
address public rollup; // the rollup contract
|
14
|
+
IBridge public bridge; // the bridge contract
|
15
|
+
|
16
|
+
mapping(uint256 => bool) public spent; // maps leaf number => if spent
|
17
|
+
mapping(bytes32 => bytes32) public roots; // maps root hashes => L2 block hash
|
18
|
+
|
19
|
+
struct L2ToL1Context {
|
20
|
+
uint128 l2Block;
|
21
|
+
uint128 l1Block;
|
22
|
+
uint128 timestamp;
|
23
|
+
bytes32 outputId;
|
24
|
+
address sender;
|
25
|
+
}
|
26
|
+
// Note, these variables are set and then wiped during a single transaction.
|
27
|
+
// Therefore their values don't need to be maintained, and their slots will
|
28
|
+
// be empty outside of transactions
|
29
|
+
L2ToL1Context internal context;
|
30
|
+
uint128 public constant OUTBOX_VERSION = 2;
|
31
|
+
|
32
|
+
function initialize(IBridge _bridge) external {
|
33
|
+
if (address(bridge) != address(0)) revert AlreadyInit();
|
34
|
+
bridge = _bridge;
|
35
|
+
rollup = address(_bridge.rollup());
|
36
|
+
}
|
37
|
+
|
38
|
+
function updateSendRoot(bytes32 root, bytes32 l2BlockHash) external override {
|
39
|
+
//if (msg.sender != rollup) revert NotRollup(msg.sender, rollup); //test only!!!
|
40
|
+
roots[root] = l2BlockHash;
|
41
|
+
emit SendRootUpdated(root, l2BlockHash);
|
42
|
+
}
|
43
|
+
|
44
|
+
/// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account
|
45
|
+
/// When the return value is zero, that means this is a system message
|
46
|
+
/// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies
|
47
|
+
function l2ToL1Sender() external view override returns (address) {
|
48
|
+
return context.sender;
|
49
|
+
}
|
50
|
+
|
51
|
+
function l2ToL1Block() external view override returns (uint256) {
|
52
|
+
return uint256(context.l2Block);
|
53
|
+
}
|
54
|
+
|
55
|
+
function l2ToL1EthBlock() external view override returns (uint256) {
|
56
|
+
return uint256(context.l1Block);
|
57
|
+
}
|
58
|
+
|
59
|
+
function l2ToL1Timestamp() external view override returns (uint256) {
|
60
|
+
return uint256(context.timestamp);
|
61
|
+
}
|
62
|
+
|
63
|
+
// @deprecated batch number is now always 0
|
64
|
+
function l2ToL1BatchNum() external pure override returns (uint256) {
|
65
|
+
return 0;
|
66
|
+
}
|
67
|
+
|
68
|
+
function l2ToL1OutputId() external view override returns (bytes32) {
|
69
|
+
return context.outputId;
|
70
|
+
}
|
71
|
+
|
72
|
+
/**
|
73
|
+
* @notice Executes a messages in an Outbox entry.
|
74
|
+
* @dev Reverts if dispute period hasn't expired, since the outbox entry
|
75
|
+
* is only created once the rollup confirms the respective assertion.
|
76
|
+
* @param proof Merkle proof of message inclusion in send root
|
77
|
+
* @param index Merkle path to message
|
78
|
+
* @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)
|
79
|
+
* @param to destination address for L1 contract call
|
80
|
+
* @param l2Block l2 block number at which sendTxToL1 call was made
|
81
|
+
* @param l1Block l1 block number at which sendTxToL1 call was made
|
82
|
+
* @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made
|
83
|
+
* @param value wei in L1 message
|
84
|
+
* @param data abi-encoded L1 message data
|
85
|
+
*/
|
86
|
+
function executeTransaction(
|
87
|
+
bytes32[] calldata proof,
|
88
|
+
uint256 index,
|
89
|
+
address l2Sender,
|
90
|
+
address to,
|
91
|
+
uint256 l2Block,
|
92
|
+
uint256 l1Block,
|
93
|
+
uint256 l2Timestamp,
|
94
|
+
uint256 value,
|
95
|
+
bytes calldata data
|
96
|
+
) external virtual {
|
97
|
+
bytes32 outputId;
|
98
|
+
{
|
99
|
+
bytes32 userTx = calculateItemHash(
|
100
|
+
l2Sender,
|
101
|
+
to,
|
102
|
+
l2Block,
|
103
|
+
l1Block,
|
104
|
+
l2Timestamp,
|
105
|
+
value,
|
106
|
+
data
|
107
|
+
);
|
108
|
+
|
109
|
+
outputId = recordOutputAsSpent(proof, index, userTx);
|
110
|
+
emit OutBoxTransactionExecuted(to, l2Sender, 0, index);
|
111
|
+
}
|
112
|
+
|
113
|
+
// we temporarily store the previous values so the outbox can naturally
|
114
|
+
// unwind itself when there are nested calls to `executeTransaction`
|
115
|
+
L2ToL1Context memory prevContext = context;
|
116
|
+
|
117
|
+
context = L2ToL1Context({
|
118
|
+
sender: l2Sender,
|
119
|
+
l2Block: uint128(l2Block),
|
120
|
+
l1Block: uint128(l1Block),
|
121
|
+
timestamp: uint128(l2Timestamp),
|
122
|
+
outputId: outputId
|
123
|
+
});
|
124
|
+
|
125
|
+
// set and reset vars around execution so they remain valid during call
|
126
|
+
executeBridgeCall(to, value, data);
|
127
|
+
|
128
|
+
context = prevContext;
|
129
|
+
}
|
130
|
+
|
131
|
+
function recordOutputAsSpent(
|
132
|
+
bytes32[] memory proof,
|
133
|
+
uint256 index,
|
134
|
+
bytes32 item
|
135
|
+
) internal returns (bytes32) {
|
136
|
+
if (proof.length >= 256) revert ProofTooLong(proof.length);
|
137
|
+
if (index >= 2**proof.length) revert PathNotMinimal(index, 2**proof.length);
|
138
|
+
|
139
|
+
// Hash the leaf an extra time to prove it's a leaf
|
140
|
+
bytes32 calcRoot = calculateMerkleRoot(proof, index, item);
|
141
|
+
if (roots[calcRoot] == bytes32(0)) revert UnknownRoot(calcRoot);
|
142
|
+
|
143
|
+
if (spent[index]) revert AlreadySpent(index);
|
144
|
+
spent[index] = true;
|
145
|
+
|
146
|
+
return bytes32(index);
|
147
|
+
}
|
148
|
+
|
149
|
+
function executeBridgeCall(
|
150
|
+
address to,
|
151
|
+
uint256 value,
|
152
|
+
bytes memory data
|
153
|
+
) internal {
|
154
|
+
(bool success, bytes memory returndata) = bridge.executeCall(to, value, data);
|
155
|
+
if (!success) {
|
156
|
+
if (returndata.length > 0) {
|
157
|
+
// solhint-disable-next-line no-inline-assembly
|
158
|
+
assembly {
|
159
|
+
let returndata_size := mload(returndata)
|
160
|
+
revert(add(32, returndata), returndata_size)
|
161
|
+
}
|
162
|
+
} else {
|
163
|
+
revert BridgeCallFailed();
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
function calculateItemHash(
|
169
|
+
address l2Sender,
|
170
|
+
address to,
|
171
|
+
uint256 l2Block,
|
172
|
+
uint256 l1Block,
|
173
|
+
uint256 l2Timestamp,
|
174
|
+
uint256 value,
|
175
|
+
bytes calldata data
|
176
|
+
) public pure returns (bytes32) {
|
177
|
+
return
|
178
|
+
keccak256(abi.encodePacked(l2Sender, to, l2Block, l1Block, l2Timestamp, value, data));
|
179
|
+
}
|
180
|
+
|
181
|
+
function calculateMerkleRoot(
|
182
|
+
bytes32[] memory proof,
|
183
|
+
uint256 path,
|
184
|
+
bytes32 item
|
185
|
+
) public pure returns (bytes32) {
|
186
|
+
return MerkleLib.calculateRoot(proof, path, keccak256(abi.encodePacked(item)));
|
187
|
+
}
|
188
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
+
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
+
// SPDX-License-Identifier: BUSL-1.1
|
4
|
+
|
5
|
+
pragma solidity ^0.8.4;
|
6
|
+
|
7
|
+
contract RollupMock {
|
8
|
+
event WithdrawTriggered();
|
9
|
+
event ZombieTriggered();
|
10
|
+
|
11
|
+
function withdrawStakerFunds() external returns (uint256) {
|
12
|
+
emit WithdrawTriggered();
|
13
|
+
return 0;
|
14
|
+
}
|
15
|
+
|
16
|
+
function removeOldZombies(
|
17
|
+
uint256 /* startIndex */
|
18
|
+
) external {
|
19
|
+
emit ZombieTriggered();
|
20
|
+
}
|
21
|
+
}
|
package/src/state/PcStack.sol
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
-
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
-
// SPDX-License-Identifier: BUSL-1.1
|
4
|
-
|
5
|
-
pragma solidity ^0.8.0;
|
6
|
-
|
7
|
-
import "./PcArray.sol";
|
8
|
-
|
9
|
-
struct PcStack {
|
10
|
-
PcArray proved;
|
11
|
-
bytes32 remainingHash;
|
12
|
-
}
|
13
|
-
|
14
|
-
library PcStackLib {
|
15
|
-
using PcArrayLib for PcArray;
|
16
|
-
|
17
|
-
function hash(PcStack memory stack) internal pure returns (bytes32 h) {
|
18
|
-
h = stack.remainingHash;
|
19
|
-
uint256 len = stack.proved.length();
|
20
|
-
for (uint256 i = 0; i < len; i++) {
|
21
|
-
h = keccak256(abi.encodePacked("Program counter stack:", stack.proved.get(i), h));
|
22
|
-
}
|
23
|
-
}
|
24
|
-
|
25
|
-
function pop(PcStack memory stack) internal pure returns (uint32) {
|
26
|
-
return stack.proved.pop();
|
27
|
-
}
|
28
|
-
|
29
|
-
function push(PcStack memory stack, uint32 val) internal pure {
|
30
|
-
return stack.proved.push(val);
|
31
|
-
}
|
32
|
-
}
|