2
2
import rlp
3
3
4
4
from eth_utils import decode_hex
5
+ from eth_utils .toolz import sliding_window
5
6
6
7
from eth import constants
7
8
from eth .abc import MiningChainAPI
8
- from eth .chains .mainnet import MAINNET_GENESIS_HEADER
9
+ from eth .chains .base import MiningChain
10
+ from eth .chains .mainnet import (
11
+ MAINNET_GENESIS_HEADER ,
12
+ MAINNET_VMS ,
13
+ )
9
14
from eth .chains .ropsten import ROPSTEN_GENESIS_HEADER
15
+ from eth .consensus .noproof import NoProofConsensus
10
16
from eth .exceptions import (
11
17
TransactionNotFound ,
12
18
)
@@ -25,6 +31,30 @@ def chain(chain_without_block_validation):
25
31
return chain_without_block_validation
26
32
27
33
34
+ VM_PAIRS = sliding_window (2 , MAINNET_VMS )
35
+
36
+
37
+ @pytest .fixture (params = VM_PAIRS )
38
+ def vm_crossover_chain (request , base_db , genesis_state ):
39
+ start_vm , end_vm = request .param
40
+ klass = MiningChain .configure (
41
+ __name__ = 'CrossoverTestChain' ,
42
+ vm_configuration = (
43
+ (
44
+ constants .GENESIS_BLOCK_NUMBER ,
45
+ start_vm .configure (consensus_class = NoProofConsensus ),
46
+ ),
47
+ # Can mine one block of the first VM, then the next block with be the next VM
48
+ (
49
+ constants .GENESIS_BLOCK_NUMBER + 2 ,
50
+ end_vm .configure (consensus_class = NoProofConsensus ),
51
+ ),
52
+ ),
53
+ chain_id = 1337 ,
54
+ )
55
+ return klass .from_genesis (base_db , dict (difficulty = 1 ), genesis_state )
56
+
57
+
28
58
@pytest .fixture
29
59
def valid_chain (chain_with_block_validation ):
30
60
return chain_with_block_validation
@@ -200,3 +230,37 @@ def test_get_transaction_receipt(chain, tx):
200
230
assert chain .get_canonical_transaction_index (tx .hash ) == (1 , 0 )
201
231
assert chain .get_transaction_receipt_by_index (1 , 0 ) == expected_receipt
202
232
assert chain .get_transaction_receipt (tx .hash ) == expected_receipt
233
+
234
+
235
+ def _mine_result_to_header (mine_all_result ):
236
+ block_import_result , _ , _ = mine_all_result
237
+ return block_import_result .imported_block .header
238
+
239
+
240
+ def test_uncles_across_VMs (vm_crossover_chain ):
241
+ chain = vm_crossover_chain
242
+
243
+ genesis = chain .get_canonical_block_header_by_number (0 )
244
+
245
+ # Mine in 1st VM
246
+ uncle_header1 = chain .mine_block (extra_data = b'uncle1' ).header
247
+ canon_header1 = _mine_result_to_header (
248
+ chain .mine_all ([], parent_header = genesis )
249
+ )
250
+
251
+ # Mine in 2nd VM
252
+ uncle_header2 = chain .mine_block (extra_data = b'uncle2' ).header
253
+ canon_header2 = _mine_result_to_header (
254
+ chain .mine_all ([], parent_header = canon_header1 )
255
+ )
256
+
257
+ # Mine block with uncles from both VMs
258
+ canon_block3 = chain .mine_block (uncles = [uncle_header1 , uncle_header2 ])
259
+
260
+ assert canon_header2 .hash == canon_block3 .header .parent_hash
261
+
262
+ assert canon_block3 .uncles == (uncle_header1 , uncle_header2 )
263
+
264
+ deserialized_block3 = chain .get_canonical_block_by_number (3 )
265
+
266
+ assert deserialized_block3 .uncles == (uncle_header1 , uncle_header2 )
0 commit comments