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

Commit ecb14c9

Browse files
committed
Removed bitcoin dependency, and made syncing work with receipt root skipping
1 parent 8931e49 commit ecb14c9

File tree

8 files changed

+69
-54
lines changed

8 files changed

+69
-54
lines changed

ethereum/config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ def __init__(self, db=None, config=None, global_config=None):
9696
self.config = config or dict(default_config)
9797
self.global_config = global_config or dict()
9898

99+
config_frontier = copy.copy(default_config)
100+
config_frontier["HOMESTEAD_FORK_BLKNUM"] = 2**99
101+
config_frontier["ANTI_DOS_FORK_BLKNUM"] = 2**99
102+
config_frontier["SPURIOUS_DRAGON_FORK_BLKNUM"] = 2**99
103+
config_frontier["METROPOLIS_FORK_BLKNUM"] = 2**99
104+
99105
config_homestead = copy.copy(default_config)
100106
config_homestead["HOMESTEAD_FORK_BLKNUM"] = 0
101107
config_homestead["ANTI_DOS_FORK_BLKNUM"] = 2**99

ethereum/specials.py

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf8 -*-
2-
import bitcoin
2+
from py_ecc.secp256k1 import privtopub, ecdsa_raw_recover, N as secp256k1n
3+
import hashlib
34
from rlp.utils import ascii_chr
45

56
from ethereum import utils, opcodes
@@ -26,7 +27,7 @@ def proc_ecrecover(ext, msg):
2627
r = msg.data.extract32(64)
2728
s = msg.data.extract32(96)
2829

29-
if r >= bitcoin.N or s >= bitcoin.N or v < 27 or v > 28:
30+
if r >= secp256k1n or s >= secp256k1n or v < 27 or v > 28:
3031
return 1, msg.gas - opcodes.GECRECOVER, []
3132
try:
3233
pub = utils.ecrecover_to_pub(message_hash, v, r, s)
@@ -44,7 +45,7 @@ def proc_sha256(ext, msg):
4445
if msg.gas < gas_cost:
4546
return 0, 0, []
4647
d = msg.data.extract_all()
47-
o = [safe_ord(x) for x in bitcoin.bin_sha256(d)]
48+
o = [safe_ord(x) for x in hashlib.sha256(d).digest()]
4849
return 1, msg.gas - gas_cost, o
4950

5051

@@ -56,7 +57,7 @@ def proc_ripemd160(ext, msg):
5657
if msg.gas < gas_cost:
5758
return 0, 0, []
5859
d = msg.data.extract_all()
59-
o = [0] * 12 + [safe_ord(x) for x in bitcoin.ripemd.RIPEMD160(d).digest()]
60+
o = [0] * 12 + [safe_ord(x) for x in hashlib.new('ripemd160', d).digest()]
6061
return 1, msg.gas - gas_cost, o
6162

6263

@@ -100,13 +101,13 @@ def proc_modexp(ext, msg):
100101
return 1, msg.gas - gas_cost, [safe_ord(x) for x in utils.zpad(utils.int_to_big_endian(o), modlen)]
101102

102103
def validate_point(x, y):
103-
import py_pairing
104-
FQ = py_pairing.FQ
105-
if x >= py_pairing.field_modulus or y >= py_pairing.field_modulus:
104+
import py_ecc.optimized_bn128 as bn128
105+
FQ = bn128.FQ
106+
if x >= bn128.field_modulus or y >= bn128.field_modulus:
106107
return False
107108
if (x, y) != (0, 0):
108109
p1 = (FQ(x), FQ(y), FQ(1))
109-
if not py_pairing.is_on_curve(p1, py_pairing.b):
110+
if not bn128.is_on_curve(p1, bn128.b):
110111
return False
111112
else:
112113
p1 = (FQ(1), FQ(1), FQ(0))
@@ -115,8 +116,8 @@ def validate_point(x, y):
115116
def proc_ecadd(ext, msg):
116117
if not ext.post_metropolis_hardfork():
117118
return 1, msg.gas, []
118-
import py_pairing
119-
FQ = py_pairing.FQ
119+
import py_ecc.optimized_bn128 as bn128
120+
FQ = bn128.FQ
120121
print('ecadd proc', msg.gas)
121122
if msg.gas < opcodes.GECADD:
122123
return 0, 0, []
@@ -128,14 +129,14 @@ def proc_ecadd(ext, msg):
128129
p2 = validate_point(x2, y2)
129130
if p1 is False or p2 is False:
130131
return 0, 0, []
131-
o = py_pairing.normalize(py_pairing.add(p1, p2))
132+
o = bn128.normalize(bn128.add(p1, p2))
132133
return 1, msg.gas - opcodes.GECADD, [safe_ord(x) for x in (encode_int32(o[0].n) + encode_int32(o[1].n))]
133134

