github.com/iotexproject/iotex-core@v1.14.1-rc1/blocksync/buffer_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  
    12  	"github.com/golang/mock/gomock"
    13  	"github.com/iotexproject/go-pkgs/hash"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	"github.com/iotexproject/iotex-core/action/protocol"
    18  	"github.com/iotexproject/iotex-core/action/protocol/account"
    19  	accountutil "github.com/iotexproject/iotex-core/action/protocol/account/util"
    20  	"github.com/iotexproject/iotex-core/action/protocol/rewarding"
    21  	"github.com/iotexproject/iotex-core/action/protocol/rolldpos"
    22  	"github.com/iotexproject/iotex-core/actpool"
    23  	"github.com/iotexproject/iotex-core/blockchain"
    24  	"github.com/iotexproject/iotex-core/blockchain/block"
    25  	"github.com/iotexproject/iotex-core/blockchain/blockdao"
    26  	"github.com/iotexproject/iotex-core/blockchain/filedao"
    27  	"github.com/iotexproject/iotex-core/db"
    28  	"github.com/iotexproject/iotex-core/state/factory"
    29  	"github.com/iotexproject/iotex-core/test/identityset"
    30  	"github.com/iotexproject/iotex-core/testutil"
    31  )
    32  
    33  func TestBlockBufferFlush(t *testing.T) {
    34  	require := require.New(t)
    35  	ctx := context.Background()
    36  	cfg, err := newTestConfig()
    37  	require.NoError(err)
    38  
    39  	registry := protocol.NewRegistry()
    40  	acc := account.NewProtocol(rewarding.DepositGas)
    41  	require.NoError(acc.Register(registry))
    42  	rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
    43  	require.NoError(rp.Register(registry))
    44  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
    45  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
    46  	require.NoError(err)
    47  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
    48  	require.NotNil(ap)
    49  	require.NoError(err)
    50  	ap.AddActionEnvelopeValidators(protocol.NewGenericValidator(sf, accountutil.AccountState))
    51  	store, err := filedao.NewFileDAOInMemForTest()
    52  	require.NoError(err)
    53  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, 16)
    54  	chain := blockchain.NewBlockchain(
    55  		cfg.Chain,
    56  		cfg.Genesis,
    57  		dao,
    58  		factory.NewMinter(sf, ap),
    59  		blockchain.BlockValidatorOption(block.NewValidator(sf, ap)),
    60  	)
    61  	require.NoError(chain.Start(ctx))
    62  	require.NotNil(chain)
    63  	ctrl := gomock.NewController(t)
    64  	defer ctrl.Finish()
    65  	// cs := mock_consensus.NewMockConsensus(ctrl)
    66  	// cs.EXPECT().ValidateBlockFooter(gomock.Any()).Return(nil).Times(1)
    67  	// cs.EXPECT().Calibrate(gomock.Any()).Times(1)
    68  	defer func() {
    69  		require.NoError(chain.Stop(ctx))
    70  	}()
    71  	ctx, err = chain.Context(ctx)
    72  	require.NoError(err)
    73  
    74  	b := blockBuffer{
    75  		blockQueues: make(map[uint64]*uniQueue),
    76  		bufferSize:  16,
    77  	}
    78  	blk, err := chain.MintNewBlock(testutil.TimestampNow())
    79  	require.NoError(err)
    80  
    81  	pid := "peer1"
    82  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
    83  	require.Equal(1, len(b.blockQueues))
    84  
    85  	blk = block.NewBlockDeprecated(
    86  		uint32(123),
    87  		uint64(0),
    88  		hash.Hash256{},
    89  		testutil.TimestampNow(),
    90  		identityset.PrivateKey(27).PublicKey(),
    91  		nil,
    92  	)
    93  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
    94  	require.Equal(1, len(b.blockQueues))
    95  
    96  	blk = block.NewBlockDeprecated(
    97  		uint32(123),
    98  		uint64(5),
    99  		hash.Hash256{},
   100  		testutil.TimestampNow(),
   101  		identityset.PrivateKey(27).PublicKey(),
   102  		nil,
   103  	)
   104  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   105  	require.Equal(2, len(b.blockQueues))
   106  
   107  	blk = block.NewBlockDeprecated(
   108  		uint32(123),
   109  		uint64(5),
   110  		hash.Hash256{},
   111  		testutil.TimestampNow(),
   112  		identityset.PrivateKey(27).PublicKey(),
   113  		nil,
   114  	)
   115  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   116  	require.Equal(2, len(b.blockQueues))
   117  
   118  	blk = block.NewBlockDeprecated(
   119  		uint32(123),
   120  		uint64(500),
   121  		hash.Hash256{},
   122  		testutil.TimestampNow(),
   123  		identityset.PrivateKey(27).PublicKey(),
   124  		nil,
   125  	)
   126  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   127  	require.Equal(2, len(b.blockQueues))
   128  }
   129  
   130  func TestBlockBufferGetBlocksIntervalsToSync(t *testing.T) {
   131  	require := require.New(t)
   132  	assert := assert.New(t)
   133  	ctx := context.Background()
   134  	cfg, err := newTestConfig()
   135  	require.NoError(err)
   136  	registry := protocol.NewRegistry()
   137  	rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
   138  	require.NoError(rp.Register(registry))
   139  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
   140  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
   141  	require.NoError(err)
   142  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
   143  	require.NotNil(ap)
   144  	require.NoError(err)
   145  	store, err := filedao.NewFileDAOInMemForTest()
   146  	require.NoError(err)
   147  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, 16)
   148  	chain := blockchain.NewBlockchain(
   149  		cfg.Chain,
   150  		cfg.Genesis,
   151  		dao,
   152  		factory.NewMinter(sf, ap),
   153  	)
   154  	require.NotNil(chain)
   155  	require.NoError(chain.Start(ctx))
   156  	ctrl := gomock.NewController(t)
   157  	defer ctrl.Finish()
   158  	defer func() {
   159  		require.NoError(chain.Stop(ctx))
   160  	}()
   161  	ctx, err = chain.Context(ctx)
   162  	require.NoError(err)
   163  
   164  	b := blockBuffer{
   165  		blockQueues:  make(map[uint64]*uniQueue),
   166  		bufferSize:   16,
   167  		intervalSize: 8,
   168  	}
   169  
   170  	out := b.GetBlocksIntervalsToSync(chain.TipHeight(), 32)
   171  	require.Equal(2, len(out))
   172  	require.Equal(uint64(1), out[0].Start)
   173  	require.Equal(uint64(8), out[0].End)
   174  	require.Equal(uint64(9), out[1].Start)
   175  	require.Equal(uint64(16), out[1].End)
   176  
   177  	b.intervalSize = 16
   178  
   179  	out = b.GetBlocksIntervalsToSync(chain.TipHeight(), 32)
   180  	require.Equal(1, len(out))
   181  	require.Equal(uint64(1), out[0].Start)
   182  	require.Equal(uint64(16), out[0].End)
   183  
   184  	out = b.GetBlocksIntervalsToSync(chain.TipHeight(), 8)
   185  	require.Equal(1, len(out))
   186  	require.Equal(uint64(1), out[0].Start)
   187  	require.Equal(uint64(16), out[0].End)
   188  
   189  	b.intervalSize = 8
   190  
   191  	blk := block.NewBlockDeprecated(
   192  		uint32(123),
   193  		uint64(2),
   194  		hash.Hash256{},
   195  		testutil.TimestampNow(),
   196  		identityset.PrivateKey(27).PublicKey(),
   197  		nil,
   198  	)
   199  
   200  	pid := "peer1"
   201  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   202  	blk = block.NewBlockDeprecated(
   203  		uint32(123),
   204  		uint64(4),
   205  		blk.HashBlock(),
   206  		testutil.TimestampNow(),
   207  		identityset.PrivateKey(27).PublicKey(),
   208  		nil,
   209  	)
   210  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   211  	blk = block.NewBlockDeprecated(
   212  		uint32(123),
   213  		uint64(5),
   214  		blk.HashBlock(),
   215  		testutil.TimestampNow(),
   216  		identityset.PrivateKey(27).PublicKey(),
   217  		nil,
   218  	)
   219  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   220  	blk = block.NewBlockDeprecated(
   221  		uint32(123),
   222  		uint64(6),
   223  		blk.HashBlock(),
   224  		testutil.TimestampNow(),
   225  		identityset.PrivateKey(27).PublicKey(),
   226  		nil,
   227  	)
   228  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   229  	blk = block.NewBlockDeprecated(
   230  		uint32(123),
   231  		uint64(8),
   232  		blk.HashBlock(),
   233  		testutil.TimestampNow(),
   234  		identityset.PrivateKey(27).PublicKey(),
   235  		nil,
   236  	)
   237  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   238  	blk = block.NewBlockDeprecated(
   239  		uint32(123),
   240  		uint64(14),
   241  		blk.HashBlock(),
   242  		testutil.TimestampNow(),
   243  		identityset.PrivateKey(27).PublicKey(),
   244  		nil,
   245  	)
   246  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   247  	blk = block.NewBlockDeprecated(
   248  		uint32(123),
   249  		uint64(16),
   250  		blk.HashBlock(),
   251  		testutil.TimestampNow(),
   252  		identityset.PrivateKey(27).PublicKey(),
   253  		nil,
   254  	)
   255  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   256  	assert.Len(b.GetBlocksIntervalsToSync(chain.TipHeight(), 32), 5)
   257  	assert.Len(b.GetBlocksIntervalsToSync(chain.TipHeight(), 7), 3)
   258  
   259  	b.intervalSize = 4
   260  
   261  	assert.Len(b.GetBlocksIntervalsToSync(chain.TipHeight(), 5), 2)
   262  	assert.Len(b.GetBlocksIntervalsToSync(chain.TipHeight(), 1), 2)
   263  
   264  	blk, err = chain.MintNewBlock(testutil.TimestampNow())
   265  	require.NoError(err)
   266  	b.AddBlock(chain.TipHeight(), newPeerBlock(pid, blk))
   267  	// There should always have at least 1 interval range to sync
   268  	assert.Len(b.GetBlocksIntervalsToSync(chain.TipHeight(), 0), 1)
   269  }