Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
EIP 97
Browse files Browse the repository at this point in the history
  • Loading branch information
vub authored and konradkonrad committed Jul 8, 2016
1 parent 7b27f4c commit abb8515
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
13 changes: 10 additions & 3 deletions ethereum/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ def reset_storage(self, address):
for k in self.caches[CACHE_KEY]:
self.set_and_journal(CACHE_KEY, k, 0)

def get_storage_data(self, address, index):
def get_storage_bytes(self, address, index):
"""Get a specific item in the storage of an account.
:param address: the address of the account (binary or hex string)
Expand All @@ -980,9 +980,16 @@ def get_storage_data(self, address, index):
key = utils.zpad(utils.coerce_to_bytes(index), 32)
storage = self.get_storage(address).get(key)
if storage:
return rlp.decode(storage, big_endian_int)
return rlp.decode(storage)
else:
return ''

def get_storage_data(self, address, index):
bytez = self.get_storage_bytes(address, index)
if len(bytez) >= 32:
return big_endian_to_int(bytez[-32:])
else:
return 0
return big_endian_to_int(bytez) * (1 << (8 * (32 - len(bytes))))

def set_storage_data(self, address, index, value):
"""Set a specific item in the storage of an account.
Expand Down
20 changes: 16 additions & 4 deletions ethereum/opcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
0xa2: ['LOG2', 4, 0, 1125],
0xa3: ['LOG3', 5, 0, 1500],
0xa4: ['LOG4', 6, 0, 1875],
0xe1: ['SLOADBYTES', 3, 0, 50],
0xe2: ['SSTOREBYTES', 3, 0, 0],
0xe3: ['SSIZE', 1, 1, 50],
0xf0: ['CREATE', 3, 1, 32000],
0xf1: ['CALL', 7, 1, 40],
0xf2: ['CALLCODE', 7, 1, 40],
Expand All @@ -85,10 +88,7 @@
GDEFAULT = 1
GMEMORY = 3
GQUADRATICMEMDENOM = 512 # 1 gas per 512 quadwords
GSTORAGEREFUND = 15000
GSTORAGEKILL = 5000
GSTORAGEMOD = 5000
GSTORAGEADD = 20000

GEXPONENTBYTE = 10 # cost of EXP exponent per byte
GCOPY = 3 # cost to copy one 32 byte word
GCONTRACTBYTE = 200 # one byte of code in contract creation
Expand All @@ -111,3 +111,15 @@

GCALLNEWACCOUNT = 25000
GSUICIDEREFUND = 24000

GSTORAGEBASE = 2500
GSTORAGEBYTESTORAGE = 250
GSTORAGEBYTECHANGE = 40
GSTORAGEMIN = 2500
GSSIZE = 50
GSLOADBYTES = 50

GSTORAGEREFUND = 15000
GSTORAGEKILL = 5000
GSTORAGEMOD = 5000
GSTORAGEADD = 20000
1 change: 1 addition & 0 deletions ethereum/processblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ def __init__(self, block, tx):
self.set_nonce = block.set_nonce
self.set_storage_data = block.set_storage_data
self.get_storage_data = block.get_storage_data
self.get_storage_bytes = block.get_storage_bytes
self.log_storage = lambda x: block.account_to_dict(x)['storage']
self.add_suicide = lambda x: block.suicides.append(x)
self.add_refund = lambda x: \
Expand Down
35 changes: 33 additions & 2 deletions ethereum/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import time
from ethereum.slogging import get_logger
from rlp.utils import encode_hex, ascii_chr
from ethereum.utils import to_string
from ethereum.utils import to_string, encode_int, zpad

log_log = get_logger('eth.vm.log')
log_vm_exit = get_logger('eth.vm.exit')
Expand Down Expand Up @@ -431,7 +431,7 @@ def vm_execute(ext, msg, code):
return vm_exception('OUT OF GAS')
compustate.gas -= gascost
ext.add_refund(refund) # adds neg gascost as a refund if below zero
ext.set_storage_data(msg.to, s0, s1)
ext.set_storage_data(msg.to, s0, zpad(encode_int(s1), 32))
elif op == 'JUMP':
compustate.pc = stk.pop()
opnew = processed_code[compustate.pc][0] if \
Expand All @@ -452,6 +452,37 @@ def vm_execute(ext, msg, code):
stk.append(len(mem))
elif op == 'GAS':
stk.append(compustate.gas) # AFTER subtracting cost 1
elif 0xe0 <= opcode < 0xef:
if not ext.post_metropolis_hardfork():
return vm_exception('OPCODE RANGE INACTIVE', opcode=opcode)
if op == 'SLOADBYTES':
key, mstart, msize = stk.pop(), stk.pop(), stk.pop()
bytez = map(ord, ext.get_storage_bytes(msg.to, key))
if not mem_extend(mem, compustate, op, mstart, min(msize, mstart + len(bytez))):
return vm_exception('OOG EXTENDING MEMORY')
for i in range(min(msize, len(bytez))):
mem[mstart + i] = bytez[i]
stk.append(ext.get_storage_data(msg.to, stk.pop()))
elif op == 'SSTOREBYTES':
key, mstart, msize = stk.pop(), stk.pop(), stk.pop()
if not mem_extend(mem, compustate, op, mstart, min(msize, mstart + len(bytez))):
return vm_exception('OOG EXTENDING MEMORY')
prev_adjbyte_count = len(ext.get_storage_data(msg.to, key))
if prev_adjbyte_count >= 0:
prev_adjbyte_count += 32
post_adjbyte_count = msize + (32 if msize else 0)
gas_cost = opcodes.GSTORAGEBASE + opcodes.GSTORAGEBYTESTORAGE * \
(post_adjbyte_count - prev_adjbyte_count) + opcodes.GSTORAGEBYTECHANGE * post_adjbyte_count
gas_payment = max(opcodes.GSTORAGEMIN, gas_cost)
refund = gas_payment - gas_cost
if compustate.gas < gas_payment:
return vm_exception('OUT OF GAS')
compustate.gas -= gas_payment
data = ''.join(map(chr, mem[mstart: mstart + msize]))
ext.set_storage_data(msg.to, data)
ext.add_refund(refund)
elif op == 'SSIZE':
stk.append(len(ext.get_storage_bytes(msg.to, stk.pop())))
elif op[:4] == 'PUSH':
pushnum = int(op[4:])
compustate.pc += pushnum
Expand Down

0 comments on commit abb8515

Please sign in to comment.