17
17
package miner
18
18
19
19
import (
20
+ "context"
20
21
"fmt"
21
22
"math"
22
23
"math/big"
@@ -33,6 +34,8 @@ import (
33
34
"github.com/scroll-tech/go-ethereum/consensus"
34
35
"github.com/scroll-tech/go-ethereum/consensus/clique"
35
36
"github.com/scroll-tech/go-ethereum/consensus/ethash"
37
+ "github.com/scroll-tech/go-ethereum/consensus/system_contract"
38
+ "github.com/scroll-tech/go-ethereum/consensus/wrapper"
36
39
"github.com/scroll-tech/go-ethereum/core"
37
40
"github.com/scroll-tech/go-ethereum/core/rawdb"
38
41
"github.com/scroll-tech/go-ethereum/core/types"
77
80
MaxAccountsNum : math .MaxInt ,
78
81
CCCMaxWorkers : 2 ,
79
82
}
83
+
84
+ testConfigAllowEmpty = & Config {
85
+ Recommit : time .Second ,
86
+ GasCeil : params .GenesisGasLimit ,
87
+ MaxAccountsNum : math .MaxInt ,
88
+ CCCMaxWorkers : 2 ,
89
+ AllowEmpty : true ,
90
+ }
80
91
)
81
92
82
93
func init () {
@@ -138,6 +149,15 @@ func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine
138
149
e .Authorize (testBankAddress , func (account accounts.Account , s string , data []byte ) ([]byte , error ) {
139
150
return crypto .Sign (crypto .Keccak256 (data ), testBankKey )
140
151
})
152
+ case * wrapper.UpgradableEngine :
153
+ gspec .ExtraData = make ([]byte , 32 + common .AddressLength + crypto .SignatureLength )
154
+ gspec .Timestamp = uint64 (time .Now ().Unix ())
155
+ copy (gspec .ExtraData [32 :32 + common .AddressLength ], testBankAddress .Bytes ())
156
+ e .Authorize (testBankAddress , func (account accounts.Account , s string , data []byte ) ([]byte , error ) {
157
+ return crypto .Sign (crypto .Keccak256 (data ), testBankKey )
158
+ }, func (account accounts.Account , s string , data []byte ) ([]byte , error ) {
159
+ return crypto .Sign (crypto .Keccak256 (data ), testBankKey )
160
+ })
141
161
case * ethash.Ethash :
142
162
default :
143
163
t .Fatalf ("unexpected consensus engine type: %T" , engine )
@@ -207,14 +227,26 @@ func (b *testWorkerBackend) newRandomTx(creation bool) *types.Transaction {
207
227
return tx
208
228
}
209
229
210
- func newTestWorker (t * testing.T , chainConfig * params.ChainConfig , engine consensus.Engine , db ethdb.Database , blocks int ) (* worker , * testWorkerBackend ) {
230
+ func testWorker (t * testing.T , chainConfig * params.ChainConfig , engine consensus.Engine , db ethdb.Database , blocks int , allowEmpty bool ) (* worker , * testWorkerBackend ) {
211
231
backend := newTestWorkerBackend (t , chainConfig , engine , db , blocks )
212
232
backend .txPool .AddLocals (pendingTxs )
213
- w := newWorker (testConfig , chainConfig , engine , backend , new (event.TypeMux ), nil , false , false )
233
+ config := testConfig
234
+ if allowEmpty {
235
+ config = testConfigAllowEmpty
236
+ }
237
+ w := newWorker (config , chainConfig , engine , backend , new (event.TypeMux ), nil , false , false )
214
238
w .setEtherbase (testBankAddress )
215
239
return w , backend
216
240
}
217
241
242
+ func newTestWorker (t * testing.T , chainConfig * params.ChainConfig , engine consensus.Engine , db ethdb.Database , blocks int ) (* worker , * testWorkerBackend ) {
243
+ return testWorker (t , chainConfig , engine , db , blocks , false )
244
+ }
245
+
246
+ func newTestWorkerWithEmptyBlock (t * testing.T , chainConfig * params.ChainConfig , engine consensus.Engine , db ethdb.Database , blocks int ) (* worker , * testWorkerBackend ) {
247
+ return testWorker (t , chainConfig , engine , db , blocks , true )
248
+ }
249
+
218
250
func TestGenerateBlockAndImportClique (t * testing.T ) {
219
251
testGenerateBlockAndImport (t , true )
220
252
}
@@ -1355,3 +1387,83 @@ func TestEuclidV2HardForkMessageQueue(t *testing.T) {
1355
1387
}
1356
1388
}
1357
1389
}
1390
+
1391
+ // TestEuclidV2TransitionVerification tests that the upgradable consensus engine
1392
+ // can successfully verify the EuclidV2 transition chain.
1393
+ func TestEuclidV2TransitionVerification (t * testing.T ) {
1394
+ // patch time.Now() to be able to simulate hard fork time
1395
+ patches := gomonkey .NewPatches ()
1396
+ defer patches .Reset ()
1397
+ var timeCount int64
1398
+ patches .ApplyFunc (time .Now , func () time.Time {
1399
+ timeCount ++
1400
+ return time .Unix (timeCount , 0 )
1401
+ })
1402
+
1403
+ // init chain config
1404
+ chainConfig := params .AllCliqueProtocolChanges .Clone ()
1405
+ chainConfig .EuclidTime = newUint64 (0 )
1406
+ chainConfig .EuclidV2Time = newUint64 (10000 )
1407
+ chainConfig .Clique = & params.CliqueConfig {Period : 1 , Epoch : 30000 }
1408
+ chainConfig .SystemContract = & params.SystemContractConfig {Period : 1 }
1409
+
1410
+ // init worker
1411
+ db := rawdb .NewMemoryDatabase ()
1412
+ cliqueEngine := clique .New (chainConfig .Clique , db )
1413
+ sysEngine := system_contract .New (context .Background (), chainConfig .SystemContract , & system_contract.FakeEthClient {Value : testBankAddress })
1414
+ engine := wrapper .NewUpgradableEngine (chainConfig .IsEuclidV2 , cliqueEngine , sysEngine )
1415
+ w , b := newTestWorkerWithEmptyBlock (t , chainConfig , engine , db , 0 )
1416
+ defer w .close ()
1417
+ b .genesis .MustCommit (db )
1418
+
1419
+ // collect mined blocks
1420
+ sub := w .mux .Subscribe (core.NewMinedBlockEvent {})
1421
+ defer sub .Unsubscribe ()
1422
+ w .start ()
1423
+
1424
+ blocks := []* types.Block {}
1425
+ headers := []* types.Header {}
1426
+
1427
+ for i := 0 ; i < 6 ; i ++ {
1428
+ select {
1429
+ case ev := <- sub .Chan ():
1430
+ // activate EuclidV2 at next block
1431
+ if i == 2 {
1432
+ timeCount = int64 (* chainConfig .EuclidV2Time )
1433
+ }
1434
+
1435
+ block := ev .Data .(core.NewMinedBlockEvent ).Block
1436
+ blocks = append (blocks , block )
1437
+ headers = append (headers , block .Header ())
1438
+
1439
+ case <- time .After (3 * time .Second ):
1440
+ t .Fatalf ("timeout" )
1441
+ }
1442
+ }
1443
+
1444
+ // sanity check: we generated the EuclidV2 transition block
1445
+ assert .False (t , chainConfig .IsEuclidV2 (headers [0 ].Time ))
1446
+ assert .True (t , chainConfig .IsEuclidV2 (headers [len (headers )- 1 ].Time ))
1447
+
1448
+ // import headers into new chain
1449
+ chainDb := rawdb .NewMemoryDatabase ()
1450
+ b .genesis .MustCommit (chainDb )
1451
+ chain , err := core .NewBlockChain (chainDb , nil , b .chain .Config (), engine , vm.Config {}, nil , nil )
1452
+ assert .NoError (t , err )
1453
+ defer chain .Stop ()
1454
+
1455
+ // previously this would fail with `unknown ancestor`
1456
+ _ , err = chain .InsertHeaderChain (headers , 0 )
1457
+ assert .NoError (t , err )
1458
+
1459
+ // import headers into new chain
1460
+ chainDb = rawdb .NewMemoryDatabase ()
1461
+ b .genesis .MustCommit (chainDb )
1462
+ chain , err = core .NewBlockChain (chainDb , nil , b .chain .Config (), engine , vm.Config {}, nil , nil )
1463
+ assert .NoError (t , err )
1464
+ defer chain .Stop ()
1465
+
1466
+ // previously this would fail with `unknown ancestor`
1467
+ _ , err = chain .InsertChain (blocks )
1468
+ assert .NoError (t , err )
1469
+ }
0 commit comments