github.com/iotexproject/iotex-core@v1.14.1-rc1/e2etest/local_test.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package e2etest 7 8 import ( 9 "context" 10 "math/big" 11 "strings" 12 "testing" 13 "time" 14 15 "github.com/libp2p/go-libp2p-core/peer" 16 "github.com/multiformats/go-multiaddr" 17 "github.com/stretchr/testify/require" 18 "google.golang.org/protobuf/proto" 19 20 "github.com/iotexproject/go-pkgs/crypto" 21 "github.com/iotexproject/go-pkgs/hash" 22 23 "github.com/iotexproject/iotex-core/action" 24 "github.com/iotexproject/iotex-core/action/protocol" 25 "github.com/iotexproject/iotex-core/action/protocol/account" 26 accountutil "github.com/iotexproject/iotex-core/action/protocol/account/util" 27 "github.com/iotexproject/iotex-core/action/protocol/rewarding" 28 "github.com/iotexproject/iotex-core/action/protocol/rolldpos" 29 "github.com/iotexproject/iotex-core/actpool" 30 "github.com/iotexproject/iotex-core/blockchain" 31 "github.com/iotexproject/iotex-core/blockchain/block" 32 "github.com/iotexproject/iotex-core/blockchain/blockdao" 33 "github.com/iotexproject/iotex-core/blockchain/filedao" 34 "github.com/iotexproject/iotex-core/blockchain/genesis" 35 "github.com/iotexproject/iotex-core/config" 36 "github.com/iotexproject/iotex-core/db" 37 "github.com/iotexproject/iotex-core/p2p" 38 "github.com/iotexproject/iotex-core/pkg/unit" 39 "github.com/iotexproject/iotex-core/server/itx" 40 "github.com/iotexproject/iotex-core/state/factory" 41 "github.com/iotexproject/iotex-core/test/identityset" 42 "github.com/iotexproject/iotex-core/testutil" 43 ) 44 45 const ( 46 _dBPath = "db.test" 47 _dBPath2 = "db.test2" 48 _triePath = "trie.test" 49 _triePath2 = "trie.test2" 50 _disabledIP = "169.254." 51 ) 52 53 func TestLocalCommit(t *testing.T) { 54 require := require.New(t) 55 56 cfg, err := newTestConfig() 57 require.NoError(err) 58 testTriePath, err := testutil.PathOfTempFile(_triePath) 59 require.NoError(err) 60 testDBPath, err := testutil.PathOfTempFile(_dBPath) 61 require.NoError(err) 62 indexDBPath, err := testutil.PathOfTempFile(_dBPath) 63 require.NoError(err) 64 contractIndexDBPath, err := testutil.PathOfTempFile(_dBPath) 65 require.NoError(err) 66 indexSGDDBPath, err := testutil.PathOfTempFile(_dBPath + "_sgd") 67 require.NoError(err) 68 cfg.Chain.TrieDBPatchFile = "" 69 cfg.Chain.TrieDBPath = testTriePath 70 cfg.Chain.ChainDBPath = testDBPath 71 cfg.Chain.IndexDBPath = indexDBPath 72 cfg.Chain.ContractStakingIndexDBPath = contractIndexDBPath 73 cfg.Chain.SGDIndexDBPath = indexSGDDBPath 74 defer func() { 75 testutil.CleanupPath(testTriePath) 76 testutil.CleanupPath(testDBPath) 77 testutil.CleanupPath(indexDBPath) 78 testutil.CleanupPath(contractIndexDBPath) 79 testutil.CleanupPath(indexSGDDBPath) 80 }() 81 82 // create server 83 ctx := genesis.WithGenesisContext(context.Background(), cfg.Genesis) 84 svr, err := itx.NewServer(cfg) 85 require.NoError(err) 86 require.NoError(svr.Start(ctx)) 87 defer func() { 88 require.NoError(svr.Stop(ctx)) 89 }() 90 cs := svr.ChainService(cfg.Chain.ID) 91 bc := cs.Blockchain() 92 sf := cs.StateFactory() 93 ap := cs.ActionPool() 94 require.NotNil(bc) 95 require.NotNil(sf) 96 require.NotNil(ap) 97 98 i27State, err := accountutil.AccountState(ctx, sf, identityset.Address(27)) 99 require.NoError(err) 100 require.NoError(addTestingTsfBlocks(bc, ap)) 101 require.EqualValues(5, bc.TipHeight()) 102 103 // check balance 104 change := &big.Int{} 105 for _, v := range []struct { 106 addrIndex int 107 balance string 108 }{ 109 {28, "23"}, 110 {29, "34"}, 111 {30, "47"}, 112 {31, "69"}, 113 {32, "100"}, 114 {33, "5242883"}, 115 } { 116 s, err := accountutil.AccountState(ctx, sf, identityset.Address(v.addrIndex)) 117 require.NoError(err) 118 require.Equal(v.balance, s.Balance.String()) 119 change.Add(change, s.Balance) 120 } 121 s, err := accountutil.AccountState(ctx, sf, identityset.Address(27)) 122 require.NoError(err) 123 change.Add(change, s.Balance) 124 change.Sub(change, i27State.Balance) 125 require.Equal(unit.ConvertIotxToRau(90000000), change) 126 127 // create client 128 cfg, err = newTestConfig() 129 require.NoError(err) 130 addrs, err := svr.P2PAgent().Self() 131 require.NoError(err) 132 cfg.Network.BootstrapNodes = []string{validNetworkAddr(addrs)} 133 p := p2p.NewAgent( 134 cfg.Network, 135 cfg.Chain.ID, 136 cfg.Genesis.Hash(), 137 func(_ context.Context, _ uint32, _ string, _ proto.Message) { 138 }, 139 func(_ context.Context, _ uint32, _ peer.AddrInfo, _ proto.Message) { 140 }, 141 ) 142 require.NotNil(p) 143 require.NoError(p.Start(ctx)) 144 defer func() { 145 require.NoError(p.Stop(ctx)) 146 }() 147 148 // create local chain 149 testTriePath2, err := testutil.PathOfTempFile(_triePath2) 150 require.NoError(err) 151 testDBPath2, err := testutil.PathOfTempFile(_dBPath2) 152 require.NoError(err) 153 indexDBPath2, err := testutil.PathOfTempFile(_dBPath2) 154 require.NoError(err) 155 defer func() { 156 testutil.CleanupPath(testTriePath2) 157 testutil.CleanupPath(testDBPath2) 158 testutil.CleanupPath(indexDBPath2) 159 }() 160 cfg.Chain.TrieDBPath = testTriePath2 161 cfg.Chain.ChainDBPath = testDBPath2 162 cfg.Chain.IndexDBPath = indexDBPath2 163 require.NoError(copyDB(testTriePath, testTriePath2)) 164 require.NoError(copyDB(testDBPath, testDBPath2)) 165 require.NoError(copyDB(indexDBPath, indexDBPath2)) 166 registry := protocol.NewRegistry() 167 factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis) 168 db1, err := db.CreateKVStoreWithCache(cfg.DB, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 169 require.NoError(err) 170 sf2, err := factory.NewStateDB(factoryCfg, db1, factory.RegistryStateDBOption(registry)) 171 require.NoError(err) 172 ap2, err := actpool.NewActPool(cfg.Genesis, sf2, cfg.ActPool) 173 require.NoError(err) 174 dbcfg := cfg.DB 175 dbcfg.DbPath = cfg.Chain.ChainDBPath 176 store, err := filedao.NewFileDAO(dbcfg, block.NewDeserializer(cfg.Chain.EVMNetworkID)) 177 require.NoError(err) 178 dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf2}, dbcfg.MaxCacheSize) 179 chain := blockchain.NewBlockchain( 180 cfg.Chain, 181 cfg.Genesis, 182 dao, 183 factory.NewMinter(sf2, ap2), 184 blockchain.BlockValidatorOption(block.NewValidator( 185 sf2, 186 protocol.NewGenericValidator(sf2, accountutil.AccountState), 187 )), 188 ) 189 rolldposProtocol := rolldpos.NewProtocol( 190 cfg.Genesis.NumCandidateDelegates, 191 cfg.Genesis.NumDelegates, 192 cfg.Genesis.NumSubEpochs, 193 ) 194 require.NoError(rolldposProtocol.Register(registry)) 195 rewardingProtocol := rewarding.NewProtocol(cfg.Genesis.Rewarding) 196 require.NoError(rewardingProtocol.Register(registry)) 197 acc := account.NewProtocol(rewarding.DepositGas) 198 require.NoError(acc.Register(registry)) 199 require.NoError(chain.Start(ctx)) 200 require.EqualValues(5, chain.TipHeight()) 201 defer func() { 202 require.NoError(chain.Stop(ctx)) 203 }() 204 205 // transfer 1 206 // C --> A 207 s, _ = accountutil.AccountState(ctx, sf, identityset.Address(30)) 208 tsf1, err := action.SignedTransfer(identityset.Address(28).String(), identityset.PrivateKey(30), s.PendingNonce(), big.NewInt(1), []byte{}, 100000, big.NewInt(0)) 209 require.NoError(err) 210 211 require.NoError(ap2.Add(context.Background(), tsf1)) 212 act1 := tsf1.Proto() 213 err = testutil.WaitUntil(10*time.Millisecond, 2*time.Second, func() (bool, error) { 214 if err := p.BroadcastOutbound(ctx, act1); err != nil { 215 return false, err 216 } 217 acts := ap.PendingActionMap() 218 return lenPendingActionMap(acts) == 1, nil 219 }) 220 require.NoError(err) 221 222 blk1, err := chain.MintNewBlock(testutil.TimestampNow()) 223 require.NoError(err) 224 require.NoError(chain.CommitBlock(blk1)) 225 226 // transfer 2 227 // F --> D 228 s, _ = accountutil.AccountState(ctx, sf, identityset.Address(33)) 229 tsf2, err := action.SignedTransfer(identityset.Address(31).String(), identityset.PrivateKey(33), s.PendingNonce(), big.NewInt(1), []byte{}, 100000, big.NewInt(0)) 230 require.NoError(err) 231 232 require.NoError(ap2.Add(context.Background(), tsf2)) 233 blk2, err := chain.MintNewBlock(testutil.TimestampNow()) 234 require.NoError(err) 235 require.NoError(chain.CommitBlock(blk2)) 236 // broadcast to P2P 237 act2 := tsf2.Proto() 238 err = testutil.WaitUntil(100*time.Millisecond, 60*time.Second, func() (bool, error) { 239 if err := p.BroadcastOutbound(ctx, act2); err != nil { 240 return false, err 241 } 242 acts := ap.PendingActionMap() 243 return lenPendingActionMap(acts) == 2, nil 244 }) 245 require.NoError(err) 246 247 // transfer 3 248 // B --> B 249 s, _ = accountutil.AccountState(ctx, sf, identityset.Address(29)) 250 tsf3, err := action.SignedTransfer(identityset.Address(29).String(), identityset.PrivateKey(29), s.PendingNonce(), big.NewInt(1), []byte{}, 100000, big.NewInt(0)) 251 require.NoError(err) 252 253 require.NoError(ap2.Add(context.Background(), tsf3)) 254 blk3, err := chain.MintNewBlock(testutil.TimestampNow()) 255 require.NoError(err) 256 require.NoError(chain.CommitBlock(blk3)) 257 // broadcast to P2P 258 act3 := tsf3.Proto() 259 err = testutil.WaitUntil(100*time.Millisecond, 60*time.Second, func() (bool, error) { 260 if err := p.BroadcastOutbound(ctx, act3); err != nil { 261 return false, err 262 } 263 acts := ap.PendingActionMap() 264 return lenPendingActionMap(acts) == 3, nil 265 }) 266 require.NoError(err) 267 268 // transfer 4 269 // test --> E 270 s, _ = accountutil.AccountState(ctx, sf, identityset.Address(27)) 271 tsf4, err := action.SignedTransfer(identityset.Address(32).String(), identityset.PrivateKey(27), s.PendingNonce(), big.NewInt(1), []byte{}, 100000, big.NewInt(0)) 272 require.NoError(err) 273 274 require.NoError(ap2.Add(context.Background(), tsf4)) 275 blk4, err := chain.MintNewBlock(testutil.TimestampNow()) 276 require.NoError(err) 277 require.NoError(chain.CommitBlock(blk4)) 278 // broadcast to P2P 279 act4 := tsf4.Proto() 280 err = testutil.WaitUntil(100*time.Millisecond, 60*time.Second, func() (bool, error) { 281 if err := p.BroadcastOutbound(ctx, act4); err != nil { 282 return false, err 283 } 284 acts := ap.PendingActionMap() 285 return lenPendingActionMap(acts) == 4, nil 286 }) 287 require.NoError(err) 288 // wait 4 blocks being picked and committed 289 require.NoError(p.BroadcastOutbound(ctx, blk2.ConvertToBlockPb())) 290 require.NoError(p.BroadcastOutbound(ctx, blk4.ConvertToBlockPb())) 291 require.NoError(p.BroadcastOutbound(ctx, blk1.ConvertToBlockPb())) 292 require.NoError(p.BroadcastOutbound(ctx, blk3.ConvertToBlockPb())) 293 err = testutil.WaitUntil(100*time.Millisecond, 60*time.Second, func() (bool, error) { 294 height := bc.TipHeight() 295 return int(height) == 9, nil 296 }) 297 require.NoError(err) 298 require.True(9 == bc.TipHeight()) 299 300 // check balance 301 change.SetBytes(nil) 302 for _, v := range []struct { 303 addrIndex int 304 balance string 305 }{ 306 {28, "24"}, 307 {29, "34"}, 308 {30, "46"}, 309 {31, "70"}, 310 {32, "101"}, 311 {33, "5242882"}, 312 } { 313 s, err = accountutil.AccountState(ctx, sf, identityset.Address(v.addrIndex)) 314 require.NoError(err) 315 require.Equal(v.balance, s.Balance.String()) 316 change.Add(change, s.Balance) 317 } 318 s, err = accountutil.AccountState(ctx, sf, identityset.Address(27)) 319 require.NoError(err) 320 change.Add(change, s.Balance) 321 change.Sub(change, i27State.Balance) 322 require.Equal(unit.ConvertIotxToRau(90000000), change) 323 } 324 325 func TestLocalSync(t *testing.T) { 326 require := require.New(t) 327 328 cfg, err := newTestConfig() 329 require.NoError(err) 330 testTriePath, err := testutil.PathOfTempFile(_triePath) 331 require.NoError(err) 332 testDBPath, err := testutil.PathOfTempFile(_dBPath) 333 require.NoError(err) 334 indexDBPath, err := testutil.PathOfTempFile(_dBPath) 335 require.NoError(err) 336 contractIndexDBPath, err := testutil.PathOfTempFile(_dBPath) 337 require.NoError(err) 338 indexSGDDBPath, err := testutil.PathOfTempFile(_dBPath + "_sgd") 339 require.NoError(err) 340 cfg.Chain.TrieDBPatchFile = "" 341 cfg.Chain.TrieDBPath = testTriePath 342 cfg.Chain.ChainDBPath = testDBPath 343 cfg.Chain.IndexDBPath = indexDBPath 344 cfg.Chain.ContractStakingIndexDBPath = contractIndexDBPath 345 cfg.Chain.SGDIndexDBPath = indexSGDDBPath 346 defer func() { 347 testutil.CleanupPath(testTriePath) 348 testutil.CleanupPath(testDBPath) 349 testutil.CleanupPath(indexDBPath) 350 testutil.CleanupPath(contractIndexDBPath) 351 testutil.CleanupPath(indexSGDDBPath) 352 }() 353 354 // bootnode 355 ctx := context.Background() 356 bootnodePort := testutil.RandomPort() 357 bootnode := p2p.NewAgent(p2p.Config{ 358 Host: "127.0.0.1", 359 Port: bootnodePort, 360 ReconnectInterval: 150 * time.Second}, 361 cfg.Chain.ID, 362 hash.ZeroHash256, 363 func(_ context.Context, _ uint32, _ string, msg proto.Message) {}, 364 func(_ context.Context, _ uint32, _ peer.AddrInfo, _ proto.Message) {}) 365 require.NoError(bootnode.Start(ctx)) 366 addrs, err := bootnode.Self() 367 require.NoError(err) 368 cfg.Network.BootstrapNodes = []string{validNetworkAddr(addrs)} 369 370 // Create server 371 svr, err := itx.NewServer(cfg) 372 require.NoError(err) 373 require.NoError(svr.Start(ctx)) 374 375 sChain := svr.ChainService(cfg.Chain.ID) 376 bc := sChain.Blockchain() 377 sf := sChain.StateFactory() 378 ap := sChain.ActionPool() 379 dao := sChain.BlockDAO() 380 require.NotNil(bc) 381 require.NotNil(sf) 382 require.NotNil(ap) 383 require.NotNil(dao) 384 require.NotNil(svr.P2PAgent()) 385 require.NoError(addTestingTsfBlocks(bc, ap)) 386 387 var blkHash [5]hash.Hash256 388 for i := uint64(1); i <= 5; i++ { 389 blk, err := dao.GetBlockByHeight(i) 390 require.NoError(err) 391 blkHash[i-1] = blk.HashBlock() 392 } 393 394 testDBPath2, err := testutil.PathOfTempFile(_dBPath2) 395 require.NoError(err) 396 testTriePath2, err := testutil.PathOfTempFile(_triePath2) 397 require.NoError(err) 398 indexDBPath2, err := testutil.PathOfTempFile(_dBPath2) 399 require.NoError(err) 400 contractIndexDBPath2, err := testutil.PathOfTempFile(_dBPath2) 401 require.NoError(err) 402 indexSGDDBPath2, err := testutil.PathOfTempFile(_dBPath2 + "_sgd") 403 require.NoError(err) 404 cfg, err = newTestConfig() 405 require.NoError(err) 406 cfg.Chain.TrieDBPatchFile = "" 407 cfg.Chain.TrieDBPath = testTriePath2 408 cfg.Chain.ChainDBPath = testDBPath2 409 cfg.Chain.IndexDBPath = indexDBPath2 410 cfg.Chain.ContractStakingIndexDBPath = contractIndexDBPath2 411 cfg.Chain.SGDIndexDBPath = indexSGDDBPath2 412 defer func() { 413 testutil.CleanupPath(testTriePath2) 414 testutil.CleanupPath(testDBPath2) 415 testutil.CleanupPath(indexDBPath2) 416 testutil.CleanupPath(contractIndexDBPath2) 417 testutil.CleanupPath(indexSGDDBPath2) 418 }() 419 420 // Create client 421 cfg.Network.BootstrapNodes = []string{validNetworkAddr(addrs)} 422 cfg.BlockSync.Interval = 1 * time.Second 423 cli, err := itx.NewServer(cfg) 424 require.NoError(err) 425 require.NoError(cli.Start(ctx)) 426 nChain := cli.ChainService(cfg.Chain.ID) 427 require.NotNil(nChain.Blockchain()) 428 require.NotNil(cli.P2PAgent()) 429 require.Zero(nChain.Blockchain().TipHeight()) 430 defer func() { 431 require.NoError(cli.Stop(ctx)) 432 require.NoError(svr.Stop(ctx)) 433 }() 434 435 err = testutil.WaitUntil(time.Millisecond*100, time.Second*60, func() (bool, error) { 436 peers, err := svr.P2PAgent().ConnectedPeers() 437 return len(peers) >= 1, err 438 }) 439 require.NoError(err) 440 nDao := nChain.BlockDAO() 441 check := testutil.CheckCondition(func() (bool, error) { 442 for i := uint64(1); i <= 5; i++ { 443 blk, err := nDao.GetBlockByHeight(i) 444 if err != nil { 445 return false, nil 446 } 447 if blk.HashBlock() != blkHash[i-1] { 448 return false, nil 449 } 450 } 451 return true, nil 452 }) 453 require.NoError(testutil.WaitUntil(time.Millisecond*100, time.Second*60, check)) 454 require.EqualValues(5, nChain.Blockchain().TipHeight()) 455 } 456 457 func TestStartExistingBlockchain(t *testing.T) { 458 require := require.New(t) 459 ctx := context.Background() 460 testDBPath, err := testutil.PathOfTempFile(_dBPath) 461 require.NoError(err) 462 testTriePath, err := testutil.PathOfTempFile(_triePath) 463 require.NoError(err) 464 testIndexPath, err := testutil.PathOfTempFile(_dBPath) 465 require.NoError(err) 466 testContractStakeIndexPath, err := testutil.PathOfTempFile(_dBPath) 467 require.NoError(err) 468 testSGDIndexPath, err := testutil.PathOfTempFile(_dBPath + "_sgd") 469 require.NoError(err) 470 // Disable block reward to make bookkeeping easier 471 cfg := config.Default 472 cfg.Chain.TrieDBPatchFile = "" 473 cfg.Chain.TrieDBPath = testTriePath 474 cfg.Chain.ChainDBPath = testDBPath 475 cfg.Chain.IndexDBPath = testIndexPath 476 cfg.Chain.ContractStakingIndexDBPath = testContractStakeIndexPath 477 cfg.Chain.SGDIndexDBPath = testSGDIndexPath 478 cfg.Chain.EnableAsyncIndexWrite = false 479 cfg.ActPool.MinGasPriceStr = "0" 480 cfg.Consensus.Scheme = config.NOOPScheme 481 cfg.Network.Port = testutil.RandomPort() 482 483 svr, err := itx.NewServer(cfg) 484 require.NoError(err) 485 require.NoError(svr.Start(ctx)) 486 cs := svr.ChainService(cfg.Chain.ID) 487 bc := cs.Blockchain() 488 ap := cs.ActionPool() 489 require.NotNil(bc) 490 require.NotNil(cs.StateFactory()) 491 require.NotNil(ap) 492 require.NotNil(cs.BlockDAO()) 493 494 defer func() { 495 testutil.CleanupPath(testTriePath) 496 testutil.CleanupPath(testDBPath) 497 testutil.CleanupPath(testIndexPath) 498 testutil.CleanupPath(testContractStakeIndexPath) 499 testutil.CleanupPath(testSGDIndexPath) 500 }() 501 502 require.NoError(addTestingTsfBlocks(bc, ap)) 503 require.Equal(uint64(5), bc.TipHeight()) 504 505 require.NoError(svr.Stop(ctx)) 506 // Delete state db and recover to tip 507 testutil.CleanupPath(testTriePath) 508 testutil.CleanupPath(testContractStakeIndexPath) 509 510 require.NoError(cs.Blockchain().Start(ctx)) 511 height, _ := cs.StateFactory().Height() 512 require.Equal(bc.TipHeight(), height) 513 require.Equal(uint64(5), height) 514 require.NoError(cs.Blockchain().Stop(ctx)) 515 516 // Recover to height 3 from empty state DB 517 cfg.DB.DbPath = cfg.Chain.ChainDBPath 518 deser := block.NewDeserializer(cfg.Chain.EVMNetworkID) 519 dao, err := filedao.NewFileDAO(cfg.DB, deser) 520 require.NoError(err) 521 require.NoError(dao.Start(protocol.WithBlockchainCtx( 522 genesis.WithGenesisContext(ctx, cfg.Genesis), 523 protocol.BlockchainCtx{ 524 ChainID: cfg.Chain.ID, 525 }))) 526 for { 527 height, err := dao.Height() 528 require.NoError(err) 529 if height <= 3 { 530 break 531 } 532 require.NoError(dao.DeleteTipBlock()) 533 } 534 require.NoError(dao.Stop(ctx)) 535 536 // Build states from height 1 to 3 537 testutil.CleanupPath(testTriePath) 538 testutil.CleanupPath(testContractStakeIndexPath) 539 testutil.CleanupPath(testSGDIndexPath) 540 svr, err = itx.NewServer(cfg) 541 require.NoError(err) 542 require.NoError(svr.Start(ctx)) 543 cs = svr.ChainService(cfg.Chain.ID) 544 height, _ = cs.StateFactory().Height() 545 require.Equal(cs.Blockchain().TipHeight(), height) 546 require.Equal(uint64(3), height) 547 548 // Recover to height 2 from an existing state DB with Height 3 549 require.NoError(svr.Stop(ctx)) 550 cfg.DB.DbPath = cfg.Chain.ChainDBPath 551 dao, err = filedao.NewFileDAO(cfg.DB, deser) 552 require.NoError(err) 553 require.NoError(dao.Start(protocol.WithBlockchainCtx( 554 genesis.WithGenesisContext(ctx, cfg.Genesis), 555 protocol.BlockchainCtx{ 556 ChainID: cfg.Chain.ID, 557 }))) 558 for { 559 height, err := dao.Height() 560 require.NoError(err) 561 if height <= 2 { 562 break 563 } 564 require.NoError(dao.DeleteTipBlock()) 565 } 566 require.NoError(dao.Stop(ctx)) 567 testutil.CleanupPath(testTriePath) 568 testutil.CleanupPath(testContractStakeIndexPath) 569 testutil.CleanupPath(testSGDIndexPath) 570 svr, err = itx.NewServer(cfg) 571 require.NoError(err) 572 // Build states from height 1 to 2 573 require.NoError(svr.Start(ctx)) 574 cs = svr.ChainService(cfg.Chain.ID) 575 height, _ = cs.StateFactory().Height() 576 require.Equal(cs.Blockchain().TipHeight(), height) 577 require.Equal(uint64(2), height) 578 require.NoError(svr.Stop(ctx)) 579 } 580 581 func newTestConfig() (config.Config, error) { 582 cfg := config.Default 583 cfg.Chain.TrieDBPath = _triePath 584 cfg.Chain.ChainDBPath = _dBPath 585 cfg.ActPool.MinGasPriceStr = "0" 586 cfg.Consensus.Scheme = config.NOOPScheme 587 cfg.Network.Port = testutil.RandomPort() 588 cfg.API.GRPCPort = testutil.RandomPort() 589 cfg.API.HTTPPort = testutil.RandomPort() 590 cfg.API.WebSocketPort = testutil.RandomPort() 591 cfg.Genesis.EnableGravityChainVoting = false 592 cfg.Genesis.MidwayBlockHeight = 1 593 sk, err := crypto.GenerateKey() 594 595 if err != nil { 596 return config.Config{}, err 597 } 598 cfg.Chain.ProducerPrivKey = sk.HexString() 599 return cfg, nil 600 } 601 602 func validNetworkAddr(addrs []multiaddr.Multiaddr) (ret string) { 603 for _, addr := range addrs { 604 if !strings.Contains(addr.String(), _disabledIP) { 605 return addr.String() 606 } 607 } 608 return 609 }