Skip to content

Commit

Permalink
Merge pull request #40 from thetatoken/pruning
Browse files Browse the repository at this point in the history
Import Chain from Backup
  • Loading branch information
qinwei-gong authored Jul 8, 2019
2 parents ab5d150 + 19a3c31 commit 2f71155
Show file tree
Hide file tree
Showing 25 changed files with 1,035 additions and 138 deletions.
12 changes: 10 additions & 2 deletions blockchain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,18 @@ func (ch *Chain) CommitBlock(hash common.Hash) {
}
}

func (ch *Chain) FinalizePreviousBlocks(hash common.Hash) {
func (ch *Chain) FinalizePreviousBlocks(hash common.Hash) error {
ch.mu.Lock()
defer ch.mu.Unlock()

status := core.BlockStatusDirectlyFinalized
for !hash.IsEmpty() {
block, err := ch.findBlock(hash)
if err != nil || block.Status.IsFinalized() {
return
return nil
}
if block.Status == core.BlockStatusDisposed {
return errors.New("Cannot finalize disposed branch")
}
block.Status = status
status = core.BlockStatusIndirectlyFinalized // Only the first block is marked as directly finalized
Expand All @@ -253,6 +256,7 @@ func (ch *Chain) FinalizePreviousBlocks(hash common.Hash) {
}
hash = block.Parent
}
return nil
}

func (ch *Chain) IsOrphan(block *core.Block) bool {
Expand All @@ -266,6 +270,10 @@ func (ch *Chain) saveBlock(block *core.ExtendedBlock) error {
return ch.store.Put(hash[:], *block)
}

func (ch *Chain) SaveBlock(block *core.ExtendedBlock) error {
return ch.saveBlock(block)
}

// FindBlock tries to retrieve a block by hash.
func (ch *Chain) FindBlock(hash common.Hash) (*core.ExtendedBlock, error) {
ch.mu.RLock()
Expand Down
5 changes: 5 additions & 0 deletions blockchain/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ func (ch *Chain) FindVotesByHash(hash common.Hash) *core.VoteSet {
ch.store.Get(voteIndexKey(hash), voteSet)
return voteSet
}

// RemoveVotesByHash removes votes for givin block.
func (ch *Chain) RemoveVotesByHash(hash common.Hash) {
ch.store.Delete(voteIndexKey(hash))
}
5 changes: 5 additions & 0 deletions cmd/theta/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import (

var cfgPath string
var snapshotPath string
var chainImportDirPath string
var chainCorrectionPath string

var nodePassword string

// RootCmd represents the base command when called without any subcommands
Expand All @@ -35,6 +38,8 @@ func init() {

RootCmd.PersistentFlags().StringVar(&cfgPath, "config", getDefaultConfigPath(), fmt.Sprintf("config path (default is %s)", getDefaultConfigPath()))
RootCmd.PersistentFlags().StringVar(&snapshotPath, "snapshot", "", "snapshot path")
RootCmd.PersistentFlags().StringVar(&chainImportDirPath, "chain_import", "", "chain import path")
RootCmd.PersistentFlags().StringVar(&chainCorrectionPath, "chain_correction", "", "chain correction path")
//RootCmd.PersistentFlags().StringVar(&snapshotPath, "snapshot", getDefaultSnapshotPath(), fmt.Sprintf("snapshot path (default is %s)", getDefaultSnapshotPath()))
RootCmd.PersistentFlags().StringVar(&nodePassword, "password", "", "password for the node")
}
Expand Down
17 changes: 10 additions & 7 deletions cmd/theta/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ func runStart(cmd *cobra.Command, args []string) {
if len(snapshotPath) == 0 {
snapshotPath = path.Join(cfgPath, "snapshot")
}
snapshotBlockHeader, err := snapshot.ValidateSnapshot(snapshotPath)

snapshotBlockHeader, err := snapshot.ValidateSnapshot(snapshotPath, chainImportDirPath, chainCorrectionPath)
if err != nil {
log.Fatalf("Snapshot validation failed, err: %v", err)
}
Expand All @@ -69,12 +70,14 @@ func runStart(cmd *cobra.Command, args []string) {
viper.Set(common.CfgGenesisChainID, root.ChainID)

params := &node.Params{
ChainID: root.ChainID,
PrivateKey: privKey,
Root: root,
Network: network,
DB: db,
SnapshotPath: snapshotPath,
ChainID: root.ChainID,
PrivateKey: privKey,
Root: root,
Network: network,
DB: db,
SnapshotPath: snapshotPath,
ChainImportDirPath: chainImportDirPath,
ChainCorrectionPath: chainCorrectionPath,
}
n := node.NewNode(params)

Expand Down
5 changes: 2 additions & 3 deletions cmd/thetacli/cmd/backup/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import (
)

var (
startFlag uint64
endFlag uint64
configFlag string
startFlag uint64
endFlag uint64
)

// chainCmd represents the chain backup command.
Expand Down
56 changes: 56 additions & 0 deletions cmd/thetacli/cmd/backup/correction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package backup

import (
"encoding/json"
"fmt"

"github.com/thetatoken/theta/cmd/thetacli/cmd/utils"
"github.com/thetatoken/theta/common"
"github.com/thetatoken/theta/rpc"

"github.com/spf13/cobra"
"github.com/spf13/viper"
rpcc "github.com/ybbus/jsonrpc"
)

var (
exclusionTxsFlag []string
)

// chainCorrectionCmd represents the chain correction command.
// Example:
// thetacli backup chain_correction
var chainCorrectionCmd = &cobra.Command{
Use: "chain_correction",
Short: "backup chain_correction",
Long: `Backup chain_correction.`,
Example: `thetacli backup chain_correction`,
Run: doChainCorrectionCmd,
}

func doChainCorrectionCmd(cmd *cobra.Command, args []string) {
client := rpcc.NewRPCClient(viper.GetString(utils.CfgRemoteRPCEndpoint))

res, err := client.Call("theta.BackupChainCorrection", rpc.BackupChainCorrectionArgs{SnapshotHeight: heightFlag, EndBlockHash: common.HexToHash(hashFlag), Config: configFlag, ExclusionTxs: exclusionTxsFlag})
if err != nil {
utils.Error("Failed to get backup chain call details: %v\n", err)
}
if res.Error != nil {
utils.Error("Failed to get backup chain res details: %v\n", res.Error)
}
json, err := json.MarshalIndent(res.Result, "", " ")
if err != nil {
utils.Error("Failed to parse server response: %v\n%v\n", err, string(json))
}
fmt.Println(string(json))
}

func init() {
chainCorrectionCmd.Flags().Uint64Var(&heightFlag, "snapshot_height", 0, "Snapshot height")
chainCorrectionCmd.Flags().StringVar(&hashFlag, "end_block_hash", "", "Ending block hash")
chainCorrectionCmd.Flags().StringVar(&configFlag, "config", "", "Config dir")
chainCorrectionCmd.Flags().StringSliceVar(&exclusionTxsFlag, "exclusion_txs", []string{}, "Exclusion Txs")
chainCorrectionCmd.MarkFlagRequired("snapshot_height")
chainCorrectionCmd.MarkFlagRequired("end_block_hash")
chainCorrectionCmd.MarkFlagRequired("config")
}
7 changes: 7 additions & 0 deletions cmd/thetacli/cmd/backup/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ package backup

import "github.com/spf13/cobra"

var (
heightFlag uint64
hashFlag string
configFlag string
)

// BackupCmd represents the backup command
var BackupCmd = &cobra.Command{
Use: "backup",
Expand All @@ -12,4 +18,5 @@ var BackupCmd = &cobra.Command{
func init() {
BackupCmd.AddCommand(chainCmd)
BackupCmd.AddCommand(snapshotCmd)
BackupCmd.AddCommand(chainCorrectionCmd)
}
3 changes: 2 additions & 1 deletion cmd/thetacli/cmd/backup/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var snapshotCmd = &cobra.Command{
func doSnapshotCmd(cmd *cobra.Command, args []string) {
client := rpcc.NewRPCClient(viper.GetString(utils.CfgRemoteRPCEndpoint))

res, err := client.Call("theta.BackupSnapshot", rpc.BackupSnapshotArgs{Config: configFlag})
res, err := client.Call("theta.BackupSnapshot", rpc.BackupSnapshotArgs{Config: configFlag, Height: heightFlag})
if err != nil {
utils.Error("Failed to get backup snapshot call details: %v\n", err)
}
Expand All @@ -43,4 +43,5 @@ func doSnapshotCmd(cmd *cobra.Command, args []string) {
func init() {
snapshotCmd.Flags().StringVar(&configFlag, "config", "", "Config dir")
snapshotCmd.MarkFlagRequired("config")
snapshotCmd.Flags().Uint64Var(&heightFlag, "height", 0, "Snapshot height")
}
Loading

0 comments on commit 2f71155

Please sign in to comment.