134135
def proc_ecmul(ext, msg):
135136
if not ext.post_metropolis_hardfork():
136137
return 1, msg.gas, []
137-
import py_pairing
138-
FQ = py_pairing.FQ
138+
import py_ecc.optimized_bn128 as bn128
139+
FQ = bn128.FQ
139140
print('ecmul proc', msg.gas)
140141
if msg.gas < opcodes.GECMUL:
141142
return 0, 0, []
@@ -145,24 +146,24 @@ def proc_ecmul(ext, msg):
145146
p = validate_point(x, y)
146147
if p is False:
147148
return 0, 0, []
148-
o = py_pairing.normalize(py_pairing.multiply(p, m))
149+
o = bn128.normalize(bn128.multiply(p, m))
149150
return (1, msg.gas - opcodes.GECMUL,
150151
[safe_ord(c) for c in (encode_int32(o[0].n) + encode_int32(o[1].n))])
151152

152153
def proc_ecpairing(ext, msg):
153154
if not ext.post_metropolis_hardfork():
154155
return 1, msg.gas, []
155-
import py_pairing
156-
FQ = py_pairing.FQ
156+
import py_ecc.optimized_bn128 as bn128
157+
FQ = bn128.FQ
157158
print('pairing proc', msg.gas)
158159
# Data must be an exact multiple of 192 byte
159160
if msg.data.size % 192:
160161
return 0, 0, []
161162
gascost = opcodes.GPAIRINGBASE + msg.data.size // 192 * opcodes.GPAIRINGPERPOINT
162163
if msg.gas < gascost:
163164
return 0, 0, []
164-
zero = (py_pairing.FQ2.one(), py_pairing.FQ2.one(), py_pairing.FQ2.zero())
165-
exponent = py_pairing.FQ12.one()
165+
zero = (bn128.FQ2.one(), bn128.FQ2.one(), bn128.FQ2.zero())
166+
exponent = bn128.FQ12.one()
166167
for i in range(0, msg.data.size, 192):
167168
x1 = msg.data.extract32(i)
168169
y1 = msg.data.extract32(i + 32)
@@ -174,20 +175,20 @@ def proc_ecpairing(ext, msg):
174175
if p1 is False:
175176
return 0, 0, []
176177
for v in (x2_i, x2_r, y2_i, y2_r):
177-
if v >= py_pairing.field_modulus:
178+
if v >= bn128.field_modulus:
178179
return 0, 0, []
179-
fq2_x = py_pairing.FQ2([x2_r, x2_i])
180-
fq2_y = py_pairing.FQ2([y2_r, y2_i])
181-
if (fq2_x, fq2_y) != (py_pairing.FQ2.zero(), py_pairing.FQ2.zero()):
182-
p2 = (fq2_x, fq2_y, py_pairing.FQ2.one())
183-
if not py_pairing.is_on_curve(p2, py_pairing.b2):
180+
fq2_x = bn128.FQ2([x2_r, x2_i])
181+
fq2_y = bn128.FQ2([y2_r, y2_i])
182+
if (fq2_x, fq2_y) != (bn128.FQ2.zero(), bn128.FQ2.zero()):
183+
p2 = (fq2_x, fq2_y, bn128.FQ2.one())
184+
if not bn128.is_on_curve(p2, bn128.b2):
184185
return 0, 0, []
185186
else:
186187
p2 = zero
187-
if py_pairing.multiply(p2, py_pairing.curve_order)[-1] != py_pairing.FQ2.zero():
188+
if bn128.multiply(p2, bn128.curve_order)[-1] != bn128.FQ2.zero():
188189
return 0, 0, []
189190
exponent *= py_pairing.pairing(p2, p1, final_exponentiate=False)
190-
result = py_pairing.final_exponentiate(exponent) == py_pairing.FQ12.one()
191+
result = bn128.final_exponentiate(exponent) == bn128.FQ12.one()
191192
return 1, msg.gas - gascost, [0] * 31 + [1 if result else 0]
192193

