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

Commit c8041a7

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into develop
2 parents c07a16c + 6792f58 commit c8041a7

32 files changed

+534
-390
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ sudo: false
44
env:
55
- TOX_ENV=py27
66
install:
7-
- pip install -r requirements.txt
8-
- pip install -r dev_requirements.txt
7+
- pip install -Ur requirements.txt
8+
- pip install -Ur dev_requirements.txt
99
script:
1010
- coverage run --source ethereum -m py.test --ignore ethereum/tests/test_vm.py --ignore
1111
ethereum/tests/test_state.py

dev_requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tox
22
coveralls
3-
pytest
4-
pytest-catchlog==1.1
5-
pytest-timeout==0.5
3+
pytest>=2.9.0
4+
pytest-catchlog==1.2.2
5+
pytest-timeout==1.0.0
66
https://github.com/ethereum/serpent/tarball/develop

ethereum/abi.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def decode(self, name, data):
100100
def is_unknown_type(self, name):
101101
return self.function_data[name]["is_unknown_type"]
102102

103-
def listen(self, log, noprint=False):
103+
def listen(self, log, noprint=True):
104104
if not len(log.topics) or log.topics[0] not in self.event_data:
105105
return
106106
types = self.event_data[log.topics[0]]['types']
@@ -149,7 +149,7 @@ class ValueOutOfBounds(EncodingError):
149149
def decint(n):
150150
if isinstance(n, str):
151151
n = utils.to_string(n)
152-
if is_numeric(n) and n < 2**256 and n > -2**255:
152+
if is_numeric(n) and n < 2**256 and n >= -2**255:
153153
return n
154154
elif is_numeric(n):
155155
raise EncodingError("Number out of range: %r" % n)
@@ -194,13 +194,14 @@ def encode_single(typ, arg):
194194
high, low = [int(x) for x in sub.split('x')]
195195
if not 0 <= arg < 2**high:
196196
raise ValueOutOfBounds(repr(arg))
197-
return zpad(encode_int(arg * 2**low), 32)
197+
return zpad(encode_int(int(arg * 2**low)), 32)
198198
# Signed reals: real<high>x<low>
199199
elif base == 'real':
200200
high, low = [int(x) for x in sub.split('x')]
201201
if not -2**(high - 1) <= arg < 2**(high - 1):
202202
raise ValueOutOfBounds(repr(arg))
203-
return zpad(encode_int((arg % 2**high) * 2**low), 32)
203+
i = int(arg * 2**low)
204+
return zpad(encode_int(i % 2**(high+low)), 32)
204205
# Strings
205206
elif base == 'string' or base == 'bytes':
206207
if not is_string(arg):
@@ -221,9 +222,9 @@ def encode_single(typ, arg):
221222
raise EncodingError("too long: %r" % arg)
222223
if isnumeric(arg):
223224
return zpad(encode_int(arg), 32)
224-
elif len(arg) == len(sub):
225+
elif len(arg) == int(sub):
225226
return zpad(arg, 32)
226-
elif len(arg) == len(sub) * 2:
227+
elif len(arg) == int(sub) * 2:
227228
return zpad(decode_hex(arg), 32)
228229
else:
229230
raise EncodingError("Could not parse hash: %r" % arg)
@@ -236,7 +237,7 @@ def encode_single(typ, arg):
236237
return zpad(arg, 32)
237238
elif len(arg) == 40:
238239
return zpad(decode_hex(arg), 32)
239-
elif len(arg) == 42 and arg[2:] == '0x':
240+
elif len(arg) == 42 and arg[:2] == '0x':
240241
return zpad(decode_hex(arg[2:]), 32)
241242
else:
242243
raise EncodingError("Could not parse address: %r" % arg)
@@ -255,6 +256,8 @@ def process_type(typ):
255256
if base == 'string' or base == 'bytes':
256257
assert re.match('^[0-9]*$', sub), \
257258
"String type must have no suffix or numerical suffix"
259+
assert not sub or int(sub) <= 32, \
260+
"Maximum 32 bytes for fixed-length str or bytes"
258261
# Check validity of integer type
259262
elif base == 'uint' or base == 'int':
260263
assert re.match('^[0-9]+$', sub), \
@@ -263,12 +266,6 @@ def process_type(typ):
263266
"Integer size out of bounds"
264267
assert int(sub) % 8 == 0, \
265268
"Integer size must be multiple of 8"
266-
# Check validity of string type
267-
if base == 'string' or base == 'bytes':
268-
assert re.match('^[0-9]*$', sub), \
269-
"String type must have no suffix or numerical suffix"
270-
assert not sub or int(sub) <= 32, \
271-
"Maximum 32 bytes for fixed-length str or bytes"
272269
# Check validity of real type
273270
elif base == 'ureal' or base == 'real':
274271
assert re.match('^[0-9]+x[0-9]+$', sub), \
@@ -375,8 +372,14 @@ def decode_single(typ, data):
375372
base, sub, _ = typ
376373
if base == 'address':
377374
return encode_hex(data[12:])
378-
elif base == 'string' or base == 'bytes' or base == 'hash':
379-
return data[:int(sub)] if len(sub) else data
375+
elif base == 'hash':
376+
return data[32-int(sub):]
377+
elif base == 'string' or base == 'bytes':
378+
if len(sub):
379+
return data[:int(sub)]
380+
else:
381+
l = big_endian_to_int(data[0:32])
382+
return data[32:][:l]
380383
elif base == 'uint':
381384
return big_endian_to_int(data)
382385
elif base == 'int':
@@ -387,7 +390,9 @@ def decode_single(typ, data):
387390
return big_endian_to_int(data) * 1.0 / 2**low
388391
elif base == 'real':
389392
high, low = [int(x) for x in sub.split('x')]
390-
return (big_endian_to_int(data) * 1.0 / 2**low) % 2**high
393+
o = big_endian_to_int(data)
394+
i = (o - 2**(high+low)) if o >= 2**(high+low-1) else o
395+
return (i * 1.0 / 2**low)
391396
elif base == 'bool':
392397
return bool(int(data.encode('hex'), 16))
393398

