Skip to content

Commit

Permalink
Add SHR Opcode for Constantinople
Browse files Browse the repository at this point in the history
  • Loading branch information
cburgdorf committed Jul 31, 2018
1 parent 70e4332 commit 9614afb
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 6 deletions.
5 changes: 5 additions & 0 deletions eth/vm/forks/constantinople/opcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
mnemonic=mnemonics.SHL,
gas_cost=constants.GAS_VERYLOW,
),
opcode_values.SHR: as_opcode(
logic_fn=arithmetic.shr,
mnemonic=mnemonics.SHR,
gas_cost=constants.GAS_VERYLOW,
),
}

CONSTANTINOPLE_OPCODES = merge(
Expand Down
20 changes: 15 additions & 5 deletions eth/vm/logic/arithmetic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
from BitVector import (
BitVector
)
from cytoolz import (
curry,
)
Expand Down Expand Up @@ -187,11 +184,24 @@ def shl(computation):
Bitwise left shift
"""
shift_length, value = computation.stack_pop(num_items=2, type_hint=constants.UINT256)
bit_vector = BitVector(intVal=value, size=constants.CONST_256)

if shift_length >= constants.CONST_256:
result = constants.CONST_0
else:
result = bit_vector.shift_left(shift_length).int_val()
result = (value << shift_length) & constants.UINT_256_MAX

computation.stack_push(result)


def shr(computation):
"""
Bitwise right shift
"""
shift_length, value = computation.stack_pop(num_items=2, type_hint=constants.UINT256)

if shift_length >= constants.CONST_256:
result = constants.CONST_0
else:
result = (value >> shift_length) & constants.UINT_256_MAX

computation.stack_push(result)
1 change: 1 addition & 0 deletions eth/vm/mnemonics.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
EXP = 'EXP'
SIGNEXTEND = 'SIGNEXTEND'
SHL = 'SHL'
SHR = 'SHR'
#
# Comparisons
#
Expand Down
1 change: 1 addition & 0 deletions eth/vm/opcode_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
NOT = 0x19
BYTE = 0x1a
SHL = 0x1b
SHR = 0x1c


#
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

deps = {
'eth': [
"BitVector>=3.4.8, <4.0.0",
"cryptography>=2.0.3,<3.0.0",
"cytoolz>=0.9.0,<1.0.0",
"eth-bloom>=1.0.0,<2.0.0",
Expand Down
82 changes: 82 additions & 0 deletions tests/core/opcodes/test_opcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,85 @@ def test_shl(vm_class, val1, val2, expected):
result = computation.stack_pop(type_hint=constants.UINT256)

assert encode_hex(pad32(int_to_big_endian(result))) == expected


@pytest.mark.parametrize(
# Cases: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right
'vm_class, val1, val2, expected',
(
(
ConstantinopleVM,
'0x0000000000000000000000000000000000000000000000000000000000000001',
'0x00',
'0x0000000000000000000000000000000000000000000000000000000000000001',
),
(
ConstantinopleVM,
'0x0000000000000000000000000000000000000000000000000000000000000001',
'0x01',
'0x0000000000000000000000000000000000000000000000000000000000000000',
),
(
ConstantinopleVM,
'0x8000000000000000000000000000000000000000000000000000000000000000',
'0x01',
'0x4000000000000000000000000000000000000000000000000000000000000000',
),
(
ConstantinopleVM,
'0x8000000000000000000000000000000000000000000000000000000000000000',
'0xff',
'0x0000000000000000000000000000000000000000000000000000000000000001',
),
(
ConstantinopleVM,
'0x8000000000000000000000000000000000000000000000000000000000000000',
'0x0100',
'0x0000000000000000000000000000000000000000000000000000000000000000',
),
(
ConstantinopleVM,
'0x8000000000000000000000000000000000000000000000000000000000000000',
'0x0101',
'0x0000000000000000000000000000000000000000000000000000000000000000',
),
(
ConstantinopleVM,
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
'0x00',
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
),
(
ConstantinopleVM,
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
'0x01',
'0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
),
(
ConstantinopleVM,
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
'0xff',
'0x0000000000000000000000000000000000000000000000000000000000000001',
),
(
ConstantinopleVM,
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
'0x0100',
'0x0000000000000000000000000000000000000000000000000000000000000000',
),
(
ConstantinopleVM,
'0x0000000000000000000000000000000000000000000000000000000000000000',
'0x01',
'0x0000000000000000000000000000000000000000000000000000000000000000',
),
)
)
def test_shr(vm_class, val1, val2, expected):
computation = prepare_computation(vm_class)
computation.stack_push(decode_hex(val1))
computation.stack_push(decode_hex(val2))
computation.opcodes[opcode_values.SHR](computation)

result = computation.stack_pop(type_hint=constants.UINT256)
assert encode_hex(pad32(int_to_big_endian(result))) == expected

0 comments on commit 9614afb

Please sign in to comment.