diff --git a/common/constant/receipt.go b/common/constant/receipt.go index a431d3aab..eb5f7f6f8 100644 --- a/common/constant/receipt.go +++ b/common/constant/receipt.go @@ -15,7 +15,4 @@ const ( ReceiptBatchPickMultiplier = uint32(5) ReceiptHashSize = 32 // sha256 ReceiptGenerateMarkleRootPeriod = 20 * time.Second - // number of blocks to lookup for receipts before current height ( - // this is also the number of blocks to consider when selecting receipts to be included in a snapshot) - LinkedReceiptBlocksLimit = uint32(720) ) diff --git a/common/query/nodeRegistrationQuery.go b/common/query/nodeRegistrationQuery.go index 4526dd03c..8ca2de568 100644 --- a/common/query/nodeRegistrationQuery.go +++ b/common/query/nodeRegistrationQuery.go @@ -367,10 +367,23 @@ func (nrq *NodeRegistrationQuery) Scan(nr *model.NodeRegistration, row *sql.Row) return nil } +// SelectDataForSnapshot this query selects only node registry latest state from height 0 to 'fromHeight' ( +// excluded) and all records from 'fromHeight' to 'toHeight', +// removing from first selection records that have duplicate ids with second second selection. +// This way we make sure only one version of every id has 'latest' field set to true func (nrq *NodeRegistrationQuery) SelectDataForSnapshot(fromHeight, toHeight uint32) string { - return fmt.Sprintf("SELECT %s FROM %s WHERE (id, height) IN (SELECT t2.id, MAX("+ - "t2.height) FROM %s as t2 WHERE height >= %d AND height <= %d GROUP BY t2.id) ORDER BY height", - strings.Join(nrq.Fields, ","), nrq.getTableName(), nrq.getTableName(), fromHeight, toHeight) + if fromHeight > 0 { + return fmt.Sprintf("SELECT %s FROM %s WHERE (id, height) IN (SELECT t2.id, "+ + "MAX(t2.height) FROM %s as t2 WHERE t2.height >= 0 AND t2.height < %d GROUP BY t2.id) "+ + "AND id NOT IN (SELECT DISTINCT t3.id FROM %s as t3 WHERE t3.height >= %d AND t3.height < %d) "+ + "UNION ALL SELECT %s FROM %s WHERE height >= %d AND height <= %d "+ + "ORDER BY height, id", + strings.Join(nrq.Fields, ","), nrq.getTableName(), nrq.getTableName(), fromHeight, + nrq.getTableName(), fromHeight, toHeight, + strings.Join(nrq.Fields, ","), nrq.getTableName(), fromHeight, toHeight) + } + return fmt.Sprintf("SELECT %s FROM %s WHERE height >= %d AND height <= %d ORDER BY height, id", + strings.Join(nrq.Fields, ","), nrq.getTableName(), fromHeight, toHeight) } // TrimDataBeforeSnapshot delete entries to assure there are no duplicates before applying a snapshot diff --git a/common/query/nodeRegistrationQuery_test.go b/common/query/nodeRegistrationQuery_test.go index 901839462..246fe3132 100644 --- a/common/query/nodeRegistrationQuery_test.go +++ b/common/query/nodeRegistrationQuery_test.go @@ -437,18 +437,6 @@ func TestNodeRegistrationQuery_InsertNodeRegistration(t *testing.T) { }) } -func TestNodeRegistrationQuery_SelectDataForSnapshot(t *testing.T) { - t.Run("GetActiveNodeRegistrations", func(t *testing.T) { - res := mockNodeRegistrationQuery.SelectDataForSnapshot(0, 10) - want := "SELECT id,node_public_key,account_address,registration_height,node_address,locked_balance,registration_status,latest," + - "height FROM node_registry WHERE (id, height) IN (SELECT t2.id, " + - "MAX(t2.height) FROM node_registry as t2 WHERE height >= 0 AND height <= 10 GROUP BY t2.id) ORDER BY height" - if res != want { - t.Errorf("string not match:\nget: %s\nwant: %s", res, want) - } - }) -} - func TestNodeRegistrationQuery_TrimDataBeforeSnapshot(t *testing.T) { t.Run("TrimDataBeforeSnapshot:success", func(t *testing.T) { res := mockNodeRegistrationQuery.TrimDataBeforeSnapshot(0, 10) @@ -458,3 +446,62 @@ func TestNodeRegistrationQuery_TrimDataBeforeSnapshot(t *testing.T) { } }) } + +func TestNodeRegistrationQuery_SelectDataForSnapshot(t *testing.T) { + type fields struct { + Fields []string + TableName string + } + type args struct { + fromHeight uint32 + toHeight uint32 + } + tests := []struct { + name string + fields fields + args args + want string + }{ + { + name: "SelectDataForSnapshot:success-{fromGenesis}", + fields: fields{ + TableName: NewNodeRegistrationQuery().TableName, + Fields: NewNodeRegistrationQuery().Fields, + }, + args: args{ + fromHeight: 0, + toHeight: 10, + }, + want: "SELECT id,node_public_key,account_address,registration_height,node_address,locked_balance,registration_status,latest," + + "height FROM node_registry WHERE height >= 0 AND height <= 10 ORDER BY height, id", + }, + { + name: "SelectDataForSnapshot:success-{fromArbitraryHeight}", + fields: fields{ + TableName: NewNodeRegistrationQuery().TableName, + Fields: NewNodeRegistrationQuery().Fields, + }, + args: args{ + fromHeight: 720, + toHeight: 1440, + }, + want: "SELECT id,node_public_key,account_address,registration_height,node_address,locked_balance,registration_status,latest," + + "height FROM node_registry WHERE (id, height) IN (SELECT t2.id, MAX(t2.height) FROM node_registry as t2 WHERE t2." + + "height >= 0 AND t2.height < 720 GROUP BY t2.id) AND id NOT IN (SELECT DISTINCT t3.id FROM node_registry as t3 WHERE t3." + + "height >= 720 AND t3.height < 1440) UNION ALL SELECT id,node_public_key,account_address,registration_height,node_address," + + "locked_balance,registration_status,latest," + + "height FROM node_registry WHERE height >= 720 AND height <= 1440 ORDER BY height, id", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + nrq := &NodeRegistrationQuery{ + Fields: tt.fields.Fields, + TableName: tt.fields.TableName, + } + if got := nrq.SelectDataForSnapshot(tt.args.fromHeight, tt.args.toHeight); got != tt.want { + t.Errorf("NodeRegistrationQuery.SelectDataForSnapshot() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/common/query/query.go b/common/query/query.go index 8a3c61926..155c3029a 100644 --- a/common/query/query.go +++ b/common/query/query.go @@ -47,7 +47,7 @@ func GetDerivedQuery(ct chaintype.ChainType) (derivedQuery []DerivedQuery) { return derivedQuery } -// GetSnapshotQuery func to get all query repos that have a SelectDataForSnapshot method +// GetSnapshotQuery func to get all query repos that have a SelectDataForSnapshot method (that have data to be included in snapshots) func GetSnapshotQuery(ct chaintype.ChainType) (snapshotQuery map[string]SnapshotQuery) { switch ct.(type) { case *chaintype.MainChain: @@ -69,3 +69,19 @@ func GetSnapshotQuery(ct chaintype.ChainType) (snapshotQuery map[string]Snapshot } return snapshotQuery } + +// GetBlocksmithSafeQuery func to get all query repos that must save their full history in snapshots, +// for a minRollbackHeight number of blocks, to not break blocksmith process logic +func GetBlocksmithSafeQuery(ct chaintype.ChainType) (snapshotQuery map[string]bool) { + switch ct.(type) { + case *chaintype.MainChain: + snapshotQuery = map[string]bool{ + "block": true, + "nodeRegistration": true, + "publishedReceipt": true, + } + default: + snapshotQuery = map[string]bool{} + } + return snapshotQuery +} diff --git a/core/blockchainsync/blockchainOrchestratorService.go b/core/blockchainsync/blockchainOrchestratorService.go index c0e856b5f..9c216fe5c 100644 --- a/core/blockchainsync/blockchainOrchestratorService.go +++ b/core/blockchainsync/blockchainOrchestratorService.go @@ -1,7 +1,6 @@ package blockchainsync import ( - "errors" "fmt" "time" @@ -31,8 +30,7 @@ type ( // of the blockchains so that the expected behavior is consistent within the application. // In the future, this service may also be expanded to orchestrate the smithing activity of the blockchains func NewBlockchainOrchestratorService( - spinechainSyncService BlockchainSyncServiceInterface, - mainchainSyncService BlockchainSyncServiceInterface, + spinechainSyncService, mainchainSyncService BlockchainSyncServiceInterface, blockchainStatusService service.BlockchainStatusServiceInterface, spineBlockManifestService service.SpineBlockManifestServiceInterface, fileDownloader p2p.FileDownloaderInterface, @@ -110,12 +108,10 @@ func (bos *BlockchainOrchestratorService) DownloadSnapshot(ct chaintype.ChainTyp if err != nil { bos.Logger.Warning(err) return err - } else { - if err := bos.MainchainSnapshotBlockServices.ImportSnapshotFile(snapshotFileInfo); err != nil { - bos.Logger.Warningf("error importing snapshot file for chaintype %s at height %d: %s\n", ct.GetName(), - lastSpineBlockManifest.SpineBlockManifestHeight, err.Error()) - return err - } + } else if err := bos.MainchainSnapshotBlockServices.ImportSnapshotFile(snapshotFileInfo); err != nil { + bos.Logger.Warningf("error importing snapshot file for chaintype %s at height %d: %s\n", ct.GetName(), + lastSpineBlockManifest.SpineBlockManifestHeight, err.Error()) + return err } } @@ -133,7 +129,7 @@ func (bos *BlockchainOrchestratorService) Start() error { lastMainBlock, err := bos.MainchainSyncService.GetBlockService().GetLastBlock() if err != nil { - return errors.New(fmt.Sprintf("cannot get last main block: %s", err.Error())) + return fmt.Errorf("cannot get last main block: %s", err.Error()) } if lastMainBlock.Height == 0 && bos.MainchainSyncService.GetBlockService().GetChainType().HasSnapshots() { diff --git a/core/blockchainsync/blockchainOrchestratorService_test.go b/core/blockchainsync/blockchainOrchestratorService_test.go index 64fc2e963..6f357d8a5 100644 --- a/core/blockchainsync/blockchainOrchestratorService_test.go +++ b/core/blockchainsync/blockchainOrchestratorService_test.go @@ -68,15 +68,18 @@ type ( } ) -func (*MockSpineBlockManifestServiceError) GetLastSpineBlockManifest(ct chaintype.ChainType, mbType model.SpineBlockManifestType) (*model.SpineBlockManifest, error) { +func (*MockSpineBlockManifestServiceError) GetLastSpineBlockManifest(ct chaintype.ChainType, + mbType model.SpineBlockManifestType) (*model.SpineBlockManifest, error) { return nil, errors.New("GetLastSpineBlockManifest error") } -func (*MockSpineBlockManifestServiceSuccessNoSpineBlockManifest) GetLastSpineBlockManifest(ct chaintype.ChainType, mbType model.SpineBlockManifestType) (*model.SpineBlockManifest, error) { +func (*MockSpineBlockManifestServiceSuccessNoSpineBlockManifest) GetLastSpineBlockManifest(ct chaintype.ChainType, + mbType model.SpineBlockManifestType) (*model.SpineBlockManifest, error) { return nil, nil } -func (*MockSpineBlockManifestServiceSuccessWithSpineBlockManifest) GetLastSpineBlockManifest(ct chaintype.ChainType, mbType model.SpineBlockManifestType) (*model.SpineBlockManifest, error) { +func (*MockSpineBlockManifestServiceSuccessWithSpineBlockManifest) GetLastSpineBlockManifest(ct chaintype.ChainType, + mbType model.SpineBlockManifestType) (*model.SpineBlockManifest, error) { return &model.SpineBlockManifest{}, nil } @@ -116,11 +119,13 @@ func (*MockBlockServiceSuccess) GetLastBlock() (*model.Block, error) { return &model.Block{}, nil } -func (*MockFileDownloaderError) DownloadSnapshot(ct chaintype.ChainType, spineBlockManifest *model.SpineBlockManifest) (*model.SnapshotFileInfo, error) { +func (*MockFileDownloaderError) DownloadSnapshot(ct chaintype.ChainType, spineBlockManifest *model.SpineBlockManifest) (*model. + SnapshotFileInfo, error) { return nil, errors.New("DownloadSnapshot error") } -func (*MockFileDownloaderSuccess) DownloadSnapshot(ct chaintype.ChainType, spineBlockManifest *model.SpineBlockManifest) (*model.SnapshotFileInfo, error) { +func (*MockFileDownloaderSuccess) DownloadSnapshot(ct chaintype.ChainType, spineBlockManifest *model.SpineBlockManifest) (*model. + SnapshotFileInfo, error) { return &model.SnapshotFileInfo{}, nil } @@ -248,7 +253,7 @@ func TestBlockchainOrchestratorService_DownloadSnapshot(t *testing.T) { MainchainSnapshotBlockServices: tt.fields.MainchainSnapshotBlockServices, Logger: tt.fields.Logger, } - bos.DownloadSnapshot(tt.args.ct) + _ = bos.DownloadSnapshot(tt.args.ct) if err := bos.DownloadSnapshot(tt.args.ct); (err != nil) != tt.wantErr { t.Errorf("BlockchainOrchestratorService.DownloadSnapshot() error = %v, wantErr %v", err, tt.wantErr) } diff --git a/core/service/blockMainService_test.go b/core/service/blockMainService_test.go index af7a747bd..4da96e5f2 100644 --- a/core/service/blockMainService_test.go +++ b/core/service/blockMainService_test.go @@ -885,7 +885,8 @@ func (*mockBlocksmithServicePushBlock) GetSortedBlocksmithsMap(*model.Block) map func (*mockBlocksmithServicePushBlock) SortBlocksmiths(block *model.Block, withLock bool) { } -func (*mockBlocksmithServicePushBlock) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, currentBlock *model.Block) error { +func (*mockBlocksmithServicePushBlock) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, + currentBlock *model.Block) error { return nil } @@ -2702,7 +2703,8 @@ func (*mockBlocksmithServiceReceiveBlock) GetSortedBlocksmithsMap(block *model.B } } -func (*mockBlocksmithServiceReceiveBlock) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, currentBlock *model.Block) error { +func (*mockBlocksmithServiceReceiveBlock) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, + currentBlock *model.Block) error { return nil } @@ -2729,7 +2731,11 @@ func (*mockQueryExecutorReceiveBlockFail) ExecuteSelectRow(qStr string, tx bool, return db.QueryRow(qStr), nil } -func (bss *mockBlocksmithServiceReceiveBlock) IsValidSmithTime(blocksmithIndex int64, numberOfBlocksmiths int64, previousBlock *model.Block) error { +func (bss *mockBlocksmithServiceReceiveBlock) IsValidSmithTime( + blocksmithIndex, + numberOfBlocksmiths int64, + previousBlock *model.Block, +) error { return nil } @@ -3620,11 +3626,13 @@ func (*mockBlocksmithServiceValidateBlockSuccess) GetSortedBlocksmithsMap(*model } } -func (*mockBlocksmithServiceValidateBlockSuccess) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, currentBlock *model.Block) error { +func (*mockBlocksmithServiceValidateBlockSuccess) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, + currentBlock *model.Block) error { return nil } -func (*mockBlocksmithServiceValidateBlockSuccess) IsValidSmithTime(blocksmithIndex int64, numberOfBlocksmiths int64, previousBlock *model.Block) error { +func (*mockBlocksmithServiceValidateBlockSuccess) IsValidSmithTime(blocksmithIndex, numberOfBlocksmiths int64, + previousBlock *model.Block) error { return nil } @@ -4490,7 +4498,8 @@ func (*mockBlocksmithServiceProcessQueued) GetSortedBlocksmithsMap(block *model. func (*mockBlocksmithServiceProcessQueued) SortBlocksmiths(block *model.Block, withLock bool) { } -func (*mockBlocksmithServiceProcessQueued) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, currentBlock *model.Block) error { +func (*mockBlocksmithServiceProcessQueued) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, + currentBlock *model.Block) error { return nil } diff --git a/core/service/blockSpineService_test.go b/core/service/blockSpineService_test.go index 1b07b10d0..fb905ba2c 100644 --- a/core/service/blockSpineService_test.go +++ b/core/service/blockSpineService_test.go @@ -801,7 +801,8 @@ func (*mockSpineBlocksmithServicePushBlock) GetSortedBlocksmithsMap(*model.Block } func (*mockSpineBlocksmithServicePushBlock) SortBlocksmiths(block *model.Block, withLock bool) { } -func (*mockSpineBlocksmithServicePushBlock) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, currentBlock *model.Block) error { +func (*mockSpineBlocksmithServicePushBlock) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, + currentBlock *model.Block) error { return nil } func TestBlockSpineService_PushBlock(t *testing.T) { @@ -2843,7 +2844,8 @@ func (*mockSpineBlocksmithServiceValidateBlockSuccess) GetSortedBlocksmithsMap(* string(mockSpineBlockData.BlocksmithPublicKey): &secondIndex, } } -func (*mockSpineBlocksmithServiceValidateBlockSuccess) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, currentBlock *model.Block) error { +func (*mockSpineBlocksmithServiceValidateBlockSuccess) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, + currentBlock *model.Block) error { return nil } diff --git a/core/service/snapshotMainBlockService.go b/core/service/snapshotMainBlockService.go index abe3bfce7..a2277dfe1 100644 --- a/core/service/snapshotMainBlockService.go +++ b/core/service/snapshotMainBlockService.go @@ -31,6 +31,7 @@ type ( SkippedBlocksmithQuery query.SkippedBlocksmithQueryInterface BlockQuery query.BlockQueryInterface SnapshotQueries map[string]query.SnapshotQuery + BlocksmithSafeQuery map[string]bool DerivedQueries []query.DerivedQuery } ) @@ -52,6 +53,7 @@ func NewSnapshotMainBlockService( skippedBlocksmithQuery query.SkippedBlocksmithQueryInterface, blockQuery query.BlockQueryInterface, snapshotQueries map[string]query.SnapshotQuery, + blocksmithSafeQueries map[string]bool, derivedQueries []query.DerivedQuery, ) *SnapshotMainBlockService { return &SnapshotMainBlockService{ @@ -72,6 +74,7 @@ func NewSnapshotMainBlockService( SkippedBlocksmithQuery: skippedBlocksmithQuery, BlockQuery: blockQuery, SnapshotQueries: snapshotQueries, + BlocksmithSafeQuery: blocksmithSafeQueries, DerivedQueries: derivedQueries, } } @@ -99,15 +102,11 @@ func (ss *SnapshotMainBlockService) NewSnapshotFile(block *model.Block) (snapsho fromHeight uint32 rows *sql.Rows ) - if qryRepoName == "block" { - if snapshotPayloadHeight > constant.MinRollbackBlocks { - fromHeight = snapshotPayloadHeight - constant.MinRollbackBlocks - } - } - if qryRepoName == "publishedReceipt" { - if snapshotPayloadHeight > constant.LinkedReceiptBlocksLimit { - fromHeight = snapshotPayloadHeight - constant.LinkedReceiptBlocksLimit - } + // if current query repo is blocksmith safe, + // include more blocks to make sure we don't break smithing process due to missing data such as blocks, + // published receipts and node registrations + if ss.BlocksmithSafeQuery[qryRepoName] && snapshotPayloadHeight > constant.MinRollbackBlocks { + fromHeight = snapshotPayloadHeight - constant.MinRollbackBlocks } qry := snapshotQuery.SelectDataForSnapshot(fromHeight, snapshotPayloadHeight) rows, err = ss.QueryExecutor.ExecuteSelect(qry, false) diff --git a/core/service/snapshotMainBlockService_test.go b/core/service/snapshotMainBlockService_test.go index 925dd0f42..45aeb8bcf 100644 --- a/core/service/snapshotMainBlockService_test.go +++ b/core/service/snapshotMainBlockService_test.go @@ -467,6 +467,8 @@ func TestSnapshotMainBlockService_NewSnapshotFile(t *testing.T) { SkippedBlocksmithQuery query.SkippedBlocksmithQueryInterface BlockQuery query.BlockQueryInterface SnapshotQueries map[string]query.SnapshotQuery + BlocksmithSafeQuery map[string]bool + DerivedQueries []query.DerivedQuery } type args struct { block *model.Block @@ -503,6 +505,8 @@ func TestSnapshotMainBlockService_NewSnapshotFile(t *testing.T) { SkippedBlocksmithQuery: &mockSkippedBlocksmithQuery{success: true}, BlockQuery: &mockSnapshotBlockQuery{success: true}, SnapshotQueries: query.GetSnapshotQuery(chaintype.GetChainType(0)), + BlocksmithSafeQuery: query.GetBlocksmithSafeQuery(chaintype.GetChainType(0)), + DerivedQueries: query.GetDerivedQuery(chaintype.GetChainType(0)), }, args: args{ block: blockForSnapshot1, @@ -540,6 +544,8 @@ func TestSnapshotMainBlockService_NewSnapshotFile(t *testing.T) { SkippedBlocksmithQuery: tt.fields.SkippedBlocksmithQuery, BlockQuery: tt.fields.BlockQuery, SnapshotQueries: tt.fields.SnapshotQueries, + BlocksmithSafeQuery: tt.fields.BlocksmithSafeQuery, + DerivedQueries: tt.fields.DerivedQueries, } got, err := ss.NewSnapshotFile(tt.args.block) if err != nil { @@ -582,6 +588,7 @@ func TestSnapshotMainBlockService_Integration_NewSnapshotFile(t *testing.T) { SkippedBlocksmithQuery query.SkippedBlocksmithQueryInterface BlockQuery query.BlockQueryInterface SnapshotQueries map[string]query.SnapshotQuery + BlocksmithSafeQuery map[string]bool DerivedQueries []query.DerivedQuery } type args struct { @@ -623,6 +630,7 @@ func TestSnapshotMainBlockService_Integration_NewSnapshotFile(t *testing.T) { BlockQuery: &mockSnapshotBlockQuery{success: true}, SnapshotQueries: query.GetSnapshotQuery(chaintype.GetChainType(0)), DerivedQueries: query.GetDerivedQuery(chaintype.GetChainType(0)), + BlocksmithSafeQuery: query.GetBlocksmithSafeQuery(chaintype.GetChainType(0)), }, args: args{ block: blockForSnapshot1, @@ -659,6 +667,7 @@ func TestSnapshotMainBlockService_Integration_NewSnapshotFile(t *testing.T) { BlockQuery: &mockSnapshotBlockQuery{success: true}, SnapshotQueries: query.GetSnapshotQuery(chaintype.GetChainType(0)), DerivedQueries: query.GetDerivedQuery(chaintype.GetChainType(0)), + BlocksmithSafeQuery: query.GetBlocksmithSafeQuery(chaintype.GetChainType(0)), }, args: args{ block: blockForSnapshot1, @@ -687,6 +696,7 @@ func TestSnapshotMainBlockService_Integration_NewSnapshotFile(t *testing.T) { BlockQuery: tt.fields.BlockQuery, SnapshotQueries: tt.fields.SnapshotQueries, DerivedQueries: tt.fields.DerivedQueries, + BlocksmithSafeQuery: tt.fields.BlocksmithSafeQuery, } got, err := ss.NewSnapshotFile(tt.args.block) if err != nil { @@ -743,6 +753,7 @@ func TestSnapshotMainBlockService_ImportSnapshotFile(t *testing.T) { SkippedBlocksmithQuery query.SkippedBlocksmithQueryInterface BlockQuery query.BlockQueryInterface SnapshotQueries map[string]query.SnapshotQuery + BlocksmithSafeQuery map[string]bool DerivedQueries []query.DerivedQuery } tests := []struct { @@ -775,6 +786,7 @@ func TestSnapshotMainBlockService_ImportSnapshotFile(t *testing.T) { SkippedBlocksmithQuery: query.NewSkippedBlocksmithQuery(), BlockQuery: query.NewBlockQuery(&chaintype.MainChain{}), SnapshotQueries: query.GetSnapshotQuery(chaintype.GetChainType(0)), + BlocksmithSafeQuery: query.GetBlocksmithSafeQuery(chaintype.GetChainType(0)), DerivedQueries: query.GetDerivedQuery(chaintype.GetChainType(0)), }, }, @@ -799,6 +811,7 @@ func TestSnapshotMainBlockService_ImportSnapshotFile(t *testing.T) { SkippedBlocksmithQuery: tt.fields.SkippedBlocksmithQuery, BlockQuery: tt.fields.BlockQuery, SnapshotQueries: tt.fields.SnapshotQueries, + BlocksmithSafeQuery: tt.fields.BlocksmithSafeQuery, DerivedQueries: tt.fields.DerivedQueries, } snapshotFileInfo, err := ss.NewSnapshotFile(blockForSnapshot1) diff --git a/core/smith/strategy/blocksmithStrategyMain.go b/core/smith/strategy/blocksmithStrategyMain.go index 9246a0666..d826817d7 100644 --- a/core/smith/strategy/blocksmithStrategyMain.go +++ b/core/smith/strategy/blocksmithStrategyMain.go @@ -164,7 +164,9 @@ func (bss *BlocksmithStrategyMain) EstimateLastBlockPersistedTime( return nil, err } defer skippedBlocksmithsRows.Close() - bss.SkippedBlocksmithQuery.BuildModel(skippedBlocksmiths, skippedBlocksmithsRows) + if _, err := bss.SkippedBlocksmithQuery.BuildModel(skippedBlocksmiths, skippedBlocksmithsRows); err != nil { + return nil, err + } return skippedBlocksmiths, nil }() if err != nil { @@ -184,7 +186,8 @@ func (bss *BlocksmithStrategyMain) EstimateLastBlockPersistedTime( // IsBlockTimestampValid check if the block provided (currentBlock) has valid timestamp based on the previous block // of the current node. This function is save to be called on download process, it does not make use of node current time. -func (bss *BlocksmithStrategyMain) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, currentBlock *model.Block) error { +func (bss *BlocksmithStrategyMain) IsBlockTimestampValid(blocksmithIndex, numberOfBlocksmiths int64, previousBlock, + currentBlock *model.Block) error { var ( err error ct = &chaintype.MainChain{} diff --git a/core/smith/strategy/blocksmithStrategyMain_test.go b/core/smith/strategy/blocksmithStrategyMain_test.go index e0c6b4202..8acd6b31a 100644 --- a/core/smith/strategy/blocksmithStrategyMain_test.go +++ b/core/smith/strategy/blocksmithStrategyMain_test.go @@ -517,7 +517,8 @@ func TestBlocksmithStrategyMain_IsBlockTimestampValid(t *testing.T) { SortedBlocksmithsLock: tt.fields.SortedBlocksmithsLock, SortedBlocksmithsMap: tt.fields.SortedBlocksmithsMap, } - if err := bss.IsBlockTimestampValid(tt.args.blocksmithIndex, tt.args.numberOfBlocksmiths, tt.args.previousBlock, tt.args.currentBlock); (err != nil) != tt.wantErr { + if err := bss.IsBlockTimestampValid(tt.args.blocksmithIndex, tt.args.numberOfBlocksmiths, tt.args.previousBlock, + tt.args.currentBlock); (err != nil) != tt.wantErr { t.Errorf("IsBlockTimestampValid() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/core/smith/strategy/blocksmithStrategySpine.go b/core/smith/strategy/blocksmithStrategySpine.go index f396ce8e5..93bb68b55 100644 --- a/core/smith/strategy/blocksmithStrategySpine.go +++ b/core/smith/strategy/blocksmithStrategySpine.go @@ -203,7 +203,7 @@ func (*BlocksmithStrategySpine) CanPersistBlock( return nil } -func (bss *BlocksmithStrategySpine) IsValidSmithTime(blocksmithIndex int64, numberOfBlocksmiths int64, previousBlock *model.Block) error { +func (bss *BlocksmithStrategySpine) IsValidSmithTime(blocksmithIndex, numberOfBlocksmiths int64, previousBlock *model.Block) error { var ( currentTime = time.Now().Unix() ct = &chaintype.MainChain{} diff --git a/core/smith/strategy/blocksmithStrategySpine_test.go b/core/smith/strategy/blocksmithStrategySpine_test.go index 93e7e987c..dc818a00a 100644 --- a/core/smith/strategy/blocksmithStrategySpine_test.go +++ b/core/smith/strategy/blocksmithStrategySpine_test.go @@ -685,7 +685,8 @@ func TestBlocksmithStrategySpine_IsBlockTimestampValid(t *testing.T) { SortedBlocksmithsMap: tt.fields.SortedBlocksmithsMap, SpineBlockQuery: tt.fields.SpineBlockQuery, } - if err := bss.IsBlockTimestampValid(tt.args.blocksmithIndex, tt.args.numberOfBlocksmiths, tt.args.previousBlock, tt.args.currentBlock); (err != nil) != tt.wantErr { + if err := bss.IsBlockTimestampValid(tt.args.blocksmithIndex, tt.args.numberOfBlocksmiths, tt.args.previousBlock, + tt.args.currentBlock); (err != nil) != tt.wantErr { t.Errorf("IsBlockTimestampValid() error = %v, wantErr %v", err, tt.wantErr) } }) diff --git a/main.go b/main.go index 96c6559ff..989953c4c 100644 --- a/main.go +++ b/main.go @@ -88,7 +88,6 @@ var ( receiptUtil = &coreUtil.ReceiptUtil{} transactionCoreServiceIns service.TransactionCoreServiceInterface fileService service.FileServiceInterface - chainTypes = chaintype.GetChainTypes() mainchain = &chaintype.MainChain{} spinechain = &chaintype.SpineChain{} blockchainStatusService service.BlockchainStatusServiceInterface @@ -200,6 +199,7 @@ func init() { query.NewSkippedBlocksmithQuery(), query.NewBlockQuery(mainchain), query.GetSnapshotQuery(mainchain), + query.GetBlocksmithSafeQuery(mainchain), query.GetDerivedQuery(mainchain), )