17
17
package vm
18
18
19
19
import (
20
+ "fmt"
21
+
20
22
"github.com/ethereum/go-ethereum/params"
21
23
)
22
24
@@ -57,21 +59,39 @@ var (
57
59
// JumpTable contains the EVM opcodes supported at a given fork.
58
60
type JumpTable [256 ]* operation
59
61
62
+ func validate (jt JumpTable ) JumpTable {
63
+ for i , op := range jt {
64
+ if op == nil {
65
+ panic (fmt .Sprintf ("op 0x%x is not set" , i ))
66
+ }
67
+ // The interpreter has an assumption that if the memorySize function is
68
+ // set, then the dynamicGas function is also set. This is a somewhat
69
+ // arbitrary assumption, and can be removed if we need to -- but it
70
+ // allows us to avoid a condition check. As long as we have that assumption
71
+ // in there, this little sanity check prevents us from merging in a
72
+ // change which violates it.
73
+ if op .memorySize != nil && op .dynamicGas == nil {
74
+ panic (fmt .Sprintf ("op %v has dynamic memory but not dynamic gas" , OpCode (i ).String ()))
75
+ }
76
+ }
77
+ return jt
78
+ }
79
+
60
80
// newLondonInstructionSet returns the frontier, homestead, byzantium,
61
81
// contantinople, istanbul, petersburg, berlin and london instructions.
62
82
func newLondonInstructionSet () JumpTable {
63
83
instructionSet := newBerlinInstructionSet ()
64
84
enable3529 (& instructionSet ) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529
65
85
enable3198 (& instructionSet ) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198
66
- return instructionSet
86
+ return validate ( instructionSet )
67
87
}
68
88
69
89
// newBerlinInstructionSet returns the frontier, homestead, byzantium,
70
90
// contantinople, istanbul, petersburg and berlin instructions.
71
91
func newBerlinInstructionSet () JumpTable {
72
92
instructionSet := newIstanbulInstructionSet ()
73
93
enable2929 (& instructionSet ) // Access lists for trie accesses https://eips.ethereum.org/EIPS/eip-2929
74
- return instructionSet
94
+ return validate ( instructionSet )
75
95
}
76
96
77
97
// newIstanbulInstructionSet returns the frontier, homestead, byzantium,
@@ -83,7 +103,7 @@ func newIstanbulInstructionSet() JumpTable {
83
103
enable1884 (& instructionSet ) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884
84
104
enable2200 (& instructionSet ) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200
85
105
86
- return instructionSet
106
+ return validate ( instructionSet )
87
107
}
88
108
89
109
// newConstantinopleInstructionSet returns the frontier, homestead,
@@ -122,7 +142,7 @@ func newConstantinopleInstructionSet() JumpTable {
122
142
maxStack : maxStack (4 , 1 ),
123
143
memorySize : memoryCreate2 ,
124
144
}
125
- return instructionSet
145
+ return validate ( instructionSet )
126
146
}
127
147
128
148
// newByzantiumInstructionSet returns the frontier, homestead and
@@ -158,14 +178,14 @@ func newByzantiumInstructionSet() JumpTable {
158
178
maxStack : maxStack (2 , 0 ),
159
179
memorySize : memoryRevert ,
160
180
}
161
- return instructionSet
181
+ return validate ( instructionSet )
162
182
}
163
183
164
184
// EIP 158 a.k.a Spurious Dragon
165
185
func newSpuriousDragonInstructionSet () JumpTable {
166
186
instructionSet := newTangerineWhistleInstructionSet ()
167
187
instructionSet [EXP ].dynamicGas = gasExpEIP158
168
- return instructionSet
188
+ return validate ( instructionSet )
169
189
170
190
}
171
191
@@ -179,7 +199,7 @@ func newTangerineWhistleInstructionSet() JumpTable {
179
199
instructionSet [CALL ].constantGas = params .CallGasEIP150
180
200
instructionSet [CALLCODE ].constantGas = params .CallGasEIP150
181
201
instructionSet [DELEGATECALL ].constantGas = params .CallGasEIP150
182
- return instructionSet
202
+ return validate ( instructionSet )
183
203
}
184
204
185
205
// newHomesteadInstructionSet returns the frontier and homestead
@@ -194,7 +214,7 @@ func newHomesteadInstructionSet() JumpTable {
194
214
maxStack : maxStack (6 , 1 ),
195
215
memorySize : memoryDelegateCall ,
196
216
}
197
- return instructionSet
217
+ return validate ( instructionSet )
198
218
}
199
219
200
220
// newFrontierInstructionSet returns the frontier instructions
@@ -1010,5 +1030,5 @@ func newFrontierInstructionSet() JumpTable {
1010
1030
}
1011
1031
}
1012
1032
1013
- return tbl
1033
+ return validate ( tbl )
1014
1034
}
0 commit comments