@@ -146,31 +146,58 @@ def _update_head(self, block):
146
146
head_hash = block , old_head_hash = self .head )
147
147
self .blockchain .put ('HEAD' , block .hash )
148
148
self .index .update_blocknumbers (self .head )
149
+ self ._update_head_candidate ()
150
+ if self .new_head_cb and not block .is_genesis ():
151
+ self .new_head_cb (block )
152
+
153
+ def _update_head_candidate (self ):
154
+ "after new head is set"
149
155
150
- # update head candidate
151
- transactions = self .get_transactions ()
152
- blk = self .head
153
- uncles = set (u .header for u in self .get_brothers (self .head ))
154
- for i in range (8 ):
155
- for u in blk .uncles : # assuming uncle headers
156
- u = utils .sha3 (rlp .encode (u ))
157
- if u in self :
158
- uncles .discard (self .get (u ))
156
+ # collect uncles
157
+ blk = self .head # parent of the block we are collecting uncles for
158
+ uncles = set (u .header for u in self .get_brothers (blk ))
159
+ for i in range (blocks .MAX_UNCLE_DEPTH + 2 ):
160
+ for u in blk .uncles :
161
+ assert isinstance (u , blocks .BlockHeader )
162
+ uncles .discard (u )
159
163
if blk .has_parent ():
160
164
blk = blk .get_parent ()
165
+ assert not uncles or max (u .number for u in uncles ) <= self .head .number
166
+ uncles = list (uncles )[:blocks .MAX_UNCLES ]
167
+
168
+ # create block
169
+ ts = max (int (time .time ()), self .head .timestamp + 1 )
170
+ head_candidate = blocks .Block .init_from_parent (self .head , coinbase = self ._coinbase ,
171
+ timestamp = ts , uncles = uncles )
172
+ assert head_candidate .validate_uncles ()
173
+
174
+ self .pre_finalize_state_root = head_candidate .state_root
175
+ head_candidate .finalize ()
161
176
162
- uncles = list (uncles )
163
- ts = max (int (time .time ()), block .timestamp + 1 )
164
- self .head_candidate = blocks .Block .init_from_parent (block , coinbase = self ._coinbase ,
165
- timestamp = ts , uncles = uncles )
166
- self .pre_finalize_state_root = self .head_candidate .state_root
167
- self .head_candidate .finalize ()
168
177
# add transactions from previous head candidate
169
- for tx in transactions :
170
- self .add_transaction (tx )
178
+ old_head_candidate = self .head_candidate
179
+ self .head_candidate = head_candidate
180
+ if old_head_candidate is not None :
181
+ for tx in old_head_candidate .get_transactions ():
182
+ self .add_transaction (tx )
171
183
172
- if self .new_head_cb and not block .is_genesis ():
173
- self .new_head_cb (block )
184
+ def get_uncles (self , block ):
185
+ """Return the uncles of `block`."""
186
+ if not block .has_parent ():
187
+ return []
188
+ else :
189
+ return self .get_brothers (block .get_parent ())
190
+
191
+ def get_brothers (self , block ):
192
+ """Return the uncles of the hypothetical child of `block`."""
193
+ o = []
194
+ i = 0
195
+ while block .has_parent () and i < blocks .MAX_UNCLE_DEPTH :
196
+ parent = block .get_parent ()
197
+ o .extend ([u for u in self .get_children (parent ) if u != block ])
198
+ block = block .get_parent ()
199
+ i += 1
200
+ return o
174
201
175
202
def get (self , blockhash ):
176
203
assert is_string (blockhash )
@@ -199,7 +226,7 @@ def add_block(self, block, forward=False):
199
226
_log .debug ('missing parent' )
200
227
return False
201
228
202
- if not block .validate_uncles (self . db ):
229
+ if not block .validate_uncles ():
203
230
_log .debug ('invalid uncles' )
204
231
return False
205
232
@@ -243,24 +270,6 @@ def add_block(self, block, forward=False):
243
270
def get_children (self , block ):
244
271
return [self .get (c ) for c in self .index .get_children (block .hash )]
245
272
246
- def get_brothers (self , block ):
247
- """Return the uncles of the hypothetical child of `block`."""
248
- o = []
249
- i = 0
250
- while block .has_parent () and i < 6 :
251
- parent = block .get_parent ()
252
- o .extend ([u for u in self .get_children (parent ) if u != block ])
253
- block = parent
254
- i += 1
255
- return o
256
-
257
- def get_uncles (self , block ):
258
- """Return the uncles of `block`."""
259
- if not block .has_parent ():
260
- return []
261
- else :
262
- return self .get_brothers (block .get_parent ())
263
-
264
273
def add_transaction (self , transaction ):
265
274
"""Add a transaction to the :attr:`head_candidate` block.
266
275
0 commit comments