@@ -47,61 +47,6 @@ def nibbles_to_bin(nibbles):
47
47
48
48
49
49
NIBBLE_TERMINATOR = 16
50
- RECORDING = 1
51
- NONE = 0
52
- VERIFYING = - 1
53
-
54
- proving = False
55
-
56
-
57
- class ProofConstructor ():
58
-
59
- def __init__ (self ):
60
- self .mode = []
61
- self .nodes = []
62
- self .exempt = []
63
-
64
- def push (self , mode , nodes = []):
65
- global proving
66
- proving = True
67
- self .mode .append (mode )
68
- self .exempt .append (set ())
69
- if mode == VERIFYING :
70
- self .nodes .append (set ([rlp_encode (x ) for x in nodes ]))
71
- else :
72
- self .nodes .append (set ())
73
-
74
- def pop (self ):
75
- global proving
76
- self .mode .pop ()
77
- self .nodes .pop ()
78
- self .exempt .pop ()
79
- if not self .mode :
80
- proving = False
81
-
82
- def get_nodelist (self ):
83
- return list (map (rlp .decode , list (self .nodes [- 1 ])))
84
-
85
- def get_nodes (self ):
86
- return self .nodes [- 1 ]
87
-
88
- def add_node (self , node ):
89
- node = rlp_encode (node )
90
- if node not in self .exempt [- 1 ]:
91
- self .nodes [- 1 ].add (node )
92
-
93
- def add_exempt (self , node ):
94
- self .exempt [- 1 ].add (rlp_encode (node ))
95
-
96
- def get_mode (self ):
97
- return self .mode [- 1 ]
98
-
99
- proof = ProofConstructor ()
100
-
101
-
102
- class InvalidSPVProof (Exception ):
103
- pass
104
-
105
50
106
51
def with_terminator (nibbles ):
107
52
nibbles = nibbles [:]
@@ -190,22 +135,16 @@ def is_key_value_type(node_type):
190
135
BLANK_ROOT = utils .sha3rlp (b'' )
191
136
192
137
193
- def transient_trie_exception (* args ):
194
- raise Exception ("Transient trie" )
195
-
196
138
197
139
class Trie (object ):
198
140
199
- def __init__ (self , db , root_hash = BLANK_ROOT , transient = False ):
141
+ def __init__ (self , db , root_hash = BLANK_ROOT ):
200
142
'''it also present a dictionary like interface
201
143
202
144
:param db key value database
203
145
:root: blank or trie node in form of [key, value] or [v0,v1..v15,v]
204
146
'''
205
147
self .db = db # Pass in a database object directly
206
- self .transient = transient
207
- if self .transient :
208
- self .update = self .get = self .delete = transient_trie_exception
209
148
self .set_root_hash (root_hash )
210
149
211
150
# def __init__(self, dbfile, root_hash=BLANK_ROOT):
@@ -221,45 +160,20 @@ def __init__(self, db, root_hash=BLANK_ROOT, transient=False):
221
160
# self.db = dbfile # Pass in a database object directly
222
161
# self.set_root_hash(root_hash)
223
162
224
- # For SPV proof production/verification purposes
225
- def spv_grabbing (self , node ):
226
- global proving
227
- if not proving :
228
- pass
229
- elif proof .get_mode () == RECORDING :
230
- proof .add_node (copy .copy (node ))
231
- # print('recording %s' % encode_hex(utils.sha3(rlp_encode(node))))
232
- elif proof .get_mode () == VERIFYING :
233
- # print('verifying %s' % encode_hex(utils.sha3(rlp_encode(node))))
234
- if rlp_encode (node ) not in proof .get_nodes ():
235
- raise InvalidSPVProof ("Proof invalid!" )
236
-
237
- def spv_storing (self , node ):
238
- global proving
239
- if not proving :
240
- pass
241
- elif proof .get_mode () == RECORDING :
242
- proof .add_exempt (copy .copy (node ))
243
- elif proof .get_mode () == VERIFYING :
244
- proof .add_node (copy .copy (node ))
245
-
246
163
@property
247
164
def root_hash (self ):
248
165
'''always empty or a 32 bytes string
249
166
'''
250
- return self .get_root_hash ()
167
+ return self ._root_hash
251
168
252
169
def get_root_hash (self ):
253
- if self .transient :
254
- return self .transient_root_hash
255
- if self .root_node == BLANK_NODE :
256
- return BLANK_ROOT
257
- assert isinstance (self .root_node , list )
170
+ return self ._root_hash
171
+
172
+ def _update_root_hash (self ):
258
173
val = rlp_encode (self .root_node )
259
174
key = utils .sha3 (val )
260
175
self .db .put (key , val )
261
- self .spv_grabbing (self .root_node )
262
- return key
176
+ self ._root_hash = key
263
177
264
178
@root_hash .setter
265
179
def root_hash (self , value ):
@@ -268,20 +182,20 @@ def root_hash(self, value):
268
182
def set_root_hash (self , root_hash ):
269
183
assert is_string (root_hash )
270
184
assert len (root_hash ) in [0 , 32 ]
271
- if self .transient :
272
- self .transient_root_hash = root_hash
273
- return
274
185
if root_hash == BLANK_ROOT :
275
186
self .root_node = BLANK_NODE
187
+ self ._root_hash = BLANK_ROOT
276
188
return
277
189
self .root_node = self ._decode_to_node (root_hash )
190
+ self ._root_hash = root_hash
278
191
279
192
def clear (self ):
280
193
''' clear all tree data
281
194
'''
282
195
self ._delete_child_storage (self .root_node )
283
196
self ._delete_node_storage (self .root_node )
284
197
self .root_node = BLANK_NODE
198
+ self ._root_hash = BLANK_ROOT
285
199
286
200
def _delete_child_storage (self , node ):
287
201
node_type = self ._get_node_type (node )
@@ -294,23 +208,21 @@ def _delete_child_storage(self, node):
294
208
def _encode_node (self , node ):
295
209
if node == BLANK_NODE :
296
210
return BLANK_NODE
297
- assert isinstance (node , list )
211
+ # assert isinstance(node, list)
298
212
rlpnode = rlp_encode (node )
299
213
if len (rlpnode ) < 32 :
300
214
return node
301
215
302
216
hashkey = utils .sha3 (rlpnode )
303
217
self .db .put (hashkey , rlpnode )
304
- self .spv_storing (node )
305
218
return hashkey
306
219
307
220
def _decode_to_node (self , encoded ):
308
221
if encoded == BLANK_NODE :
309
222
return BLANK_NODE
310
- if isinstance (encoded , list ):
223
+ # if isinstance(encoded, list):
311
224
return encoded
312
225
o = rlp .decode (self .db .get (encoded ))
313
- self .spv_grabbing (o )
314
226
return o
315
227
316
228
def _get_node_type (self , node ):
@@ -552,8 +464,8 @@ def split(self, key):
552
464
return t1 , t2
553
465
554
466
def _merge (self , node1 , node2 ):
555
- assert isinstance (node1 , list ) or not node1
556
- assert isinstance (node2 , list ) or not node2
467
+ # assert isinstance(node1, list) or not node1
468
+ # assert isinstance(node2, list) or not node2
557
469
node_type1 = self ._get_node_type (node1 )
558
470
node_type2 = self ._get_node_type (node2 )
559
471
if not node1 :
@@ -684,7 +596,7 @@ def _delete_node_storage(self, node):
684
596
'''
685
597
if node == BLANK_NODE :
686
598
return
687
- assert isinstance (node , list )
599
+ # assert isinstance(node, list)
688
600
encoded = self ._encode_node (node )
689
601
if len (encoded ) < 32 :
690
602
return
@@ -798,7 +710,7 @@ def _delete_kv_node(self, node, key):
798
710
if new_sub_node == BLANK_NODE :
799
711
return BLANK_NODE
800
712
801
- assert isinstance (new_sub_node , list )
713
+ # assert isinstance(new_sub_node, list)
802
714
803
715
# new sub node not blank, not value and has changed
804
716
new_sub_node_type = self ._get_node_type (new_sub_node )
@@ -828,7 +740,7 @@ def delete(self, key):
828
740
self .root_node = self ._delete_and_delete_storage (
829
741
self .root_node ,
830
742
bin_to_nibbles (to_string (key )))
831
- self .get_root_hash ()
743
+ self ._update_root_hash ()
832
744
833
745
def _get_size (self , node ):
834
746
'''Get counts of (key, value) stored in this and the descendant nodes
@@ -991,39 +903,13 @@ def update(self, key, value):
991
903
self .root_node ,
992
904
bin_to_nibbles (to_string (key )),
993
905
to_string (value ))
994
- self .get_root_hash ()
906
+ self ._update_root_hash ()
995
907
996
908
def root_hash_valid (self ):
997
909
if self .root_hash == BLANK_ROOT :
998
910
return True
999
911
return self .root_hash in self .db
1000
912
1001
- def produce_spv_proof (self , key ):
1002
- proof .push (RECORDING )
1003
- self .get (key )
1004
- o = proof .get_nodelist ()
1005
- proof .pop ()
1006
- return o
1007
-
1008
-
1009
- def verify_spv_proof (root , key , proof ):
1010
- proof .push (VERIFYING , proof )
1011
- t = Trie (db .EphemDB ())
1012
-
1013
- for i , node in enumerate (proof ):
1014
- R = rlp_encode (node )
1015
- H = utils .sha3 (R )
1016
- t .db .put (H , R )
1017
- try :
1018
- t .root_hash = root
1019
- t .get (key )
1020
- proof .pop ()
1021
- return True
1022
- except Exception as e :
1023
- print (e )
1024
- proof .pop ()
1025
- return False
1026
-
1027
913
1028
914
if __name__ == "__main__" :
1029
915
import sys
0 commit comments