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  }