Skip to content

Commit 8143710

Browse files
committed
Add SHR Opcode for Constantinople
1 parent c53e66a commit 8143710

File tree

5 files changed

+103
-0
lines changed

5 files changed

+103
-0
lines changed

eth/vm/forks/constantinople/opcodes.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
mnemonic=mnemonics.SHL,
2828
gas_cost=constants.GAS_VERYLOW,
2929
),
30+
opcode_values.SHR: as_opcode(
31+
logic_fn=arithmetic.shr,
32+
mnemonic=mnemonics.SHR,
33+
gas_cost=constants.GAS_VERYLOW,
34+
),
3035
}
3136

3237
CONSTANTINOPLE_OPCODES = merge(

eth/vm/logic/arithmetic.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,17 @@ def shl(computation):
191191
result = (value << shift_length) & constants.UINT_256_MAX
192192

193193
computation.stack_push(result)
194+
195+
196+
def shr(computation):
197+
"""
198+
Bitwise right shift
199+
"""
200+
shift_length, value = computation.stack_pop(num_items=2, type_hint=constants.UINT256)
201+
202+
if shift_length >= 256:
203+
result = 0
204+
else:
205+
result = (value >> shift_length) & constants.UINT_256_MAX
206+
207+
computation.stack_push(result)

eth/vm/mnemonics.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
EXP = 'EXP'
1515
SIGNEXTEND = 'SIGNEXTEND'
1616
SHL = 'SHL'
17+
SHR = 'SHR'
1718
#
1819
# Comparisons
1920
#

eth/vm/opcode_values.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
NOT = 0x19
3131
BYTE = 0x1a
3232
SHL = 0x1b
33+
SHR = 0x1c
3334

3435

3536
#

tests/core/opcodes/test_opcodes.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,85 @@ def test_shl(vm_class, val1, val2, expected):
183183
result = computation.stack_pop(type_hint=constants.UINT256)
184184

185185
assert encode_hex(pad32(int_to_big_endian(result))) == expected
186+
187+
188+
@pytest.mark.parametrize(
189+
# Cases: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right
190+
'vm_class, val1, val2, expected',
191+
(
192+
(
193+
ConstantinopleVM,
194+
'0x0000000000000000000000000000000000000000000000000000000000000001',
195+
'0x00',
196+
'0x0000000000000000000000000000000000000000000000000000000000000001',
197+
),
198+
(
199+
ConstantinopleVM,
200+
'0x0000000000000000000000000000000000000000000000000000000000000001',
201+
'0x01',
202+
'0x0000000000000000000000000000000000000000000000000000000000000000',
203+
),
204+
(
205+
ConstantinopleVM,
206+
'0x8000000000000000000000000000000000000000000000000000000000000000',
207+
'0x01',
208+
'0x4000000000000000000000000000000000000000000000000000000000000000',
209+
),
210+
(
211+
ConstantinopleVM,
212+
'0x8000000000000000000000000000000000000000000000000000000000000000',
213+
'0xff',
214+
'0x0000000000000000000000000000000000000000000000000000000000000001',
215+
),
216+
(
217+
ConstantinopleVM,
218+
'0x8000000000000000000000000000000000000000000000000000000000000000',
219+
'0x0100',
220+
'0x0000000000000000000000000000000000000000000000000000000000000000',
221+
),
222+
(
223+
ConstantinopleVM,
224+
'0x8000000000000000000000000000000000000000000000000000000000000000',
225+
'0x0101',
226+
'0x0000000000000000000000000000000000000000000000000000000000000000',
227+
),
228+
(
229+
ConstantinopleVM,
230+
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
231+
'0x00',
232+
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
233+
),
234+
(
235+
ConstantinopleVM,
236+
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
237+
'0x01',
238+
'0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
239+
),
240+
(
241+
ConstantinopleVM,
242+
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
243+
'0xff',
244+
'0x0000000000000000000000000000000000000000000000000000000000000001',
245+
),
246+
(
247+
ConstantinopleVM,
248+
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
249+
'0x0100',
250+
'0x0000000000000000000000000000000000000000000000000000000000000000',
251+
),
252+
(
253+
ConstantinopleVM,
254+
'0x0000000000000000000000000000000000000000000000000000000000000000',
255+
'0x01',
256+
'0x0000000000000000000000000000000000000000000000000000000000000000',
257+
),
258+
)
259+
)
260+
def test_shr(vm_class, val1, val2, expected):
261+
computation = prepare_computation(vm_class)
262+
computation.stack_push(decode_hex(val1))
263+
computation.stack_push(decode_hex(val2))
264+
computation.opcodes[opcode_values.SHR](computation)
265+
266+
result = computation.stack_pop(type_hint=constants.UINT256)
267+
assert encode_hex(pad32(int_to_big_endian(result))) == expected

0 commit comments

Comments
 (0)