github.com/iotexproject/iotex-core@v1.14.1-rc1/blocksync/blocksync_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 blocksync 7 8 import ( 9 "context" 10 "testing" 11 "time" 12 13 "github.com/golang/mock/gomock" 14 "github.com/iotexproject/go-pkgs/hash" 15 "github.com/libp2p/go-libp2p-core/peer" 16 "github.com/pkg/errors" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 "google.golang.org/protobuf/proto" 20 21 "github.com/iotexproject/iotex-core/action/protocol" 22 "github.com/iotexproject/iotex-core/action/protocol/account" 23 accountutil "github.com/iotexproject/iotex-core/action/protocol/account/util" 24 "github.com/iotexproject/iotex-core/action/protocol/rewarding" 25 "github.com/iotexproject/iotex-core/action/protocol/rolldpos" 26 "github.com/iotexproject/iotex-core/actpool" 27 "github.com/iotexproject/iotex-core/blockchain" 28 "github.com/iotexproject/iotex-core/blockchain/block" 29 "github.com/iotexproject/iotex-core/blockchain/blockdao" 30 "github.com/iotexproject/iotex-core/blockchain/filedao" 31 "github.com/iotexproject/iotex-core/blockchain/genesis" 32 "github.com/iotexproject/iotex-core/consensus" 33 "github.com/iotexproject/iotex-core/db" 34 "github.com/iotexproject/iotex-core/state/factory" 35 "github.com/iotexproject/iotex-core/test/identityset" 36 "github.com/iotexproject/iotex-core/test/mock/mock_blockchain" 37 "github.com/iotexproject/iotex-core/test/mock/mock_blockdao" 38 "github.com/iotexproject/iotex-core/test/mock/mock_blocksync" 39 "github.com/iotexproject/iotex-core/test/mock/mock_consensus" 40 "github.com/iotexproject/iotex-core/testutil" 41 ) 42 43 type testConfig struct { 44 BlockSync Config 45 Genesis genesis.Genesis 46 Chain blockchain.Config 47 ActPool actpool.Config 48 } 49 50 func newBlockSyncerForTest(cfg Config, chain blockchain.Blockchain, dao blockdao.BlockDAO, cs consensus.Consensus) (*blockSyncer, error) { 51 bs, err := NewBlockSyncer(cfg, chain.TipHeight, 52 func(h uint64) (*block.Block, error) { 53 return dao.GetBlockByHeight(h) 54 }, 55 func(blk *block.Block) error { 56 if err := cs.ValidateBlockFooter(blk); err != nil { 57 return err 58 } 59 if err := chain.ValidateBlock(blk); err != nil { 60 return err 61 } 62 if err := chain.CommitBlock(blk); err != nil { 63 return err 64 } 65 cs.Calibrate(blk.Height()) 66 return nil 67 }, 68 func() ([]peer.AddrInfo, error) { 69 return []peer.AddrInfo{}, nil 70 }, 71 func(context.Context, peer.AddrInfo, proto.Message) error { 72 return nil 73 }, 74 func(string) { 75 return 76 }, 77 ) 78 if err != nil { 79 return nil, err 80 } 81 return bs.(*blockSyncer), nil 82 } 83 84 func TestNewBlockSyncer(t *testing.T) { 85 assert := assert.New(t) 86 require := require.New(t) 87 88 ctrl := gomock.NewController(t) 89 90 mBc := mock_blockchain.NewMockBlockchain(ctrl) 91 // TipHeight return ERROR 92 mBc.EXPECT().TipHeight().AnyTimes().Return(uint64(0)) 93 mBc.EXPECT().ChainID().AnyTimes().Return(blockchain.DefaultConfig.ID) 94 blk := block.NewBlockDeprecated( 95 uint32(123), 96 uint64(0), 97 hash.Hash256{}, 98 testutil.TimestampNow(), 99 identityset.PrivateKey(27).PublicKey(), 100 nil, 101 ) 102 dao := mock_blockdao.NewMockBlockDAO(ctrl) 103 dao.EXPECT().GetBlockByHeight(gomock.Any()).AnyTimes().Return(blk, nil) 104 105 cfg, err := newTestConfig() 106 require.NoError(err) 107 108 cs := mock_consensus.NewMockConsensus(ctrl) 109 110 bs, err := newBlockSyncerForTest(cfg.BlockSync, mBc, dao, cs) 111 assert.Nil(err) 112 assert.NotNil(bs) 113 } 114 115 func TestBlockSyncerStart(t *testing.T) { 116 assert := assert.New(t) 117 118 ctrl := gomock.NewController(t) 119 120 ctx := context.Background() 121 mBs := mock_blocksync.NewMockBlockSync(ctrl) 122 mBs.EXPECT().Start(gomock.Any()).Times(1) 123 assert.Nil(mBs.Start(ctx)) 124 } 125 126 func TestBlockSyncerStop(t *testing.T) { 127 assert := assert.New(t) 128 129 ctrl := gomock.NewController(t) 130 131 ctx := context.Background() 132 mBs := mock_blocksync.NewMockBlockSync(ctrl) 133 mBs.EXPECT().Stop(gomock.Any()).Times(1) 134 assert.Nil(mBs.Stop(ctx)) 135 } 136 137 func TestBlockSyncerProcessSyncRequest(t *testing.T) { 138 assert := assert.New(t) 139 require := require.New(t) 140 141 ctrl := gomock.NewController(t) 142 143 mBc := mock_blockchain.NewMockBlockchain(ctrl) 144 mBc.EXPECT().ChainID().AnyTimes().Return(blockchain.DefaultConfig.ID) 145 blk := block.NewBlockDeprecated( 146 uint32(123), 147 uint64(0), 148 hash.Hash256{}, 149 testutil.TimestampNow(), 150 identityset.PrivateKey(27).PublicKey(), 151 nil, 152 ) 153 dao := mock_blockdao.NewMockBlockDAO(ctrl) 154 dao.EXPECT().GetBlockByHeight(gomock.Any()).AnyTimes().Return(blk, nil) 155 mBc.EXPECT().TipHeight().AnyTimes().Return(uint64(0)) 156 cfg, err := newTestConfig() 157 require.NoError(err) 158 cs := mock_consensus.NewMockConsensus(ctrl) 159 160 bs, err := newBlockSyncerForTest(cfg.BlockSync, mBc, dao, cs) 161 assert.NoError(err) 162 assert.NoError(bs.ProcessSyncRequest(context.Background(), peer.AddrInfo{}, 1, 1)) 163 } 164 165 func TestBlockSyncerProcessSyncRequestError(t *testing.T) { 166 require := require.New(t) 167 ctrl := gomock.NewController(t) 168 169 cfg, err := newTestConfig() 170 require.NoError(err) 171 172 chain := mock_blockchain.NewMockBlockchain(ctrl) 173 dao := mock_blockdao.NewMockBlockDAO(ctrl) 174 dao.EXPECT().GetBlockByHeight(uint64(1)).Return(nil, errors.New("some error")).Times(1) 175 chain.EXPECT().ChainID().Return(uint32(1)).AnyTimes() 176 chain.EXPECT().TipHeight().Return(uint64(10)).Times(1) 177 cs := mock_consensus.NewMockConsensus(ctrl) 178 179 bs, err := newBlockSyncerForTest(cfg.BlockSync, chain, dao, cs) 180 require.NoError(err) 181 182 require.Error(bs.ProcessSyncRequest(context.Background(), peer.AddrInfo{}, 1, 5)) 183 } 184 185 func TestBlockSyncerProcessBlockTipHeight(t *testing.T) { 186 require := require.New(t) 187 ctrl := gomock.NewController(t) 188 189 ctx := context.Background() 190 cfg, err := newTestConfig() 191 require.NoError(err) 192 registry := protocol.NewRegistry() 193 acc := account.NewProtocol(rewarding.DepositGas) 194 require.NoError(acc.Register(registry)) 195 rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs) 196 require.NoError(rp.Register(registry)) 197 factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis) 198 sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry)) 199 require.NoError(err) 200 ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool) 201 require.NotNil(ap) 202 require.NoError(err) 203 ap.AddActionEnvelopeValidators(protocol.NewGenericValidator(sf, accountutil.AccountState)) 204 store, err := filedao.NewFileDAOInMemForTest() 205 require.NoError(err) 206 dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, 16) 207 chain := blockchain.NewBlockchain( 208 cfg.Chain, 209 cfg.Genesis, 210 dao, 211 factory.NewMinter(sf, ap), 212 blockchain.BlockValidatorOption(block.NewValidator(sf, ap)), 213 ) 214 require.NoError(chain.Start(ctx)) 215 require.NotNil(chain) 216 cs := mock_consensus.NewMockConsensus(ctrl) 217 cs.EXPECT().ValidateBlockFooter(gomock.Any()).Return(nil).Times(1) 218 cs.EXPECT().Calibrate(uint64(1)).Times(1) 219 220 bs, err := newBlockSyncerForTest(cfg.BlockSync, chain, dao, cs) 221 require.NoError(err) 222 223 defer func() { 224 require.NoError(chain.Stop(ctx)) 225 }() 226 227 h := chain.TipHeight() 228 blk, err := chain.MintNewBlock(testutil.TimestampNow()) 229 require.NotNil(blk) 230 require.NoError(err) 231 ctx, err = chain.Context(ctx) 232 require.NoError(err) 233 234 peer := "peer1" 235 236 require.NoError(bs.ProcessBlock(ctx, peer, blk)) 237 h2 := chain.TipHeight() 238 assert.Equal(t, h+1, h2) 239 240 // commit top 241 require.NoError(bs.ProcessBlock(ctx, peer, blk)) 242 h3 := chain.TipHeight() 243 assert.Equal(t, h+1, h3) 244 245 // commit same block again 246 require.NoError(bs.ProcessBlock(ctx, peer, blk)) 247 h4 := chain.TipHeight() 248 assert.Equal(t, h3, h4) 249 } 250 251 func TestBlockSyncerProcessBlockOutOfOrder(t *testing.T) { 252 require := require.New(t) 253 ctrl := gomock.NewController(t) 254 255 ctx := context.Background() 256 cfg, err := newTestConfig() 257 require.NoError(err) 258 registry := protocol.NewRegistry() 259 acc := account.NewProtocol(rewarding.DepositGas) 260 require.NoError(acc.Register(registry)) 261 rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs) 262 require.NoError(rp.Register(registry)) 263 factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis) 264 sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry)) 265 require.NoError(err) 266 ap1, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool) 267 require.NotNil(ap1) 268 require.NoError(err) 269 ap1.AddActionEnvelopeValidators(protocol.NewGenericValidator(sf, accountutil.AccountState)) 270 store, err := filedao.NewFileDAOInMemForTest() 271 require.NoError(err) 272 dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, 16) 273 chain1 := blockchain.NewBlockchain( 274 cfg.Chain, 275 cfg.Genesis, 276 dao, 277 factory.NewMinter(sf, ap1), 278 blockchain.BlockValidatorOption(block.NewValidator(sf, ap1)), 279 ) 280 require.NotNil(chain1) 281 require.NoError(chain1.Start(ctx)) 282 cs1 := mock_consensus.NewMockConsensus(ctrl) 283 cs1.EXPECT().ValidateBlockFooter(gomock.Any()).Return(nil).Times(3) 284 cs1.EXPECT().Calibrate(gomock.Any()).Times(3) 285 286 bs1, err := newBlockSyncerForTest(cfg.BlockSync, chain1, dao, cs1) 287 require.NoError(err) 288 registry2 := protocol.NewRegistry() 289 require.NoError(acc.Register(registry2)) 290 require.NoError(rp.Register(registry2)) 291 sf2, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry2)) 292 require.NoError(err) 293 ap2, err := actpool.NewActPool(cfg.Genesis, sf2, cfg.ActPool) 294 require.NotNil(ap2) 295 require.NoError(err) 296 ap2.AddActionEnvelopeValidators(protocol.NewGenericValidator(sf2, accountutil.AccountState)) 297 store2, err := filedao.NewFileDAOInMemForTest() 298 require.NoError(err) 299 dao2 := blockdao.NewBlockDAOWithIndexersAndCache(store2, []blockdao.BlockIndexer{sf2}, 16) 300 chain2 := blockchain.NewBlockchain( 301 cfg.Chain, 302 cfg.Genesis, 303 dao2, 304 factory.NewMinter(sf2, ap2), 305 blockchain.BlockValidatorOption(block.NewValidator(sf2, ap2)), 306 ) 307 require.NotNil(chain2) 308 require.NoError(chain2.Start(ctx)) 309 cs2 := mock_consensus.NewMockConsensus(ctrl) 310 cs2.EXPECT().ValidateBlockFooter(gomock.Any()).Return(nil).Times(3) 311 cs2.EXPECT().Calibrate(gomock.Any()).Times(3) 312 bs2, err := newBlockSyncerForTest(cfg.BlockSync, chain2, dao2, cs2) 313 require.NoError(err) 314 315 defer func() { 316 require.NoError(chain1.Stop(ctx)) 317 require.NoError(chain2.Stop(ctx)) 318 }() 319 320 // commit top 321 ctx, err = chain1.Context(ctx) 322 require.NoError(err) 323 324 peer := "peer1" 325 326 blk1, err := chain1.MintNewBlock(testutil.TimestampNow()) 327 require.NotNil(blk1) 328 require.NoError(err) 329 require.NoError(bs1.ProcessBlock(ctx, peer, blk1)) 330 blk2, err := chain1.MintNewBlock(testutil.TimestampNow()) 331 require.NotNil(blk2) 332 require.NoError(err) 333 require.NoError(bs1.ProcessBlock(ctx, peer, blk2)) 334 blk3, err := chain1.MintNewBlock(testutil.TimestampNow()) 335 require.NotNil(blk3) 336 require.NoError(err) 337 require.NoError(bs1.ProcessBlock(ctx, peer, blk3)) 338 h1 := chain1.TipHeight() 339 assert.Equal(t, uint64(3), h1) 340 341 require.NoError(bs2.ProcessBlock(ctx, peer, blk3)) 342 require.NoError(bs2.ProcessBlock(ctx, peer, blk2)) 343 require.NoError(bs2.ProcessBlock(ctx, peer, blk2)) 344 require.NoError(bs2.ProcessBlock(ctx, peer, blk1)) 345 h2 := chain2.TipHeight() 346 assert.Equal(t, h1, h2) 347 } 348 349 func TestBlockSyncerProcessBlock(t *testing.T) { 350 require := require.New(t) 351 ctrl := gomock.NewController(t) 352 353 ctx := context.Background() 354 cfg, err := newTestConfig() 355 require.NoError(err) 356 registry := protocol.NewRegistry() 357 acc := account.NewProtocol(rewarding.DepositGas) 358 require.NoError(acc.Register(registry)) 359 rolldposProtocol := rolldpos.NewProtocol( 360 cfg.Genesis.NumCandidateDelegates, 361 cfg.Genesis.NumDelegates, 362 cfg.Genesis.NumSubEpochs, 363 ) 364 require.NoError(rolldposProtocol.Register(registry)) 365 factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis) 366 sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry)) 367 require.NoError(err) 368 ap1, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool) 369 require.NotNil(ap1) 370 require.NoError(err) 371 ap1.AddActionEnvelopeValidators(protocol.NewGenericValidator(sf, accountutil.AccountState)) 372 store, err := filedao.NewFileDAOInMemForTest() 373 require.NoError(err) 374 dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, 16) 375 chain1 := blockchain.NewBlockchain( 376 cfg.Chain, 377 cfg.Genesis, 378 dao, 379 factory.NewMinter(sf, ap1), 380 blockchain.BlockValidatorOption(block.NewValidator(sf, ap1)), 381 ) 382 require.NoError(chain1.Start(ctx)) 383 require.NotNil(chain1) 384 cs1 := mock_consensus.NewMockConsensus(ctrl) 385 cs1.EXPECT().ValidateBlockFooter(gomock.Any()).Return(nil).Times(3) 386 cs1.EXPECT().Calibrate(gomock.Any()).Times(3) 387 bs1, err := newBlockSyncerForTest(cfg.BlockSync, chain1, dao, cs1) 388 require.NoError(err) 389 registry2 := protocol.NewRegistry() 390 require.NoError(acc.Register(registry2)) 391 require.NoError(rolldposProtocol.Register(registry2)) 392 sf2, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry2)) 393 require.NoError(err) 394 ap2, err := actpool.NewActPool(cfg.Genesis, sf2, cfg.ActPool) 395 require.NotNil(ap2) 396 require.NoError(err) 397 ap2.AddActionEnvelopeValidators(protocol.NewGenericValidator(sf2, accountutil.AccountState)) 398 store2, err := filedao.NewFileDAOInMemForTest() 399 require.NoError(err) 400 dao2 := blockdao.NewBlockDAOWithIndexersAndCache(store2, []blockdao.BlockIndexer{sf2}, 16) 401 chain2 := blockchain.NewBlockchain( 402 cfg.Chain, 403 cfg.Genesis, 404 dao2, 405 factory.NewMinter(sf2, ap2), 406 blockchain.BlockValidatorOption(block.NewValidator(sf2, ap2)), 407 ) 408 require.NoError(chain2.Start(ctx)) 409 require.NotNil(chain2) 410 cs2 := mock_consensus.NewMockConsensus(ctrl) 411 cs2.EXPECT().ValidateBlockFooter(gomock.Any()).Return(nil).Times(3) 412 cs2.EXPECT().Calibrate(gomock.Any()).Times(3) 413 bs2, err := newBlockSyncerForTest(cfg.BlockSync, chain2, dao2, cs2) 414 require.NoError(err) 415 416 defer func() { 417 require.NoError(chain1.Stop(ctx)) 418 require.NoError(chain2.Stop(ctx)) 419 }() 420 421 ctx, err = chain1.Context(ctx) 422 require.NoError(err) 423 424 peer := "peer1" 425 426 // commit top 427 blk1, err := chain1.MintNewBlock(testutil.TimestampNow()) 428 require.NotNil(blk1) 429 require.NoError(err) 430 require.NoError(bs1.ProcessBlock(ctx, peer, blk1)) 431 blk2, err := chain1.MintNewBlock(testutil.TimestampNow()) 432 require.NotNil(blk2) 433 require.NoError(err) 434 require.NoError(bs1.ProcessBlock(ctx, peer, blk2)) 435 blk3, err := chain1.MintNewBlock(testutil.TimestampNow()) 436 require.NotNil(blk3) 437 require.NoError(err) 438 require.NoError(bs1.ProcessBlock(ctx, peer, blk3)) 439 h1 := chain1.TipHeight() 440 assert.Equal(t, uint64(3), h1) 441 442 require.NoError(bs2.ProcessBlock(ctx, peer, blk2)) 443 require.NoError(bs2.ProcessBlock(ctx, peer, blk3)) 444 require.NoError(bs2.ProcessBlock(ctx, peer, blk1)) 445 h2 := chain2.TipHeight() 446 assert.Equal(t, h1, h2) 447 } 448 449 func TestBlockSyncerSync(t *testing.T) { 450 require := require.New(t) 451 ctrl := gomock.NewController(t) 452 453 ctx := context.Background() 454 cfg, err := newTestConfig() 455 require.NoError(err) 456 registry := protocol.NewRegistry() 457 rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs) 458 require.NoError(rp.Register(registry)) 459 factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis) 460 sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry)) 461 require.NoError(err) 462 ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool) 463 require.NotNil(ap) 464 require.NoError(err) 465 ap.AddActionEnvelopeValidators(protocol.NewGenericValidator(sf, accountutil.AccountState)) 466 store, err := filedao.NewFileDAOInMemForTest() 467 require.NoError(err) 468 dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, 16) 469 chain := blockchain.NewBlockchain( 470 cfg.Chain, 471 cfg.Genesis, 472 dao, 473 factory.NewMinter(sf, ap), 474 blockchain.BlockValidatorOption(block.NewValidator(sf, ap)), 475 ) 476 require.NoError(chain.Start(ctx)) 477 require.NotNil(chain) 478 cs := mock_consensus.NewMockConsensus(ctrl) 479 cs.EXPECT().ValidateBlockFooter(gomock.Any()).Return(nil).Times(2) 480 cs.EXPECT().Calibrate(gomock.Any()).Times(2) 481 482 bs, err := newBlockSyncerForTest(cfg.BlockSync, chain, dao, cs) 483 require.NoError(err) 484 require.NotNil(bs) 485 require.NoError(bs.Start(ctx)) 486 time.Sleep(time.Millisecond << 7) 487 488 defer func() { 489 require.NoError(bs.Stop(ctx)) 490 require.NoError(chain.Stop(ctx)) 491 }() 492 493 ctx, err = chain.Context(ctx) 494 require.NoError(err) 495 496 peer := "peer1" 497 498 blk, err := chain.MintNewBlock(testutil.TimestampNow()) 499 require.NotNil(blk) 500 require.NoError(err) 501 require.NoError(bs.ProcessBlock(ctx, peer, blk)) 502 503 blk, err = chain.MintNewBlock(testutil.TimestampNow()) 504 require.NotNil(blk) 505 require.NoError(err) 506 require.NoError(bs.ProcessBlock(ctx, peer, blk)) 507 time.Sleep(time.Millisecond << 7) 508 } 509 510 func newTestConfig() (testConfig, error) { 511 testTriePath, err := testutil.PathOfTempFile("trie") 512 if err != nil { 513 return testConfig{}, err 514 } 515 testDBPath, err := testutil.PathOfTempFile("db") 516 if err != nil { 517 return testConfig{}, err 518 } 519 defer func() { 520 testutil.CleanupPath(testTriePath) 521 testutil.CleanupPath(testDBPath) 522 }() 523 524 cfg := testConfig{ 525 BlockSync: DefaultConfig, 526 Genesis: genesis.Default, 527 Chain: blockchain.DefaultConfig, 528 ActPool: actpool.DefaultConfig, 529 } 530 cfg.Chain.TrieDBPath = testTriePath 531 cfg.Chain.ChainDBPath = testDBPath 532 cfg.BlockSync.Interval = 100 * time.Millisecond 533 cfg.Genesis.EnableGravityChainVoting = false 534 return cfg, nil 535 } 536 537 func TestDummyBlockSync(t *testing.T) { 538 require := require.New(t) 539 bs := NewDummyBlockSyncer() 540 require.NoError(bs.Start(nil)) 541 require.NoError(bs.Stop(nil)) 542 require.NoError(bs.ProcessBlock(nil, "", nil)) 543 require.NoError(bs.ProcessSyncRequest(nil, peer.AddrInfo{}, 0, 0)) 544 require.Equal(bs.TargetHeight(), uint64(0)) 545 startingHeight, currentHeight, targetHeight, desc := bs.SyncStatus() 546 require.Zero(startingHeight) 547 require.Zero(currentHeight) 548 require.Zero(targetHeight) 549 require.Empty(desc) 550 }