ethereum/blocks.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@
3434
Log = processblock.Log
3535

3636

37+
class lazy_encode(object):
38+
def __init__(self, data):
39+
self.data = data
40+
41+
def __repr__(self):
42+
return repr([[k, encode_hex(a), v if k != 'code' else encode_hex(v)] for k, a, v in self.data])
43+
44+
def __str__(self):
45+
return str(repr(self))
46+
3747

3848
# Difficulty adjustment algo
3949
def calc_difficulty(parent, timestamp):
@@ -257,12 +267,10 @@ def receipts_root(self, value):
257267
else:
258268
self._receipts_root = value
259269

260-
_fimxe_hash = None
261-
262270
@property
263271
def hash(self):
264272
"""The binary block hash"""
265-
return self._fimxe_hash or utils.sha3(rlp.encode(self))
273+
return utils.sha3(rlp.encode(self))
266274

267275
def hex_hash(self):
268276
"""The hex encoded block hash"""
@@ -381,7 +389,6 @@ def __init__(self, header, transaction_list=[], uncles=[], env=None,
381389
self.header = header
382390
self.uncles = uncles
383391

384-
self.uncles = uncles
385392
self.suicides = []
386393
self.logs = []
387394
self.log_listeners = []
@@ -647,6 +654,10 @@ def validate_uncles(self):
647654
parent = get_block(self.env, uncle.prevhash)
648655
if uncle.difficulty != calc_difficulty(parent, uncle.timestamp):
649656
return False
657+
if uncle.number != parent.number + 1:
658+
return False
659+
if uncle.timestamp < parent.timestamp:
660+
return False
650661
if not uncle.check_pow():
651662
return False
652663
if uncle.prevhash not in eligible_ancestor_hashes:
@@ -1018,7 +1029,7 @@ def commit_state(self):
10181029
t.delete(enckey)
10191030
acct.storage = t.root_hash
10201031
self.state.update(addr, rlp.encode(acct))
1021-
log_state.trace('delta', changes=changes)
1032+
log_state.trace('delta', changes=lazy_encode(changes))
10221033
self.reset_cache()
10231034
self.db.put_temporarily(b'validated:' + self.hash, '1')
10241035

ethereum/bloom.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1414
bloom(0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6)
1515
sha3: bd2b01afcd27800b54d2179edc49e2bffde5078bb6d0b204694169b1643fb108
16-
first double-bytes: bd2b, 01af, cd27 -- which leads to bits in bloom --> 299, 431, 295
16+
first double-bytes: bd2b, 01af, cd27 -- which leads to bits in bloom --> 1323, 431, 1319
1717
1818
blooms in this module are of type 'int'
1919
"""

ethereum/chain.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
from rlp.utils import encode_hex
1010
from ethereum import blocks
1111
from ethereum import processblock
12+
from ethereum.exceptions import VerificationFailed, InvalidTransaction
1213
from ethereum.slogging import get_logger
1314
from ethereum.config import Env
14-
import sys
1515
log = get_logger('eth.chain')
1616

1717

@@ -301,7 +301,7 @@ def add_block(self, block, forward_pending_transactions=True):
301301
if block.has_parent():
302302
try:
303303
processblock.verify(block, block.get_parent())
304-
except processblock.VerificationFailed as e:
304+
except VerificationFailed as e:
305305
_log.critical('VERIFICATION FAILED', error=e)
306306
f = os.path.join(utils.data_dir, 'badblock.log')
307307
open(f, 'w').write(to_string(block.hex_serialize()))
@@ -351,7 +351,7 @@ def add_transaction(self, transaction):
351351
head_candidate.state_root = self.pre_finalize_state_root
352352
try:
353353
success, output = processblock.apply_transaction(head_candidate, transaction)
354-
except processblock.InvalidTransaction as e:
354+
except InvalidTransaction as e:
355355
# if unsuccessful the prerequisites were not fullfilled
356356
# and the tx is invalid, state must not have changed
357357
log.debug('invalid tx', error=e)

ethereum/processblock.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import sys
22
import rlp
33
from rlp.sedes import CountableList, binary
4-
from rlp.utils import decode_hex, encode_hex, ascii_chr, str_to_bytes
4+
from rlp.utils import decode_hex, encode_hex, ascii_chr
55
from ethereum import opcodes
66
from ethereum import utils
77
from ethereum import specials
88
from ethereum import bloom
99
from ethereum import vm as vm
10-
from ethereum.exceptions import *
11-
from ethereum.utils import safe_ord, normalize_address, mk_contract_address
10+
from ethereum.exceptions import InvalidNonce, InsufficientStartGas, UnsignedTransaction, \
11+
BlockGasLimitReached, InsufficientBalance
12+
from ethereum.utils import safe_ord, mk_contract_address
1213
from ethereum import transactions
14+
import ethereum.config as config
1315

1416
sys.setrecursionlimit(100000)
1517

@@ -80,6 +82,8 @@ def rp(what, actual, target):
8082
# (1) The transaction signature is valid;
8183
if not tx.sender: # sender is set and validated on Transaction initialization
8284
raise UnsignedTransaction(tx)
85+
if block.number >= config.default_config["HOMESTEAD_FORK_BLKNUM"]:
86+
tx.check_low_s()
8387

8488
# (2) the transaction nonce is valid (equivalent to the
8589
# sender account's current nonce);
@@ -105,6 +109,30 @@ def rp(what, actual, target):
105109
return True
106110

107111

112+
class lazy_safe_encode(object):
113+
"""Creates a lazy and logging safe representation of transaction data.
114+
Use this in logging of transactions; instead of
115+
116+
>>> log.debug(data=data)
117+
118+
do this:
119+
120+
>>> log.debug(data=lazy_safe_encode(data))
121+
"""
122+
123+
def __init__(self, data):
124+
self.data = data
125+
126+
def __str__(self):
127+
if not isinstance(self.data, (str, unicode)):
128+
return repr(self.data)
129+
else:
130+
return encode_hex(self.data)
131+
132+
def __repr__(self):
133+
return str(self)
134+
135+
108136
def apply_transaction(block, tx):
109137
validate_transaction(block, tx)
110138

@@ -124,7 +152,7 @@ def rp(what, actual, target):
124152
log_tx.debug('TX NEW', tx_dict=tx.log_dict())
125153
# start transacting #################
126154
block.increment_nonce(tx.sender)
127-
155+
128156
# buy startgas
129157
assert block.get_balance(tx.sender) >= tx.startgas * tx.gasprice
130158
block.delta_balance(tx.sender, -tx.startgas * tx.gasprice)
@@ -136,16 +164,16 @@ def rp(what, actual, target):
136164
ext = VMExt(block, tx)
137165
if tx.to and tx.to != CREATE_CONTRACT_ADDRESS:
138166
result, gas_remained, data = apply_msg(ext, message)
139-
log_tx.debug('_res_', result=result, gas_remained=gas_remained, data=data)
167+
log_tx.debug('_res_', result=result, gas_remained=gas_remained, data=lazy_safe_encode(data))
140168
else: # CREATE
141169
result, gas_remained, data = create_contract(ext, message)
142170
assert utils.is_numeric(gas_remained)
143-
log_tx.debug('_create_', result=result, gas_remained=gas_remained, data=data)
171+
log_tx.debug('_create_', result=result, gas_remained=gas_remained, data=lazy_safe_encode(data))
144172

145173
assert gas_remained >= 0
146174

147175
log_tx.debug("TX APPLIED", result=result, gas_remained=gas_remained,
148-
data=data)
176+
data=lazy_safe_encode(data))
149177

150178
if not result: # 0 = OOG failure in both cases
151179
log_tx.debug('TX FAILED', reason='out of gas',
@@ -155,7 +183,7 @@ def rp(what, actual, target):
155183
output = b''
156184
success = 0
157185
else:
158-
log_tx.debug('TX SUCCESS', data=data)
186+
log_tx.debug('TX SUCCESS', data=lazy_safe_encode(data))
159187
gas_used = tx.startgas - gas_remained
160188
block.refunds += len(set(block.suicides)) * opcodes.GSUICIDEREFUND
161189
if block.refunds > 0:
@@ -251,7 +279,7 @@ def _apply_msg(ext, msg, code):
251279
# assert utils.is_numeric(gas)
252280
if trace_msg:
253281
log_msg.debug('MSG APPLIED', gas_remained=gas,
254-
sender=msg.sender, to=msg.to, data=dat)
282+
sender=encode_hex(msg.sender), to=encode_hex(msg.to), data=dat)
255283
if log_state.is_active('trace'):
256284
log_state.trace('MSG POST STATE SENDER', account=msg.sender.encode('hex'),
257285
bal=ext.get_balance(msg.sender),

0 commit comments

Comments
 (0)