@arbitrum/nitro-contracts 1.0.0-beta.1
Sign up to get free protection for your applications and to get access to all the features.
- package/.prettierrc +5 -0
- package/.solhint.json +18 -0
- package/deploy/BridgeStubCreator.js +10 -0
- package/deploy/HashProofHelper.js +13 -0
- package/deploy/InboxStubCreator.js +17 -0
- package/deploy/OneStepProofEntryCreator.js +19 -0
- package/deploy/OneStepProver0Creator.js +14 -0
- package/deploy/OneStepProverHostIoCreator.js +14 -0
- package/deploy/OneStepProverMathCreator.js +14 -0
- package/deploy/OneStepProverMemoryCreator.js +14 -0
- package/deploy/SequencerInboxStubCreator.js +13 -0
- package/deploy/ValueArrayTesterCreator.js +13 -0
- package/hardhat.config.ts +47 -0
- package/hardhat.prod-config.js +18 -0
- package/package.json +49 -0
- package/scripts/build.bash +5 -0
- package/src/bridge/Bridge.sol +168 -0
- package/src/bridge/IBridge.sol +68 -0
- package/src/bridge/IInbox.sol +80 -0
- package/src/bridge/IMessageProvider.sol +11 -0
- package/src/bridge/IOutbox.sol +52 -0
- package/src/bridge/ISequencerInbox.sol +85 -0
- package/src/bridge/Inbox.sol +414 -0
- package/src/bridge/Messages.sol +38 -0
- package/src/bridge/Outbox.sol +188 -0
- package/src/bridge/SequencerInbox.sol +274 -0
- package/src/challenge/ChallengeLib.sol +135 -0
- package/src/challenge/ChallengeManager.sol +367 -0
- package/src/challenge/IChallengeManager.sol +75 -0
- package/src/challenge/IChallengeResultReceiver.sol +13 -0
- package/src/libraries/AddressAliasHelper.sol +29 -0
- package/src/libraries/AdminFallbackProxy.sol +153 -0
- package/src/libraries/ArbitrumProxy.sol +20 -0
- package/src/libraries/Constants.sol +10 -0
- package/src/libraries/CryptographyPrimitives.sol +323 -0
- package/src/libraries/DelegateCallAware.sol +44 -0
- package/src/libraries/Error.sol +38 -0
- package/src/libraries/IGasRefunder.sol +35 -0
- package/src/libraries/MerkleLib.sol +46 -0
- package/src/libraries/MessageTypes.sol +14 -0
- package/src/libraries/SecondaryLogicUUPSUpgradeable.sol +58 -0
- package/src/libraries/UUPSNotUpgradeable.sol +56 -0
- package/src/mocks/BridgeStub.sol +115 -0
- package/src/mocks/Counter.sol +13 -0
- package/src/mocks/ExecutionManager.sol +41 -0
- package/src/mocks/InboxStub.sol +131 -0
- package/src/mocks/MockResultReceiver.sol +59 -0
- package/src/mocks/SequencerInboxStub.sol +42 -0
- package/src/mocks/SimpleProxy.sol +19 -0
- package/src/node-interface/NodeInterface.sol +50 -0
- package/src/osp/HashProofHelper.sol +154 -0
- package/src/osp/IOneStepProofEntry.sol +20 -0
- package/src/osp/IOneStepProver.sol +27 -0
- package/src/osp/OneStepProofEntry.sol +129 -0
- package/src/osp/OneStepProver0.sol +566 -0
- package/src/osp/OneStepProverHostIo.sol +357 -0
- package/src/osp/OneStepProverMath.sol +514 -0
- package/src/osp/OneStepProverMemory.sol +313 -0
- package/src/precompiles/ArbAddressTable.sol +60 -0
- package/src/precompiles/ArbAggregator.sol +62 -0
- package/src/precompiles/ArbBLS.sol +53 -0
- package/src/precompiles/ArbDebug.sol +39 -0
- package/src/precompiles/ArbFunctionTable.sol +29 -0
- package/src/precompiles/ArbGasInfo.sol +121 -0
- package/src/precompiles/ArbInfo.sol +15 -0
- package/src/precompiles/ArbOwner.sol +65 -0
- package/src/precompiles/ArbOwnerPublic.sol +18 -0
- package/src/precompiles/ArbRetryableTx.sol +89 -0
- package/src/precompiles/ArbStatistics.sol +29 -0
- package/src/precompiles/ArbSys.sol +134 -0
- package/src/precompiles/ArbosActs.sol +41 -0
- package/src/precompiles/ArbosTest.sol +14 -0
- package/src/rollup/BridgeCreator.sol +120 -0
- package/src/rollup/IRollupCore.sol +152 -0
- package/src/rollup/IRollupLogic.sol +183 -0
- package/src/rollup/Node.sol +99 -0
- package/src/rollup/RollupAdminLogic.sol +322 -0
- package/src/rollup/RollupCore.sol +627 -0
- package/src/rollup/RollupCreator.sol +133 -0
- package/src/rollup/RollupEventBridge.sol +46 -0
- package/src/rollup/RollupLib.sol +135 -0
- package/src/rollup/RollupUserLogic.sol +712 -0
- package/src/rollup/ValidatorUtils.sol +243 -0
- package/src/rollup/ValidatorWallet.sol +76 -0
- package/src/rollup/ValidatorWalletCreator.sol +43 -0
- package/src/state/Deserialize.sol +321 -0
- package/src/state/GlobalState.sol +44 -0
- package/src/state/Instructions.sol +159 -0
- package/src/state/Machine.sol +65 -0
- package/src/state/MerkleProof.sol +99 -0
- package/src/state/Module.sol +33 -0
- package/src/state/ModuleMemory.sol +42 -0
- package/src/state/PcArray.sol +45 -0
- package/src/state/PcStack.sol +32 -0
- package/src/state/StackFrame.sol +63 -0
- package/src/state/Value.sol +65 -0
- package/src/state/ValueArray.sol +47 -0
- package/src/state/ValueStack.sol +39 -0
- package/src/test-helpers/CryptographyPrimitivesTester.sol +27 -0
- package/src/test-helpers/MessageTester.sol +34 -0
- package/src/test-helpers/ValueArrayTester.sol +34 -0
- package/test/contract/arbRollup.spec.ts +869 -0
- package/test/contract/common/challengeLib.ts +43 -0
- package/test/contract/common/globalStateLib.ts +17 -0
- package/test/contract/common/rolluplib.ts +259 -0
- package/test/contract/cryptographyPrimitives.spec.ts +82 -0
- package/test/contract/sequencerInboxForceInclude.spec.ts +516 -0
- package/test/contract/utils.ts +40 -0
- package/test/prover/hash-proofs.ts +75 -0
- package/test/prover/one-step-proof.ts +93 -0
- package/test/prover/proofs/.gitkeep +0 -0
- package/test/prover/value-arrays.ts +11 -0
- package/tsconfig.json +13 -0
@@ -0,0 +1,44 @@
|
|
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
|
+
struct GlobalState {
|
8
|
+
bytes32[2] bytes32Vals;
|
9
|
+
uint64[2] u64Vals;
|
10
|
+
}
|
11
|
+
|
12
|
+
library GlobalStateLib {
|
13
|
+
uint16 internal constant BYTES32_VALS_NUM = 2;
|
14
|
+
uint16 internal constant U64_VALS_NUM = 2;
|
15
|
+
|
16
|
+
function hash(GlobalState memory state) internal pure returns (bytes32) {
|
17
|
+
return
|
18
|
+
keccak256(
|
19
|
+
abi.encodePacked(
|
20
|
+
"Global state:",
|
21
|
+
state.bytes32Vals[0],
|
22
|
+
state.bytes32Vals[1],
|
23
|
+
state.u64Vals[0],
|
24
|
+
state.u64Vals[1]
|
25
|
+
)
|
26
|
+
);
|
27
|
+
}
|
28
|
+
|
29
|
+
function getBlockHash(GlobalState memory state) internal pure returns (bytes32) {
|
30
|
+
return state.bytes32Vals[0];
|
31
|
+
}
|
32
|
+
|
33
|
+
function getSendRoot(GlobalState memory state) internal pure returns (bytes32) {
|
34
|
+
return state.bytes32Vals[1];
|
35
|
+
}
|
36
|
+
|
37
|
+
function getInboxPosition(GlobalState memory state) internal pure returns (uint64) {
|
38
|
+
return state.u64Vals[0];
|
39
|
+
}
|
40
|
+
|
41
|
+
function getPositionInMessage(GlobalState memory state) internal pure returns (uint64) {
|
42
|
+
return state.u64Vals[1];
|
43
|
+
}
|
44
|
+
}
|
@@ -0,0 +1,159 @@
|
|
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
|
+
struct Instruction {
|
8
|
+
uint16 opcode;
|
9
|
+
uint256 argumentData;
|
10
|
+
}
|
11
|
+
|
12
|
+
library Instructions {
|
13
|
+
uint16 internal constant UNREACHABLE = 0x00;
|
14
|
+
uint16 internal constant NOP = 0x01;
|
15
|
+
uint16 internal constant BLOCK = 0x02;
|
16
|
+
uint16 internal constant BRANCH = 0x0C;
|
17
|
+
uint16 internal constant BRANCH_IF = 0x0D;
|
18
|
+
uint16 internal constant RETURN = 0x0F;
|
19
|
+
uint16 internal constant CALL = 0x10;
|
20
|
+
uint16 internal constant CALL_INDIRECT = 0x11;
|
21
|
+
uint16 internal constant LOCAL_GET = 0x20;
|
22
|
+
uint16 internal constant LOCAL_SET = 0x21;
|
23
|
+
uint16 internal constant GLOBAL_GET = 0x23;
|
24
|
+
uint16 internal constant GLOBAL_SET = 0x24;
|
25
|
+
|
26
|
+
uint16 internal constant I32_LOAD = 0x28;
|
27
|
+
uint16 internal constant I64_LOAD = 0x29;
|
28
|
+
uint16 internal constant F32_LOAD = 0x2A;
|
29
|
+
uint16 internal constant F64_LOAD = 0x2B;
|
30
|
+
uint16 internal constant I32_LOAD8_S = 0x2C;
|
31
|
+
uint16 internal constant I32_LOAD8_U = 0x2D;
|
32
|
+
uint16 internal constant I32_LOAD16_S = 0x2E;
|
33
|
+
uint16 internal constant I32_LOAD16_U = 0x2F;
|
34
|
+
uint16 internal constant I64_LOAD8_S = 0x30;
|
35
|
+
uint16 internal constant I64_LOAD8_U = 0x31;
|
36
|
+
uint16 internal constant I64_LOAD16_S = 0x32;
|
37
|
+
uint16 internal constant I64_LOAD16_U = 0x33;
|
38
|
+
uint16 internal constant I64_LOAD32_S = 0x34;
|
39
|
+
uint16 internal constant I64_LOAD32_U = 0x35;
|
40
|
+
|
41
|
+
uint16 internal constant I32_STORE = 0x36;
|
42
|
+
uint16 internal constant I64_STORE = 0x37;
|
43
|
+
uint16 internal constant F32_STORE = 0x38;
|
44
|
+
uint16 internal constant F64_STORE = 0x39;
|
45
|
+
uint16 internal constant I32_STORE8 = 0x3A;
|
46
|
+
uint16 internal constant I32_STORE16 = 0x3B;
|
47
|
+
uint16 internal constant I64_STORE8 = 0x3C;
|
48
|
+
uint16 internal constant I64_STORE16 = 0x3D;
|
49
|
+
uint16 internal constant I64_STORE32 = 0x3E;
|
50
|
+
|
51
|
+
uint16 internal constant MEMORY_SIZE = 0x3F;
|
52
|
+
uint16 internal constant MEMORY_GROW = 0x40;
|
53
|
+
|
54
|
+
uint16 internal constant DROP = 0x1A;
|
55
|
+
uint16 internal constant SELECT = 0x1B;
|
56
|
+
uint16 internal constant I32_CONST = 0x41;
|
57
|
+
uint16 internal constant I64_CONST = 0x42;
|
58
|
+
uint16 internal constant F32_CONST = 0x43;
|
59
|
+
uint16 internal constant F64_CONST = 0x44;
|
60
|
+
uint16 internal constant I32_EQZ = 0x45;
|
61
|
+
uint16 internal constant I32_RELOP_BASE = 0x46;
|
62
|
+
uint16 internal constant IRELOP_EQ = 0;
|
63
|
+
uint16 internal constant IRELOP_NE = 1;
|
64
|
+
uint16 internal constant IRELOP_LT_S = 2;
|
65
|
+
uint16 internal constant IRELOP_LT_U = 3;
|
66
|
+
uint16 internal constant IRELOP_GT_S = 4;
|
67
|
+
uint16 internal constant IRELOP_GT_U = 5;
|
68
|
+
uint16 internal constant IRELOP_LE_S = 6;
|
69
|
+
uint16 internal constant IRELOP_LE_U = 7;
|
70
|
+
uint16 internal constant IRELOP_GE_S = 8;
|
71
|
+
uint16 internal constant IRELOP_GE_U = 9;
|
72
|
+
uint16 internal constant IRELOP_LAST = IRELOP_GE_U;
|
73
|
+
|
74
|
+
uint16 internal constant I64_EQZ = 0x50;
|
75
|
+
uint16 internal constant I64_RELOP_BASE = 0x51;
|
76
|
+
|
77
|
+
uint16 internal constant I32_UNOP_BASE = 0x67;
|
78
|
+
uint16 internal constant IUNOP_CLZ = 0;
|
79
|
+
uint16 internal constant IUNOP_CTZ = 1;
|
80
|
+
uint16 internal constant IUNOP_POPCNT = 2;
|
81
|
+
uint16 internal constant IUNOP_LAST = IUNOP_POPCNT;
|
82
|
+
|
83
|
+
uint16 internal constant I32_ADD = 0x6A;
|
84
|
+
uint16 internal constant I32_SUB = 0x6B;
|
85
|
+
uint16 internal constant I32_MUL = 0x6C;
|
86
|
+
uint16 internal constant I32_DIV_S = 0x6D;
|
87
|
+
uint16 internal constant I32_DIV_U = 0x6E;
|
88
|
+
uint16 internal constant I32_REM_S = 0x6F;
|
89
|
+
uint16 internal constant I32_REM_U = 0x70;
|
90
|
+
uint16 internal constant I32_AND = 0x71;
|
91
|
+
uint16 internal constant I32_OR = 0x72;
|
92
|
+
uint16 internal constant I32_XOR = 0x73;
|
93
|
+
uint16 internal constant I32_SHL = 0x74;
|
94
|
+
uint16 internal constant I32_SHR_S = 0x75;
|
95
|
+
uint16 internal constant I32_SHR_U = 0x76;
|
96
|
+
uint16 internal constant I32_ROTL = 0x77;
|
97
|
+
uint16 internal constant I32_ROTR = 0x78;
|
98
|
+
|
99
|
+
uint16 internal constant I64_UNOP_BASE = 0x79;
|
100
|
+
|
101
|
+
uint16 internal constant I64_ADD = 0x7C;
|
102
|
+
uint16 internal constant I64_SUB = 0x7D;
|
103
|
+
uint16 internal constant I64_MUL = 0x7E;
|
104
|
+
uint16 internal constant I64_DIV_S = 0x7F;
|
105
|
+
uint16 internal constant I64_DIV_U = 0x80;
|
106
|
+
uint16 internal constant I64_REM_S = 0x81;
|
107
|
+
uint16 internal constant I64_REM_U = 0x82;
|
108
|
+
uint16 internal constant I64_AND = 0x83;
|
109
|
+
uint16 internal constant I64_OR = 0x84;
|
110
|
+
uint16 internal constant I64_XOR = 0x85;
|
111
|
+
uint16 internal constant I64_SHL = 0x86;
|
112
|
+
uint16 internal constant I64_SHR_S = 0x87;
|
113
|
+
uint16 internal constant I64_SHR_U = 0x88;
|
114
|
+
uint16 internal constant I64_ROTL = 0x89;
|
115
|
+
uint16 internal constant I64_ROTR = 0x8A;
|
116
|
+
|
117
|
+
uint16 internal constant I32_WRAP_I64 = 0xA7;
|
118
|
+
uint16 internal constant I64_EXTEND_I32_S = 0xAC;
|
119
|
+
uint16 internal constant I64_EXTEND_I32_U = 0xAD;
|
120
|
+
|
121
|
+
uint16 internal constant I32_REINTERPRET_F32 = 0xBC;
|
122
|
+
uint16 internal constant I64_REINTERPRET_F64 = 0xBD;
|
123
|
+
uint16 internal constant F32_REINTERPRET_I32 = 0xBE;
|
124
|
+
uint16 internal constant F64_REINTERPRET_I64 = 0xBF;
|
125
|
+
|
126
|
+
uint16 internal constant I32_EXTEND_8S = 0xC0;
|
127
|
+
uint16 internal constant I32_EXTEND_16S = 0xC1;
|
128
|
+
uint16 internal constant I64_EXTEND_8S = 0xC2;
|
129
|
+
uint16 internal constant I64_EXTEND_16S = 0xC3;
|
130
|
+
uint16 internal constant I64_EXTEND_32S = 0xC4;
|
131
|
+
|
132
|
+
uint16 internal constant END_BLOCK = 0x8000;
|
133
|
+
uint16 internal constant END_BLOCK_IF = 0x8001;
|
134
|
+
uint16 internal constant INIT_FRAME = 0x8002;
|
135
|
+
uint16 internal constant ARBITRARY_JUMP_IF = 0x8003;
|
136
|
+
uint16 internal constant PUSH_STACK_BOUNDARY = 0x8004;
|
137
|
+
uint16 internal constant MOVE_FROM_STACK_TO_INTERNAL = 0x8005;
|
138
|
+
uint16 internal constant MOVE_FROM_INTERNAL_TO_STACK = 0x8006;
|
139
|
+
uint16 internal constant IS_STACK_BOUNDARY = 0x8007;
|
140
|
+
uint16 internal constant DUP = 0x8008;
|
141
|
+
uint16 internal constant CROSS_MODULE_CALL = 0x8009;
|
142
|
+
uint16 internal constant CALLER_MODULE_INTERNAL_CALL = 0x800A;
|
143
|
+
|
144
|
+
uint16 internal constant GET_GLOBAL_STATE_BYTES32 = 0x8010;
|
145
|
+
uint16 internal constant SET_GLOBAL_STATE_BYTES32 = 0x8011;
|
146
|
+
uint16 internal constant GET_GLOBAL_STATE_U64 = 0x8012;
|
147
|
+
uint16 internal constant SET_GLOBAL_STATE_U64 = 0x8013;
|
148
|
+
|
149
|
+
uint16 internal constant READ_PRE_IMAGE = 0x8020;
|
150
|
+
uint16 internal constant READ_INBOX_MESSAGE = 0x8021;
|
151
|
+
uint16 internal constant HALT_AND_SET_FINISHED = 0x8022;
|
152
|
+
|
153
|
+
uint256 internal constant INBOX_INDEX_SEQUENCER = 0;
|
154
|
+
uint256 internal constant INBOX_INDEX_DELAYED = 1;
|
155
|
+
|
156
|
+
function hash(Instruction memory inst) internal pure returns (bytes32) {
|
157
|
+
return keccak256(abi.encodePacked("Instruction:", inst.opcode, inst.argumentData));
|
158
|
+
}
|
159
|
+
}
|
@@ -0,0 +1,65 @@
|
|
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 "./ValueStack.sol";
|
8
|
+
import "./PcStack.sol";
|
9
|
+
import "./Instructions.sol";
|
10
|
+
import "./StackFrame.sol";
|
11
|
+
|
12
|
+
enum MachineStatus {
|
13
|
+
RUNNING,
|
14
|
+
FINISHED,
|
15
|
+
ERRORED,
|
16
|
+
TOO_FAR
|
17
|
+
}
|
18
|
+
|
19
|
+
struct Machine {
|
20
|
+
MachineStatus status;
|
21
|
+
ValueStack valueStack;
|
22
|
+
ValueStack internalStack;
|
23
|
+
PcStack blockStack;
|
24
|
+
StackFrameWindow frameStack;
|
25
|
+
bytes32 globalStateHash;
|
26
|
+
uint32 moduleIdx;
|
27
|
+
uint32 functionIdx;
|
28
|
+
uint32 functionPc;
|
29
|
+
bytes32 modulesRoot;
|
30
|
+
}
|
31
|
+
|
32
|
+
library MachineLib {
|
33
|
+
using PcStackLib for PcStack;
|
34
|
+
using StackFrameLib for StackFrameWindow;
|
35
|
+
using ValueStackLib for ValueStack;
|
36
|
+
|
37
|
+
function hash(Machine memory mach) internal pure returns (bytes32) {
|
38
|
+
// Warning: the non-running hashes are replicated in Challenge
|
39
|
+
if (mach.status == MachineStatus.RUNNING) {
|
40
|
+
return
|
41
|
+
keccak256(
|
42
|
+
abi.encodePacked(
|
43
|
+
"Machine running:",
|
44
|
+
mach.valueStack.hash(),
|
45
|
+
mach.internalStack.hash(),
|
46
|
+
mach.blockStack.hash(),
|
47
|
+
mach.frameStack.hash(),
|
48
|
+
mach.globalStateHash,
|
49
|
+
mach.moduleIdx,
|
50
|
+
mach.functionIdx,
|
51
|
+
mach.functionPc,
|
52
|
+
mach.modulesRoot
|
53
|
+
)
|
54
|
+
);
|
55
|
+
} else if (mach.status == MachineStatus.FINISHED) {
|
56
|
+
return keccak256(abi.encodePacked("Machine finished:", mach.globalStateHash));
|
57
|
+
} else if (mach.status == MachineStatus.ERRORED) {
|
58
|
+
return keccak256(abi.encodePacked("Machine errored:"));
|
59
|
+
} else if (mach.status == MachineStatus.TOO_FAR) {
|
60
|
+
return keccak256(abi.encodePacked("Machine too far:"));
|
61
|
+
} else {
|
62
|
+
revert("BAD_MACH_STATUS");
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
@@ -0,0 +1,99 @@
|
|
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 "./Value.sol";
|
8
|
+
import "./Instructions.sol";
|
9
|
+
import "./Module.sol";
|
10
|
+
|
11
|
+
struct MerkleProof {
|
12
|
+
bytes32[] counterparts;
|
13
|
+
}
|
14
|
+
|
15
|
+
library MerkleProofLib {
|
16
|
+
using ModuleLib for Module;
|
17
|
+
using ValueLib for Value;
|
18
|
+
|
19
|
+
function computeRootFromValue(
|
20
|
+
MerkleProof memory proof,
|
21
|
+
uint256 index,
|
22
|
+
Value memory leaf
|
23
|
+
) internal pure returns (bytes32) {
|
24
|
+
return computeRootUnsafe(proof, index, leaf.hash(), "Value merkle tree:");
|
25
|
+
}
|
26
|
+
|
27
|
+
function computeRootFromInstruction(
|
28
|
+
MerkleProof memory proof,
|
29
|
+
uint256 index,
|
30
|
+
Instruction memory inst
|
31
|
+
) internal pure returns (bytes32) {
|
32
|
+
return computeRootUnsafe(proof, index, Instructions.hash(inst), "Instruction merkle tree:");
|
33
|
+
}
|
34
|
+
|
35
|
+
function computeRootFromFunction(
|
36
|
+
MerkleProof memory proof,
|
37
|
+
uint256 index,
|
38
|
+
bytes32 codeRoot
|
39
|
+
) internal pure returns (bytes32) {
|
40
|
+
bytes32 h = keccak256(abi.encodePacked("Function:", codeRoot));
|
41
|
+
return computeRootUnsafe(proof, index, h, "Function merkle tree:");
|
42
|
+
}
|
43
|
+
|
44
|
+
function computeRootFromMemory(
|
45
|
+
MerkleProof memory proof,
|
46
|
+
uint256 index,
|
47
|
+
bytes32 contents
|
48
|
+
) internal pure returns (bytes32) {
|
49
|
+
bytes32 h = keccak256(abi.encodePacked("Memory leaf:", contents));
|
50
|
+
return computeRootUnsafe(proof, index, h, "Memory merkle tree:");
|
51
|
+
}
|
52
|
+
|
53
|
+
function computeRootFromElement(
|
54
|
+
MerkleProof memory proof,
|
55
|
+
uint256 index,
|
56
|
+
bytes32 funcTypeHash,
|
57
|
+
Value memory val
|
58
|
+
) internal pure returns (bytes32) {
|
59
|
+
bytes32 h = keccak256(abi.encodePacked("Table element:", funcTypeHash, val.hash()));
|
60
|
+
return computeRootUnsafe(proof, index, h, "Table element merkle tree:");
|
61
|
+
}
|
62
|
+
|
63
|
+
function computeRootFromTable(
|
64
|
+
MerkleProof memory proof,
|
65
|
+
uint256 index,
|
66
|
+
uint8 tableType,
|
67
|
+
uint64 tableSize,
|
68
|
+
bytes32 elementsRoot
|
69
|
+
) internal pure returns (bytes32) {
|
70
|
+
bytes32 h = keccak256(abi.encodePacked("Table:", tableType, tableSize, elementsRoot));
|
71
|
+
return computeRootUnsafe(proof, index, h, "Table merkle tree:");
|
72
|
+
}
|
73
|
+
|
74
|
+
function computeRootFromModule(
|
75
|
+
MerkleProof memory proof,
|
76
|
+
uint256 index,
|
77
|
+
Module memory mod
|
78
|
+
) internal pure returns (bytes32) {
|
79
|
+
return computeRootUnsafe(proof, index, mod.hash(), "Module merkle tree:");
|
80
|
+
}
|
81
|
+
|
82
|
+
// WARNING: leafHash must be computed in such a way that it cannot be a non-leaf hash.
|
83
|
+
function computeRootUnsafe(
|
84
|
+
MerkleProof memory proof,
|
85
|
+
uint256 index,
|
86
|
+
bytes32 leafHash,
|
87
|
+
string memory prefix
|
88
|
+
) internal pure returns (bytes32 h) {
|
89
|
+
h = leafHash;
|
90
|
+
for (uint256 layer = 0; layer < proof.counterparts.length; layer++) {
|
91
|
+
if (index & 1 == 0) {
|
92
|
+
h = keccak256(abi.encodePacked(prefix, h, proof.counterparts[layer]));
|
93
|
+
} else {
|
94
|
+
h = keccak256(abi.encodePacked(prefix, proof.counterparts[layer], h));
|
95
|
+
}
|
96
|
+
index >>= 1;
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
@@ -0,0 +1,33 @@
|
|
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 "./ModuleMemory.sol";
|
8
|
+
|
9
|
+
struct Module {
|
10
|
+
bytes32 globalsMerkleRoot;
|
11
|
+
ModuleMemory moduleMemory;
|
12
|
+
bytes32 tablesMerkleRoot;
|
13
|
+
bytes32 functionsMerkleRoot;
|
14
|
+
uint32 internalsOffset;
|
15
|
+
}
|
16
|
+
|
17
|
+
library ModuleLib {
|
18
|
+
using ModuleMemoryLib for ModuleMemory;
|
19
|
+
|
20
|
+
function hash(Module memory mod) internal pure returns (bytes32) {
|
21
|
+
return
|
22
|
+
keccak256(
|
23
|
+
abi.encodePacked(
|
24
|
+
"Module:",
|
25
|
+
mod.globalsMerkleRoot,
|
26
|
+
mod.moduleMemory.hash(),
|
27
|
+
mod.tablesMerkleRoot,
|
28
|
+
mod.functionsMerkleRoot,
|
29
|
+
mod.internalsOffset
|
30
|
+
)
|
31
|
+
);
|
32
|
+
}
|
33
|
+
}
|
@@ -0,0 +1,42 @@
|
|
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 "./MerkleProof.sol";
|
8
|
+
import "./Deserialize.sol";
|
9
|
+
|
10
|
+
struct ModuleMemory {
|
11
|
+
uint64 size;
|
12
|
+
bytes32 merkleRoot;
|
13
|
+
}
|
14
|
+
|
15
|
+
library ModuleMemoryLib {
|
16
|
+
using MerkleProofLib for MerkleProof;
|
17
|
+
|
18
|
+
function hash(ModuleMemory memory mem) internal pure returns (bytes32) {
|
19
|
+
return keccak256(abi.encodePacked("Memory:", mem.size, mem.merkleRoot));
|
20
|
+
}
|
21
|
+
|
22
|
+
function proveLeaf(
|
23
|
+
ModuleMemory memory mem,
|
24
|
+
uint256 leafIdx,
|
25
|
+
bytes calldata proof,
|
26
|
+
uint256 startOffset
|
27
|
+
)
|
28
|
+
internal
|
29
|
+
pure
|
30
|
+
returns (
|
31
|
+
bytes32 contents,
|
32
|
+
uint256 offset,
|
33
|
+
MerkleProof memory merkle
|
34
|
+
)
|
35
|
+
{
|
36
|
+
offset = startOffset;
|
37
|
+
(contents, offset) = Deserialize.b32(proof, offset);
|
38
|
+
(merkle, offset) = Deserialize.merkleProof(proof, offset);
|
39
|
+
bytes32 recomputedRoot = merkle.computeRootFromMemory(leafIdx, contents);
|
40
|
+
require(recomputedRoot == mem.merkleRoot, "WRONG_MEM_ROOT");
|
41
|
+
}
|
42
|
+
}
|
@@ -0,0 +1,45 @@
|
|
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
|
+
struct PcArray {
|
8
|
+
uint32[] inner;
|
9
|
+
}
|
10
|
+
|
11
|
+
library PcArrayLib {
|
12
|
+
function get(PcArray memory arr, uint256 index) internal pure returns (uint32) {
|
13
|
+
return arr.inner[index];
|
14
|
+
}
|
15
|
+
|
16
|
+
function set(
|
17
|
+
PcArray memory arr,
|
18
|
+
uint256 index,
|
19
|
+
uint32 val
|
20
|
+
) internal pure {
|
21
|
+
arr.inner[index] = val;
|
22
|
+
}
|
23
|
+
|
24
|
+
function length(PcArray memory arr) internal pure returns (uint256) {
|
25
|
+
return arr.inner.length;
|
26
|
+
}
|
27
|
+
|
28
|
+
function push(PcArray memory arr, uint32 val) internal pure {
|
29
|
+
uint32[] memory newInner = new uint32[](arr.inner.length + 1);
|
30
|
+
for (uint256 i = 0; i < arr.inner.length; i++) {
|
31
|
+
newInner[i] = arr.inner[i];
|
32
|
+
}
|
33
|
+
newInner[arr.inner.length] = val;
|
34
|
+
arr.inner = newInner;
|
35
|
+
}
|
36
|
+
|
37
|
+
function pop(PcArray memory arr) internal pure returns (uint32 popped) {
|
38
|
+
popped = arr.inner[arr.inner.length - 1];
|
39
|
+
uint32[] memory newInner = new uint32[](arr.inner.length - 1);
|
40
|
+
for (uint256 i = 0; i < newInner.length; i++) {
|
41
|
+
newInner[i] = arr.inner[i];
|
42
|
+
}
|
43
|
+
arr.inner = newInner;
|
44
|
+
}
|
45
|
+
}
|
@@ -0,0 +1,32 @@
|
|
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
|
+
}
|
@@ -0,0 +1,63 @@
|
|
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 "./Value.sol";
|
8
|
+
|
9
|
+
struct StackFrame {
|
10
|
+
Value returnPc;
|
11
|
+
bytes32 localsMerkleRoot;
|
12
|
+
uint32 callerModule;
|
13
|
+
uint32 callerModuleInternals;
|
14
|
+
}
|
15
|
+
|
16
|
+
struct StackFrameWindow {
|
17
|
+
StackFrame[] proved;
|
18
|
+
bytes32 remainingHash;
|
19
|
+
}
|
20
|
+
|
21
|
+
library StackFrameLib {
|
22
|
+
using ValueLib for Value;
|
23
|
+
|
24
|
+
function hash(StackFrame memory frame) internal pure returns (bytes32) {
|
25
|
+
return
|
26
|
+
keccak256(
|
27
|
+
abi.encodePacked(
|
28
|
+
"Stack frame:",
|
29
|
+
frame.returnPc.hash(),
|
30
|
+
frame.localsMerkleRoot,
|
31
|
+
frame.callerModule,
|
32
|
+
frame.callerModuleInternals
|
33
|
+
)
|
34
|
+
);
|
35
|
+
}
|
36
|
+
|
37
|
+
function hash(StackFrameWindow memory window) internal pure returns (bytes32 h) {
|
38
|
+
h = window.remainingHash;
|
39
|
+
for (uint256 i = 0; i < window.proved.length; i++) {
|
40
|
+
h = keccak256(abi.encodePacked("Stack frame stack:", hash(window.proved[i]), h));
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
function peek(StackFrameWindow memory window) internal pure returns (StackFrame memory) {
|
45
|
+
require(window.proved.length == 1, "BAD_WINDOW_LENGTH");
|
46
|
+
return window.proved[0];
|
47
|
+
}
|
48
|
+
|
49
|
+
function pop(StackFrameWindow memory window) internal pure returns (StackFrame memory frame) {
|
50
|
+
require(window.proved.length == 1, "BAD_WINDOW_LENGTH");
|
51
|
+
frame = window.proved[0];
|
52
|
+
window.proved = new StackFrame[](0);
|
53
|
+
}
|
54
|
+
|
55
|
+
function push(StackFrameWindow memory window, StackFrame memory frame) internal pure {
|
56
|
+
StackFrame[] memory newProved = new StackFrame[](window.proved.length + 1);
|
57
|
+
for (uint256 i = 0; i < window.proved.length; i++) {
|
58
|
+
newProved[i] = window.proved[i];
|
59
|
+
}
|
60
|
+
newProved[window.proved.length] = frame;
|
61
|
+
window.proved = newProved;
|
62
|
+
}
|
63
|
+
}
|
@@ -0,0 +1,65 @@
|
|
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
|
+
enum ValueType {
|
8
|
+
I32,
|
9
|
+
I64,
|
10
|
+
F32,
|
11
|
+
F64,
|
12
|
+
REF_NULL,
|
13
|
+
FUNC_REF,
|
14
|
+
INTERNAL_REF,
|
15
|
+
STACK_BOUNDARY
|
16
|
+
}
|
17
|
+
|
18
|
+
struct Value {
|
19
|
+
ValueType valueType;
|
20
|
+
uint256 contents;
|
21
|
+
}
|
22
|
+
|
23
|
+
library ValueLib {
|
24
|
+
function hash(Value memory val) internal pure returns (bytes32) {
|
25
|
+
return keccak256(abi.encodePacked("Value:", val.valueType, val.contents));
|
26
|
+
}
|
27
|
+
|
28
|
+
function maxValueType() internal pure returns (ValueType) {
|
29
|
+
return ValueType.STACK_BOUNDARY;
|
30
|
+
}
|
31
|
+
|
32
|
+
function assumeI32(Value memory val) internal pure returns (uint32) {
|
33
|
+
uint256 uintval = uint256(val.contents);
|
34
|
+
require(val.valueType == ValueType.I32, "NOT_I32");
|
35
|
+
require(uintval < (1 << 32), "BAD_I32");
|
36
|
+
return uint32(uintval);
|
37
|
+
}
|
38
|
+
|
39
|
+
function assumeI64(Value memory val) internal pure returns (uint64) {
|
40
|
+
uint256 uintval = uint256(val.contents);
|
41
|
+
require(val.valueType == ValueType.I64, "NOT_I64");
|
42
|
+
require(uintval < (1 << 64), "BAD_I64");
|
43
|
+
return uint64(uintval);
|
44
|
+
}
|
45
|
+
|
46
|
+
function newRefNull() internal pure returns (Value memory) {
|
47
|
+
return Value({valueType: ValueType.REF_NULL, contents: 0});
|
48
|
+
}
|
49
|
+
|
50
|
+
function newI32(uint32 x) internal pure returns (Value memory) {
|
51
|
+
return Value({valueType: ValueType.I32, contents: uint256(x)});
|
52
|
+
}
|
53
|
+
|
54
|
+
function newI64(uint64 x) internal pure returns (Value memory) {
|
55
|
+
return Value({valueType: ValueType.I64, contents: uint256(x)});
|
56
|
+
}
|
57
|
+
|
58
|
+
function newBoolean(bool x) internal pure returns (Value memory) {
|
59
|
+
if (x) {
|
60
|
+
return newI32(uint32(1));
|
61
|
+
} else {
|
62
|
+
return newI32(uint32(0));
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|