Skip to content

Fix manifest rollback #773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Apr 23, 2020
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
660997e
add spineblock height field
andy-shi88 Apr 20, 2020
4e4b6bf
rename spine block manifest column and add indesx on block height column
andy-shi88 Apr 21, 2020
880f220
rename spine_block_manifest column field
andy-shi88 Apr 21, 2020
9d01d6d
move spine_block_manifest to spinechain derived query category
andy-shi88 Apr 21, 2020
255592d
clean snapshot file on rollbacked
andy-shi88 Apr 21, 2020
68c9bda
add delete snapshot file function
andy-shi88 Apr 21, 2020
71f021d
update tests
andy-shi88 Apr 21, 2020
073038d
remove ErrNoRows check as that error only occur on sql.Row not sql.Rows
andy-shi88 Apr 21, 2020
87c7256
inject snapshot block service to spine block service
andy-shi88 Apr 21, 2020
958f730
snapshot manifest field rename
andy-shi88 Apr 21, 2020
0d533d3
fix new rollback query for manifest
andy-shi88 Apr 23, 2020
74534d0
use parse instead of splitting chunks manually
andy-shi88 Apr 23, 2020
70c58f5
log the deletion error
andy-shi88 Apr 23, 2020
4b9540f
handle error
andy-shi88 Apr 23, 2020
9b57d80
update schema
andy-shi88 Apr 23, 2020
2fe0d73
Merge branch 'develop' of github.com:zoobc/zoobc-core into fix-manife…
andy-shi88 Apr 23, 2020
efe139c
Merge branch 'develop' into fix-manifest-rollbacl-reset-db
capt4ce Apr 23, 2020
3fe4829
add extra comment for testing
andy-shi88 Apr 23, 2020
44cd860
Merge branch 'fix-manifest-rollbacl-reset-db' of github.com:andy-shi8…
andy-shi88 Apr 23, 2020
0692cef
move file deletion to after db commit and as goroutine
andy-shi88 Apr 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common/constant/blockchainSync.go
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ const (
PeerGetBlocksLimit uint32 = 1440
CommonMilestoneBlockIdsLimit int32 = 10
SafeBlockGap = MinRollbackBlocks / 2
// @iltoga change this to 2 for testing snapshots
// @iltoga change this to 2 for testing snapshots to maintain functionality keep this value above PriorityStrategyBuildScrambleNodesGap
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

MinRollbackBlocks uint32 = 720 // production 720
MaxCommonMilestoneRequestTrial = MinRollbackBlocks/uint32(CommonMilestoneBlockIdsLimit) + 1
MinimumPeersBlocksToDownload int32 = 2
9 changes: 8 additions & 1 deletion common/database/migration.go
Original file line number Diff line number Diff line change
@@ -269,9 +269,10 @@ func (m *Migration) Init() error {
"full_file_hash" BLOB, -- hash of the (snapshot) file content
"file_chunk_hashes" BLOB, -- sorted sequence file chunks hashes referenced by the spine_block_manifest
"manifest_reference_height" INTEGER NOT NULL, -- height at which the snapshot was taken on the (main)chain
"manifest_spine_block_height" INTEGER NOT NULL, -- height at which the snapshot was taken on the (main)chain
"chain_type" INTEGER NOT NULL, -- chain type this spine_block_manifest reference to
"manifest_type" INTEGER NOT NULL, -- type of spine_block_manifest (as of now only snapshot)
"manifest_timestamp" INTEGER NOT NULL, -- timestamp that marks the end of file chunks processing
"expiration_timestamp" INTEGER NOT NULL, -- timestamp that marks the end of file chunks processing
PRIMARY KEY("id")
UNIQUE("id")
)
@@ -345,6 +346,12 @@ func (m *Migration) Init() error {
`
CREATE INDEX "published_receipt_datum_hash_idx" ON "published_receipt" ("datum_hash")
`,
`
CREATE INDEX "spine_block_manifest_spine_block_height_idx" ON "spine_block_manifest" ("manifest_spine_block_height")
`,
`
CREATE INDEX "spine_block_manifest_reference_height_idx" ON "spine_block_manifest" ("manifest_reference_height")
`,
}
return nil
}
64 changes: 38 additions & 26 deletions common/model/spineBlockManifest.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion common/query/query.go
Original file line number Diff line number Diff line change
@@ -35,12 +35,12 @@ func GetDerivedQuery(ct chaintype.ChainType) (derivedQuery []DerivedQuery) {
NewPendingTransactionQuery(),
NewPendingSignatureQuery(),
NewMultisignatureInfoQuery(),
NewSpineBlockManifestQuery(),
}
derivedQuery = append(derivedQuery, mainchainDerivedQuery...)
case *chaintype.SpineChain:
spinechainDerivedQuery := []DerivedQuery{
NewSpinePublicKeyQuery(),
NewSpineBlockManifestQuery(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
derivedQuery = append(derivedQuery, spinechainDerivedQuery...)
}
2 changes: 1 addition & 1 deletion common/query/query_test.go
Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@ func TestGetDerivedQuery(t *testing.T) {
NewPendingTransactionQuery(),
NewPendingSignatureQuery(),
NewMultisignatureInfoQuery(),
NewSpineBlockManifestQuery(),
},
},
{
@@ -45,6 +44,7 @@ func TestGetDerivedQuery(t *testing.T) {
want: []DerivedQuery{
NewBlockQuery(spinechain),
NewSpinePublicKeyQuery(),
NewSpineBlockManifestQuery(),
},
},
}
35 changes: 27 additions & 8 deletions common/query/spineBlockManifestQuery.go
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ package query
import (
"database/sql"
"fmt"
"github.com/zoobc/zoobc-core/common/constant"
"strings"

"github.com/zoobc/zoobc-core/common/chaintype"
@@ -15,6 +14,8 @@ type (
SpineBlockManifestQueryInterface interface {
InsertSpineBlockManifest(spineBlockManifest *model.SpineBlockManifest) (str string, args []interface{})
GetSpineBlockManifestTimeInterval(fromTimestamp, toTimestamp int64) string
GetManifestBySpineBlockHeight(spineBlockHeight uint32) string
GetManifestsFromSpineBlockHeight(spineBlockHeight uint32) string
GetLastSpineBlockManifest(ct chaintype.ChainType, mbType model.SpineBlockManifestType) string
ExtractModel(mb *model.SpineBlockManifest) []interface{}
BuildModel(spineBlockManifests []*model.SpineBlockManifest, rows *sql.Rows) ([]*model.SpineBlockManifest, error)
@@ -34,9 +35,10 @@ func NewSpineBlockManifestQuery() *SpineBlockManifestQuery {
"full_file_hash",
"file_chunk_hashes",
"manifest_reference_height",
"manifest_spine_block_height",
"chain_type",
"manifest_type",
"manifest_timestamp",
"expiration_timestamp",
},
TableName: "spine_block_manifest",
}
@@ -72,19 +74,34 @@ func (mbl *SpineBlockManifestQuery) GetLastSpineBlockManifest(ct chaintype.Chain
// GetSpineBlockManifestTimeInterval retrieve all spineBlockManifests within a time frame
// Note: it is used to get all entities that have expired between spine blocks
func (mbl *SpineBlockManifestQuery) GetSpineBlockManifestTimeInterval(fromTimestamp, toTimestamp int64) string {
query := fmt.Sprintf("SELECT %s FROM %s WHERE manifest_timestamp > %d AND manifest_timestamp <= %d "+
query := fmt.Sprintf("SELECT %s FROM %s WHERE expiration_timestamp > %d AND expiration_timestamp <= %d "+
"ORDER BY manifest_type, chain_type, manifest_reference_height",
strings.Join(mbl.Fields, ", "), mbl.getTableName(), fromTimestamp, toTimestamp)
return query
}

// GetManifestBySpineBlockHeight retrieve manifests of binded to a spineblock height
func (mbl *SpineBlockManifestQuery) GetManifestBySpineBlockHeight(spineBlockHeight uint32) string {
query := fmt.Sprintf("SELECT %s FROM %s WHERE manifest_spine_block_height = %d "+
"ORDER BY manifest_type, chain_type, manifest_reference_height",
strings.Join(mbl.Fields, ", "), mbl.getTableName(), spineBlockHeight)
return query
}

func (mbl *SpineBlockManifestQuery) GetManifestsFromSpineBlockHeight(spineBlockHeight uint32) string {
query := fmt.Sprintf("SELECT %s FROM %s WHERE manifest_spine_block_height > %d ",
strings.Join(mbl.Fields, ", "), mbl.getTableName(), spineBlockHeight)
return query
}

// ExtractModel extract the model struct fields to the order of SpineBlockManifestQuery.Fields
func (mbl *SpineBlockManifestQuery) ExtractModel(mb *model.SpineBlockManifest) []interface{} {
return []interface{}{
mb.ID,
mb.FullFileHash,
mb.FileChunkHashes,
mb.SpineBlockManifestHeight,
mb.ManifestReferenceHeight,
mb.ManifestSpineBlockHeight,
mb.ChainType,
mb.SpineBlockManifestType,
mb.ExpirationTimestamp,
@@ -106,7 +123,8 @@ func (mbl *SpineBlockManifestQuery) BuildModel(
&mb.ID,
&mb.FullFileHash,
&mb.FileChunkHashes,
&mb.SpineBlockManifestHeight,
&mb.ManifestReferenceHeight,
&mb.ManifestSpineBlockHeight,
&mb.ChainType,
&mb.SpineBlockManifestType,
&mb.ExpirationTimestamp,
@@ -125,7 +143,8 @@ func (mbl *SpineBlockManifestQuery) Scan(mb *model.SpineBlockManifest, row *sql.
&mb.ID,
&mb.FullFileHash,
&mb.FileChunkHashes,
&mb.SpineBlockManifestHeight,
&mb.ManifestReferenceHeight,
&mb.ManifestSpineBlockHeight,
&mb.ChainType,
&mb.SpineBlockManifestType,
&mb.ExpirationTimestamp,
@@ -142,8 +161,8 @@ func (mbl *SpineBlockManifestQuery) Scan(mb *model.SpineBlockManifest, row *sql.
func (mbl *SpineBlockManifestQuery) Rollback(height uint32) (multiQueries [][]interface{}) {
return [][]interface{}{
{
fmt.Sprintf("DELETE FROM %s WHERE manifest_reference_height > ?", mbl.getTableName()),
height - constant.MinRollbackBlocks,
fmt.Sprintf("DELETE FROM %s WHERE manifest_spine_block_height > ?", mbl.getTableName()),
height,
},
}
}
20 changes: 10 additions & 10 deletions common/query/spineBlockManifestQuery_test.go
Original file line number Diff line number Diff line change
@@ -18,8 +18,8 @@ func TestSpineBlockManifestQuery_InsertSpineBlockManifest(t *testing.T) {
}

mb1 := &model.SpineBlockManifest{
FullFileHash: make([]byte, 64), // sha3-512
SpineBlockManifestHeight: 720,
FullFileHash: make([]byte, 64), // sha3-512
ManifestReferenceHeight: 720,
}
tests := []struct {
name string
@@ -37,8 +37,8 @@ func TestSpineBlockManifestQuery_InsertSpineBlockManifest(t *testing.T) {
spineBlockManifest: mb1,
},
want: "INSERT OR REPLACE INTO spine_block_manifest (id,full_file_hash,file_chunk_hashes,manifest_reference_height," +
"chain_type,manifest_type," +
"manifest_timestamp) VALUES(? , ?, ?, ?, ?, ?, ?)",
"manifest_spine_block_height,chain_type,manifest_type," +
"expiration_timestamp) VALUES(? , ?, ?, ?, ?, ?, ?, ?)",
},
}
for _, tt := range tests {
@@ -79,9 +79,9 @@ func TestSpineBlockManifestQuery_GetLastSpineBlockManifest(t *testing.T) {
ct: &chaintype.MainChain{},
mbType: model.SpineBlockManifestType_Snapshot,
},
want: "SELECT id, full_file_hash, file_chunk_hashes, manifest_reference_height, chain_type, manifest_type, " +
"manifest_timestamp FROM spine_block_manifest WHERE chain_type = 0 AND manifest_type = 0 ORDER BY manifest_reference_height" +
" DESC LIMIT 1",
want: "SELECT id, full_file_hash, file_chunk_hashes, manifest_reference_height, manifest_spine_block_height, " +
"chain_type, manifest_type, expiration_timestamp FROM spine_block_manifest WHERE chain_type = 0 AND " +
"manifest_type = 0 ORDER BY manifest_reference_height DESC LIMIT 1",
},
}
for _, tt := range tests {
@@ -122,9 +122,9 @@ func TestSpineBlockManifestQuery_GetSpineBlockManifestsInTimeInterval(t *testing
fromTimestamp: 10,
toTimestamp: 20,
},
want: "SELECT id, full_file_hash, file_chunk_hashes, manifest_reference_height, chain_type, manifest_type, " +
"manifest_timestamp FROM spine_block_manifest WHERE manifest_timestamp > 10 AND manifest_timestamp <= 20 ORDER" +
" BY manifest_type, chain_type, manifest_reference_height",
want: "SELECT id, full_file_hash, file_chunk_hashes, manifest_reference_height, manifest_spine_block_height, " +
"chain_type, manifest_type, expiration_timestamp FROM spine_block_manifest WHERE expiration_timestamp > 10 " +
"AND expiration_timestamp <= 20 ORDER BY manifest_type, chain_type, manifest_reference_height",
},
}
for _, tt := range tests {
2 changes: 1 addition & 1 deletion common/schema
4 changes: 2 additions & 2 deletions core/blockchainsync/blockchainOrchestratorService.go
Original file line number Diff line number Diff line change
@@ -103,14 +103,14 @@ func (bos *BlockchainOrchestratorService) DownloadSnapshot(ct chaintype.ChainTyp
}
bos.Logger.Infof("found a Snapshot Spine Block Manifest for chaintype %s, "+
"at height is %d. Start downloading...\n", ct.GetName(),
lastSpineBlockManifest.SpineBlockManifestHeight)
lastSpineBlockManifest.ManifestReferenceHeight)
snapshotFileInfo, err := bos.FileDownloader.DownloadSnapshot(ct, lastSpineBlockManifest)
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())
lastSpineBlockManifest.ManifestReferenceHeight, err.Error())
return err
}

Loading