193194
specials = {

ethereum/state.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ def code(self, value):
9191
# thing that fails to get garbage collected is when code disappears due
9292
# to a suicide
9393
self.env.db.put(self.code_hash, value)
94-
# self.env.db.inc_refcount(self.code_hash, value)
9594

9695
def get_storage_data(self, key):
9796
if key not in self.storage_cache:
@@ -115,7 +114,7 @@ def is_blank(self):
115114
@property
116115
def exists(self):
117116
if self.is_blank():
118-
return self.existent_at_start and not self.touched
117+
return self.touched or (self.existent_at_start and not self.deleted)
119118
return True
120119

121120
def to_dict(self):
@@ -296,10 +295,12 @@ def account_exists(self, address):
296295
o = not self.get_and_cache_account(utils.normalize_address(address)).is_blank()
297296
else:
298297
a = self.get_and_cache_account(address)
298+
if a.deleted and not a.touched:
299+
return False
299300
if a.touched:
300-
o = not a.deleted
301+
return True
301302
else:
302-
o = a.existent_at_start
303+
return a.existent_at_start
303304
return o
304305

305306
def transfer_value(self, from_addr, to_addr, value):
@@ -315,15 +316,16 @@ def account_to_dict(self, address):
315316

316317
def commit(self, allow_empties=False):
317318
for addr, acct in self.cache.items():
318-
if acct.touched:
319+
if acct.touched or acct.deleted:
319320
acct.commit()
320321
self.deletes.extend(acct.storage_trie.deletes)
321-
if acct.exists or allow_empties or (not self.is_SPURIOUS_DRAGON() and not acct.deleted):
322-
# print('upd', encode_hex(addr))
322+
if self.account_exists(addr) or allow_empties:
323323
self.trie.update(addr, rlp.encode(acct))
324+
#self.db.update(b'acct:'+addr, rlp.encode(acct))
324325
else:
325-
# print('del', encode_hex(addr))
326326
self.trie.delete(addr)
327+
# self.db.update(b'acct:'+addr, rlp.encode(acct))
328+
# self.trie.db.
327329
self.deletes.extend(self.trie.deletes)
328330
self.trie.deletes = []
329331
self.cache = {}
@@ -340,6 +342,8 @@ def del_account(self, address):
340342
self.set_code(address, b'')
341343
self.reset_storage(address)
342344
self.set_and_journal(self.get_and_cache_account(utils.normalize_address(address)), 'deleted', True)
345+
self.set_and_journal(self.get_and_cache_account(utils.normalize_address(address)), 'touched', False)
346+
# self.set_and_journal(self.get_and_cache_account(utils.normalize_address(address)), 'existent_at_start', False)
343347

344348
def reset_storage(self, address):
345349
acct = self.get_and_cache_account(address)
@@ -434,7 +438,7 @@ def ephemeral_clone(self):
434438
s.recent_uncles = self.recent_uncles
435439
s.prev_headers = self.prev_headers
436440
for acct in self.cache.values():
437-
assert not acct.touched
441+
assert not acct.touched or not acct.deleted
438442
s.journal = copy.copy(self.journal)
439443
s.cache = {}
440444
return s

ethereum/todo_tests/tst_frontier.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
import time
1313
import random
1414

15-
# from ethereum.slogging import LogRecorder, configure_logging, set_level
16-
# config_string = ':info,eth.vm.log:trace,eth.vm.op:trace,eth.vm.stack:trace,eth.vm.exit:trace,eth.pb.msg:trace,eth.pb.tx:debug'
15+
from ethereum.slogging import LogRecorder, configure_logging, set_level
16+
config_string = ':info,eth.vm.log:trace,eth.vm.op:trace,eth.vm.stack:trace,eth.vm.exit:trace,eth.pb.msg:trace,eth.pb.tx:debug'
1717
# configure_logging(config_string=config_string)
1818

1919
messages.SKIP_MEDSTATES = True
@@ -121,14 +121,19 @@ def snapshot(c, num_blocks):
121121
# don't check pow
122122
BlockHeader.check_pow = lambda *args: True
123123

124+
#print(block_rlps[116525].encode('hex'))
125+
#sys.exit()
126+
124127
# process blocks
125128
st = time.time()
126129
num_blks = 0
127130
num_txs = 0
128131
gas_used = 0
129-
for block in block_rlps[1:50000]:
132+
for i, block in list(enumerate(block_rlps))[1:250000]:
130133
# print 'prevh:', s.prev_headers
131134
block = rlp.decode(block, Block)
135+
#if i == 116525:
136+
# configure_logging(config_string=config_string)
132137
assert c.add_block(block)
133138
num_blks += 1
134139
num_txs += len(block.transactions)

ethereum/tools/new_statetest_utils.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from ethereum.block import FakeHeader, Block
33
from ethereum.utils import decode_hex, parse_int_or_hex, sha3, to_string, \
44
remove_0x_head, encode_hex, big_endian_to_int
5-
from ethereum.config import default_config, config_homestead, config_tangerine, config_spurious, config_metropolis, Env
5+
from ethereum.config import default_config, config_frontier, config_homestead, config_tangerine, config_spurious, config_metropolis, Env
66
from ethereum.exceptions import InvalidTransaction
77
import ethereum.transactions as transactions
88
from ethereum.messages import apply_transaction
@@ -37,8 +37,9 @@ def mk_fake_header(blknum):
3737

3838

3939
configs = {
40-
#"Homestead": config_homestead,
41-
#"EIP150": config_tangerine,
40+
"Frontier": config_frontier,
41+
"Homestead": config_homestead,
42+
"EIP150": config_tangerine,
4243
"EIP158": config_spurious,
4344
#"Metropolis": config_metropolis
4445
}

ethereum/transactions.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# -*- coding: utf-8 -*-
22
import rlp
3-
from bitcoin import encode_pubkey, N, encode_privkey
43
from rlp.sedes import big_endian_int, binary
54
from rlp.utils import str_to_bytes, ascii_chr
65
from ethereum.utils import encode_hex
@@ -82,7 +81,7 @@ def sender(self):
8281
sighash = utils.sha3(rlpdata)
8382
else:
8483
raise InvalidTransaction("Invalid V value")
85-
if self.r >= N or self.s >= N or self.r == 0 or self.s == 0:
84+
if self.r >= secpk1n or self.s >= secpk1n or self.r == 0 or self.s == 0:
8685
raise InvalidTransaction("Invalid signature values!")
8786
pub = ecrecover_to_pub(sighash, vee, self.r, self.s)
8887
if pub == b"\x00" * 64:
@@ -172,11 +171,11 @@ def __structlog__(self):
172171
# The >= operator is replaced by > because the integer division N/2 always produces the value
173172
# which is by 0.5 less than the real N/2
174173
def check_low_s_metropolis(self):
175-
if self.s > N // 2:
174+
if self.s > secpk1n // 2:
176175
raise InvalidTransaction("Invalid signature S value!")
177176

178177
def check_low_s_homestead(self):
179-
if self.s > N // 2 or self.s == 0:
178+
if self.s > secpk1n // 2 or self.s == 0:
180179
raise InvalidTransaction("Invalid signature S value!")
181180

182181

ethereum/utils.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
except ImportError:
55
import sha3 as _sha3
66
sha3_256 = lambda x: _sha3.keccak_256(x).digest()
7-
from bitcoin import privtopub, ecdsa_raw_sign, ecdsa_raw_recover, encode_pubkey
7+
from py_ecc.secp256k1 import privtopub, ecdsa_raw_sign, ecdsa_raw_recover
88
import sys
99
import rlp
1010
from rlp.sedes import big_endian_int, BigEndianInt, Binary
@@ -104,8 +104,8 @@ def ecrecover_to_pub(rawhash, v, r, s):
104104
except:
105105
pub = b"\x00" * 64
106106
else:
107-
recovered_addr = ecdsa_raw_recover(rawhash, (v, r, s))
108-
pub = encode_pubkey(recovered_addr, 'bin_electrum')
107+
x, y = ecdsa_raw_recover(rawhash, (v, r, s))
108+
pub = encode_int32(x) + encode_int32(y)
109109
assert len(pub) == 64
110110
return pub
111111

@@ -184,10 +184,10 @@ def sha3(seed):
184184
assert encode_hex(sha3(b'')) == 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
185185

186186

187-
def privtoaddr(x):
188-
if len(x) > 32:
189-
x = decode_hex(x)
190-
return sha3(privtopub(x)[1:])[12:]
187+
def privtoaddr(k):
188+
k = normalize_key(k)
189+
x, y = privtopub(k)
190+
return sha3(encode_int32(x) + encode_int32(y))[12:]
191191

192192

193193
def checksum_encode(addr): # Takes a 20-byte binary address as input

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
bitcoin
21
pysha3>=1.0.1
32
PyYAML
43
repoze.lru
54
pbkdf2
6-
pycryptodome>=3.3.1
75
scrypt
6+
py_ecc
87
rlp>=0.4.7
98
https://github.com/ethereum/ethash/tarball/master

0 commit comments

Comments
 (0)