Skip to content

Commit

Permalink
Merge pull request ethereum#439 from LefterisJP/correct_turing
Browse files Browse the repository at this point in the history
Shouldn't have a number equal to 2^256 in EVM
  • Loading branch information
konradkonrad authored Mar 3, 2017
2 parents ff0f149 + cfd86bf commit 64e9f63
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 45 deletions.
20 changes: 16 additions & 4 deletions ethereum/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@
from ethereum.pruning_trie import Trie
from ethereum.securetrie import SecureTrie
from ethereum import utils
from ethereum.utils import address, int256, trie_root, hash32, to_string, big_endian_to_int
from ethereum.utils import (
address,
int256,
trie_root,
hash32,
to_string,
big_endian_to_int,
TT256,
)
from ethereum import processblock
from ethereum.transactions import Transaction
from ethereum import bloom
Expand All @@ -30,7 +38,6 @@
else:
from functools import lru_cache


log = get_logger('eth.block')
log_state = get_logger('eth.msg.state')
Log = processblock.Log
Expand Down Expand Up @@ -920,7 +927,10 @@ def get_balance(self, address):
:param address: the address of the account (binary or hex string)
"""
return self._get_acct_item(address, 'balance')
balance = self._get_acct_item(address, 'balance')
if balance >= TT256:
raise ValueError("balance too high")
return balance

def set_balance(self, address, value):
"""Set the balance of an account.
Expand All @@ -929,6 +939,8 @@ def set_balance(self, address, value):
:param value: the new balance
:returns: `True` if successful, otherwise `False`
"""
if value >= TT256:
raise ValueError("value too high")
self._set_acct_item(address, 'balance', value)

def delta_balance(self, address, value):
Expand All @@ -950,7 +962,7 @@ def transfer_value(self, from_addr, to_addr, value):
:param value: the (positive) value to send
:returns: `True` if successful, otherwise `False`
"""
assert value >= 0
assert value >= 0 and value < TT256
if self.delta_balance(from_addr, -value):
return self.delta_balance(to_addr, value)
return False
Expand Down
103 changes: 63 additions & 40 deletions ethereum/tests/test_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
from rlp.utils import decode_hex
from ethereum.utils import encode_hex
import ethereum.ethpow as ethpow
import ethereum.utils as utils
from ethereum.utils import (
sha3,
privtoaddr,
denoms,
dump_state,
)
from ethereum.chain import Chain
from ethereum.db import EphemDB
from ethereum.tests.utils import new_db
Expand All @@ -29,10 +34,10 @@ def env(db):

@pytest.fixture(scope="module")
def accounts():
k = utils.sha3(b'cow')
v = utils.privtoaddr(k)
k2 = utils.sha3(b'horse')
v2 = utils.privtoaddr(k2)
k = sha3(b'cow')
v = privtoaddr(k)
k2 = sha3(b'horse')
v2 = privtoaddr(k2)
return k, v, k2, v2


Expand Down Expand Up @@ -106,7 +111,7 @@ def get_transaction(gasprice=0, nonce=0):
k, v, k2, v2 = accounts()
tx = transactions.Transaction(
nonce, gasprice, startgas=100000,
to=v2, value=utils.denoms.finney * 10, data='').sign(k)
to=v2, value=denoms.finney * 10, data='').sign(k)
return tx


Expand All @@ -115,9 +120,19 @@ def store_block(blk):
assert blocks.get_block(env(blk.db), blk.hash) == blk


def test_transfer(db):
@pytest.mark.parametrize('balance', [
denoms.wei * 10000,
denoms.babbage,
denoms.lovelace,
denoms.shannon,
denoms.szabo,
denoms.finney,
denoms.ether,
denoms.turing
])
def test_transfer(db, balance):
k, v, k2, v2 = accounts()
blk = blocks.genesis(env(db), start_alloc={v: {"balance": utils.denoms.ether * 1}})
blk = blocks.genesis(env(db), start_alloc={v: {"balance": balance}})
b_v = blk.get_balance(v)
b_v2 = blk.get_balance(v2)
value = 42
Expand All @@ -127,12 +142,20 @@ def test_transfer(db):
assert blk.get_balance(v2) == b_v2 + value


def test_alloc_too_big(db):
k, v, k2, v2 = accounts()
blk = None
with pytest.raises(ValueError):
blk = blocks.genesis(env(db), start_alloc={v: {"balance": 2 ** 256}})
assert blk is None


def test_failing_transfer(db):
k, v, k2, v2 = accounts()
blk = blocks.genesis(env(db), start_alloc={v: {"balance": utils.denoms.ether * 1}})
blk = blocks.genesis(env(db), start_alloc={v: {"balance": denoms.ether * 1}})
b_v = blk.get_balance(v)
b_v2 = blk.get_balance(v2)
value = utils.denoms.ether * 2
value = denoms.ether * 2
# should fail
success = blk.transfer_value(v, v2, value)
assert not success
Expand All @@ -149,19 +172,19 @@ def test_serialize_block(db):

