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 }