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

Commit f0b696a

Browse files
vubvub
authored andcommitted
Added new tester module
1 parent a70b075 commit f0b696a

File tree

4 files changed

+147
-3
lines changed

4 files changed

+147
-3
lines changed

ethereum/ethpow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def mine(block_number, difficulty, mining_hash, start_nonce=0, rounds=1000):
112112
assert utils.is_numeric(start_nonce)
113113
cache = get_cache(block_number)
114114
nonce = start_nonce
115-
target = utils.zpad(utils.int_to_big_endian(2**256 // (difficulty or 1)), 32)
115+
target = utils.zpad(utils.int_to_big_endian(2**256 // (difficulty or 1) - 1), 32)
116116
for i in range(1, rounds + 1):
117117
bin_nonce = utils.zpad(utils.int_to_big_endian((nonce + i) & TT64M1), 8)
118118
o = hashimoto_light(block_number, cache, mining_hash, bin_nonce)

ethereum/parse_genesis_declaration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def mk_basic_state(alloc, header, env):
9090
if not header:
9191
header = {
9292
"number": 0, "gas_limit": 4712388, "gas_used": 0,
93-
"timestamp": 1467446877, "difficulty": 2**25,
93+
"timestamp": 1467446877, "difficulty": 1,
9494
"uncles_hash": '0x'+encode_hex(BLANK_UNCLES_HASH)
9595
}
9696
h = BlockHeader(number=parse_as_int(header['number']),

ethereum/tester2.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
from ethereum.utils import sha3, privtoaddr, int_to_addr, to_string
2+
from ethereum.parse_genesis_declaration import mk_basic_state
3+
from ethereum import chain
4+
from ethereum.transactions import Transaction
5+
from ethereum.consensus_strategy import get_consensus_strategy
6+
from ethereum.config import Env
7+
from ethereum.ethpow import Miner
8+
from ethereum.state_transition import apply_transaction, verify_execution_results
9+
from ethereum.block_creation import pre_seal
10+
from ethereum.abi import ContractTranslator
11+
import rlp
12+
# Initialize accounts
13+
accounts = []
14+
keys = []
15+
16+
for account_number in range(10):
17+
keys.append(sha3(to_string(account_number)))
18+
accounts.append(privtoaddr(keys[-1]))
19+
20+
k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 = keys[:10]
21+
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = accounts[:10]
22+
23+
base_alloc = {}
24+
for a in accounts:
25+
base_alloc[a] = {'balance': 10**18}
26+
for i in range(16):
27+
base_alloc[int_to_addr(i)] = {'balance': 1}
28+
29+
# Initialize languages
30+
languages = {}
31+
32+
try:
33+
import serpent
34+
languages['serpent'] = serpent
35+
except ImportError:
36+
pass
37+
38+
from ethereum._solidity import get_solidity
39+
_solidity = get_solidity()
40+
if _solidity:
41+
languages['solidity'] = _solidity
42+
43+
try:
44+
from viper import compiler
45+
languages['viper'] = compiler
46+
except ImportError:
47+
pass
48+
49+
from ethereum.abi import ContractTranslator
50+
import types
51+
52+
STARTGAS = 3141592
53+
GASPRICE = 1
54+
55+
from ethereum.slogging import configure_logging
56+
config_string = ':info'
57+
# configure_logging(config_string=config_string)
58+
59+
class ABIContract(object): # pylint: disable=too-few-public-methods
60+
61+
def __init__(self, _chain, _abi, address):
62+
self.address = address
63+
64+
if isinstance(_abi, ContractTranslator):
65+
abi_translator = _abi
66+
else:
67+
abi_translator = ContractTranslator(_abi)
68+
69+
self.translator = abi_translator
70+
71+
for function_name in self.translator.function_data:
72+
function = self.method_factory(_chain, function_name)
73+
method = types.MethodType(function, self)
74+
setattr(self, function_name, method)
75+
76+
@staticmethod
77+
def method_factory(test_chain, function_name):
78+
""" Return a proxy for calling a contract method with automatic encoding of
79+
argument and decoding of results.
80+
"""
81+
82+
def kall(self, *args, **kwargs):
83+
key = kwargs.get('sender', k0)
84+
85+
result = test_chain.tx( # pylint: disable=protected-access
86+
sender=key,
87+
to=self.address,
88+
value=kwargs.get('value', 0),
89+
data=self.translator.encode(function_name, args),
90+
startgas=kwargs.get('startgas', STARTGAS)
91+
)
92+
93+
o = self.translator.decode(function_name, result)
94+
return o[0] if len(o) == 1 else o
95+
return kall
96+
97+
98+
class Chain(object):
99+
def __init__(self, alloc=None, env=None):
100+
self.chain = chain.Chain(mk_basic_state(base_alloc if alloc is None else alloc,
101+
None,
102+
Env() if env is None else env))
103+
self.cs = get_consensus_strategy(self.chain.env.config)
104+
self.block = self.cs.block_setup(self.chain, timestamp=self.chain.state.timestamp + 1)
105+
self.head_state = self.chain.state.ephemeral_clone()
106+
107+
@property
108+
def last_tx(self):
109+
return self.txs_this_block[-1] if self.txs_this_block else None
110+
111+
def tx(self, sender=k0, to=b'\x00' * 20, value=0, data=b'', startgas=STARTGAS, gasprice=GASPRICE):
112+
sender_addr = privtoaddr(sender)
113+
transaction = Transaction(self.head_state.get_nonce(sender_addr), gasprice, startgas,
114+
to, value, data).sign(sender)
115+
success, output = apply_transaction(self.head_state, transaction)
116+
self.block.transactions.append(transaction)
117+
if not success:
118+
return False
119+
return output
120+
121+
def contract(self, sourcecode, args=[], sender=k0, value=0, language='evm', startgas=STARTGAS, gasprice=GASPRICE):
122+
if language == 'evm':
123+
assert len(args) == 0
124+
return self.tx(sender=sender, to=b'', value=value, data=sourcecode, startgas=startgas, gasprice=gasprice)
125+
else:
126+
compiler = languages[language]
127+
interface = compiler.mk_full_signature(sourcecode)
128+
ct = ContractTranslator(interface)
129+
code = compiler.compile(sourcecode) + (ct.encode_constructor_arguments(args) if args else b'')
130+
addr = self.tx(sender=sender, to=b'', value=value, data=code, startgas=startgas, gasprice=gasprice)
131+
return ABIContract(self, ct, addr)
132+
133+
def mine(self, number_of_blocks=1, coinbase=a0):
134+
pre_seal(self.head_state, self.block)
135+
self.block = Miner(self.block).mine(rounds=100, start_nonce=0)
136+
assert self.chain.add_block(self.block)
137+
assert self.head_state.trie.root_hash == self.chain.state.trie.root_hash
138+
for i in range(1, number_of_blocks):
139+
b = self.cs.block_setup(self.chain, timestamp=self.chain.state.timestamp + 1)
140+
pre_seal(self.chain.state.ephemeral_clone(), b)
141+
b = Miner(b).mine(rounds=100, start_nonce=0)
142+
assert self.chain.add_block(b)
143+
self.block = self.cs.block_setup(self.chain, timestamp=self.chain.state.timestamp + 1)
144+
self.head_state = self.chain.state.ephemeral_clone()

ethereum/vm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def __init__(self, sender, to, value=0, gas=1000000, data='', depth=0,
6767
self.to = to
6868
self.value = value
6969
self.gas = gas
70-
self.data = CallData(map(ord, data)) if isinstance(data, (str, bytes)) else data
70+
self.data = CallData(list(map(utils.safe_ord, data))) if isinstance(data, (str, bytes)) else data
7171
self.depth = depth
7272
self.logs = []
7373
self.code_address = to if code_address is None else code_address

0 commit comments

Comments
 (0)