def test_genesis(db, alt_db):
k, v, k2, v2 = accounts()
blk = blocks.genesis(env(db), start_alloc={v: {"balance": utils.denoms.ether * 1}})
blk = blocks.genesis(env(db), start_alloc={v: {"balance": denoms.ether * 1}})
# sr = blk.state_root
assert blk.state.db.db == db.db
db.put(blk.hash, rlp.encode(blk))
blk.state.db.commit()
# assert sr in db
db.commit()
# assert sr in db
blk2 = blocks.genesis(env(db), start_alloc={v: {"balance": utils.denoms.ether * 1}})
blk2 = blocks.genesis(env(db), start_alloc={v: {"balance": denoms.ether * 1}})
blk3 = blocks.genesis(env(db))
assert blk == blk2
assert blk != blk3
blk2 = blocks.genesis(env(alt_db), start_alloc={v: {"balance": utils.denoms.ether * 1}})
blk2 = blocks.genesis(env(alt_db), start_alloc={v: {"balance": denoms.ether * 1}})
blk3 = blocks.genesis(env(alt_db))
assert blk == blk2
assert blk != blk3
Expand All @@ -184,21 +207,21 @@ def test_deserialize_commit(db):

def test_genesis_db(db, alt_db):
k, v, k2, v2 = accounts()
blk = blocks.genesis(env(db), start_alloc={v: {"balance": utils.denoms.ether * 1}})
blk = blocks.genesis(env(db), start_alloc={v: {"balance": denoms.ether * 1}})
store_block(blk)
blk2 = blocks.genesis(env(db), start_alloc={v: {"balance": utils.denoms.ether * 1}})
blk2 = blocks.genesis(env(db), start_alloc={v: {"balance": denoms.ether * 1}})
blk3 = blocks.genesis(env(db))
assert blk == blk2
assert blk != blk3
blk2 = blocks.genesis(env(alt_db), start_alloc={v: {"balance": utils.denoms.ether * 1}})
blk2 = blocks.genesis(env(alt_db), start_alloc={v: {"balance": denoms.ether * 1}})
blk3 = blocks.genesis(env(alt_db))
assert blk == blk2
assert blk != blk3


def test_mine_block(db):
k, v, k2, v2 = accounts()
blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db)
blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db)
store_block(blk)
blk2 = mine_next_block(blk, coinbase=v)
store_block(blk2)
Expand All @@ -220,21 +243,21 @@ def test_block_serialization_with_transaction_empty_genesis(db):

def test_mine_block_with_transaction(db):
k, v, k2, v2 = accounts()
blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=db)
blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db=db)
store_block(blk)
tx = get_transaction()
blk = mine_next_block(blk, transactions=[tx])
assert tx in blk.get_transactions()
assert blk.get_transaction(0) == tx
with pytest.raises(IndexError):
blk.get_transaction(1)
assert blk.get_balance(v) == utils.denoms.finney * 990
assert blk.get_balance(v2) == utils.denoms.finney * 10
assert blk.get_balance(v) == denoms.finney * 990
assert blk.get_balance(v2) == denoms.finney * 10


def test_mine_block_with_transaction2(db):
k, v, k2, v2 = accounts()
blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db)
blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db)
store_block(blk)
tx = get_transaction()
blk2 = mine_next_block(blk, coinbase=v, transactions=[tx])
Expand All @@ -253,18 +276,18 @@ def test_mine_block_with_transaction2(db):

def test_mine_block_with_transaction3(db):
k, v, k2, v2 = accounts()
blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db)
blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db)
store_block(blk)
tx = get_transaction()
blk = mine_next_block(blk, transactions=[tx])
assert tx in blk.get_transactions()
assert blk.get_balance(v) == utils.denoms.finney * 990
assert blk.get_balance(v2) == utils.denoms.finney * 10
assert blk.get_balance(v) == denoms.finney * 990
assert blk.get_balance(v2) == denoms.finney * 10


def test_block_serialization_same_db(db):
k, v, k2, v2 = accounts()
blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db)
blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db)
assert blk.hash == rlp.decode(rlp.encode(blk), blocks.Block, env=env(db)).hash
store_block(blk)
blk2 = mine_next_block(blk)
Expand Down Expand Up @@ -299,20 +322,20 @@ def test_block_serialization_with_transaction_other_db():
k, v, k2, v2 = accounts()
a_db, b_db = db(), db()
# mine two blocks
a_blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=a_db)
a_blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db=a_db)
store_block(a_blk)
tx = get_transaction()
logger.debug('a: state_root before tx %r' % hx(a_blk.state_root))
logger.debug('a: state:\n%s' % utils.dump_state(a_blk.state))
logger.debug('a: state:\n%s' % dump_state(a_blk.state))
a_blk2 = mine_next_block(a_blk, transactions=[tx])
logger.debug('a: state_root after tx %r' % hx(a_blk2.state_root))
logger.debug('a: state:\n%s' % utils.dump_state(a_blk2.state))
logger.debug('a: state:\n%s' % dump_state(a_blk2.state))
assert tx in a_blk2.get_transactions()
store_block(a_blk2)
assert tx in a_blk2.get_transactions()
logger.debug('preparing receiving chain ---------------------')
# receive in other db
b_blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, b_db)
b_blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, b_db)
store_block(b_blk)

assert b_blk.number == 0
Expand All @@ -332,15 +355,15 @@ def test_block_serialization_with_transaction_other_db():

def test_transaction(db):
k, v, k2, v2 = accounts()
blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=db)
blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db=db)
store_block(blk)
blk = mine_next_block(blk)
tx = get_transaction()
assert tx not in blk.get_transactions()
success, res = processblock.apply_transaction(blk, tx)
assert tx in blk.get_transactions()
assert blk.get_balance(v) == utils.denoms.finney * 990
assert blk.get_balance(v2) == utils.denoms.finney * 10
assert blk.get_balance(v) == denoms.finney * 990
assert blk.get_balance(v2) == denoms.finney * 10


def test_transaction_serialization():
Expand All @@ -353,12 +376,12 @@ def test_transaction_serialization():

def test_invalid_transaction(db):
k, v, k2, v2 = accounts()
blk = mkquickgenesis({v2: {"balance": utils.denoms.ether * 1}}, db=db)
blk = mkquickgenesis({v2: {"balance": denoms.ether * 1}}, db=db)
store_block(blk)
tx = get_transaction()
blk = mine_next_block(blk, transactions=[tx])
assert blk.get_balance(v) == 0
assert blk.get_balance(v2) == utils.denoms.ether * 1
assert blk.get_balance(v2) == denoms.ether * 1
assert tx not in blk.get_transactions()


Expand All @@ -371,7 +394,7 @@ def test_prevhash(db):

def test_genesis_chain(db):
k, v, k2, v2 = accounts()
blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=db)
blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db=db)
chain = Chain(env=env(blk.db), genesis=blk)

assert chain.has_block(blk.hash)
Expand All @@ -392,7 +415,7 @@ def test_genesis_chain(db):

def test_simple_chain(db):
k, v, k2, v2 = accounts()
blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=db)
blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db=db)
store_block(blk)
chain = Chain(env=env(blk.db), genesis=blk)
tx = get_transaction()
Expand Down Expand Up @@ -437,15 +460,15 @@ def test_add_side_chain(db, alt_db):
"""
k, v, k2, v2 = accounts()
# Remote: mine one block
R0 = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=db)
R0 = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db=db)
store_block(R0)
tx0 = get_transaction(nonce=0)
R1 = mine_next_block(R0, transactions=[tx0])
store_block(R1)
assert tx0.hash in [x.hash for x in R1.get_transactions()]

# Local: mine two blocks
L0 = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, alt_db)
L0 = mkquickgenesis({v: {"balance": denoms.ether * 1}}, alt_db)
chain = Chain(env=env(L0.db), genesis=L0)
tx0 = get_transaction(nonce=0)
L1 = mine_next_block(L0, transactions=[tx0])
Expand All @@ -470,7 +493,7 @@ def test_add_longer_side_chain(db, alt_db):
"""
k, v, k2, v2 = accounts()
# Remote: mine one block
blk = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=db)
blk = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db=db)
store_block(blk)
remote_blocks = [blk]
for i in range(3):
Expand All @@ -479,7 +502,7 @@ def test_add_longer_side_chain(db, alt_db):
store_block(blk)
remote_blocks.append(blk)
# Local: mine two blocks
L0 = mkquickgenesis({v: {"balance": utils.denoms.ether * 1}}, db=alt_db)
L0 = mkquickgenesis({v: {"balance": denoms.ether * 1}}, db=alt_db)
chain = Chain(env=env(L0.db), genesis=L0)
tx0 = get_transaction(nonce=0)
L1 = mine_next_block(L0, transactions=[tx0])
Expand Down
3 changes: 2 additions & 1 deletion ethereum/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,8 @@ def __init__(self):
self.szabo = 10 ** 12
self.finney = 10 ** 15
self.ether = 10 ** 18
self.turing = 2 ** 256
self.turing = 2 ** 256 - 1


denoms = Denoms()

Expand Down

0 comments on commit 64e9f63

Please sign in to comment.