• R/O
  • HTTP
  • SSH
  • HTTPS

vapor: 提交

Golang implemented sidechain for Bytom


Commit MetaInfo

修订版01eeb5341fd4d099389ee6186f95069a81ccb6f6 (tree)
时间2020-02-23 13:00:51
作者Paladz <yzhu101@uott...>
CommiterGitHub

Log Message

Merge branch 'mov' into fix_add_order_of_order_book

更改概述

差异

--- a/application/mov/mov_core.go
+++ b/application/mov/mov_core.go
@@ -53,6 +53,9 @@ func (m *MovCore) ApplyBlock(block *types.Block) error {
5353 if err := m.movStore.InitDBState(block.Height, &blockHash); err != nil {
5454 return err
5555 }
56+
57+ // the next block can send orders
58+ return nil
5659 }
5760
5861 if err := m.validateMatchedTxSequence(block.Transactions); err != nil {
--- /dev/null
+++ b/cmd/vapord/commands/rollback_node.go
@@ -0,0 +1,38 @@
1+package commands
2+
3+import (
4+ "strconv"
5+
6+ log "github.com/sirupsen/logrus"
7+ "github.com/spf13/cobra"
8+
9+ "github.com/bytom/vapor/node"
10+)
11+
12+var rollbackCmd = &cobra.Command{
13+ Use: "rollback",
14+ Short: "Rollback chain to target height!",
15+ Args: cobra.ExactArgs(1),
16+ Run: func(cmd *cobra.Command, args []string) {
17+ setLogLevel(config.LogLevel)
18+
19+ height, err := strconv.ParseInt(args[0], 10, 64)
20+ if err != nil {
21+ log.WithFields(log.Fields{"module": logModule, "err": err}).Fatal("failed to parse int")
22+ }
23+
24+ if height < 0 {
25+ log.WithFields(log.Fields{"module": logModule}).Fatal("height should >= 0")
26+ }
27+
28+ if err = node.Rollback(config, uint64(height)); err != nil {
29+ log.WithFields(log.Fields{"module": logModule, "err": err}).Fatal("failed to rollback")
30+ }
31+
32+ log.WithFields(log.Fields{"module": logModule}).Infof("success to rollback height of %d", height)
33+ },
34+}
35+
36+func init() {
37+ RootCmd.AddCommand(rollbackCmd)
38+}
--- a/database/store.go
+++ b/database/store.go
@@ -156,6 +156,18 @@ func GetConsensusResult(db dbm.DB, seq uint64) (*state.ConsensusResult, error) {
156156 return consensusResult, nil
157157 }
158158
159+// DeleteConsensusResult delete a consensusResult from cache and database
160+func (s *Store) DeleteConsensusResult(seq uint64) error {
161+ consensusResult, err := GetConsensusResult(s.db, seq)
162+ if err != nil {
163+ return err
164+ }
165+
166+ s.db.Delete(calcConsensusResultKey(seq))
167+ s.cache.removeConsensusResult(consensusResult)
168+ return nil
169+}
170+
159171 // DeleteBlock delete a new block in the protocol.
160172 func (s *Store) DeleteBlock(block *types.Block) error {
161173 blockHash := block.Hash()
--- a/node/node.go
+++ b/node/node.go
@@ -59,13 +59,7 @@ type Node struct {
5959
6060 // NewNode create bytom node
6161 func NewNode(config *cfg.Config) *Node {
62- if err := lockDataDirectory(config); err != nil {
63- cmn.Exit("Error: " + err.Error())
64- }
65-
66- if err := cfg.LoadFederationFile(config.FederationFile(), config); err != nil {
67- cmn.Exit(cmn.Fmt("Failed to load federated information:[%s]", err.Error()))
68- }
62+ initNodeConfig(config)
6963
7064 if err := vaporLog.InitLogFile(config); err != nil {
7165 log.WithField("err", err).Fatalln("InitLogFile failed")
@@ -79,12 +73,6 @@ func NewNode(config *cfg.Config) *Node {
7973 "fed_controlprogram": hex.EncodeToString(cfg.FederationWScript(config)),
8074 }).Info()
8175
82- if err := consensus.InitActiveNetParams(config.ChainID); err != nil {
83- log.Fatalf("Failed to init ActiveNetParams:[%s]", err.Error())
84- }
85-
86- initCommonConfig(config)
87-
8876 // Get store
8977 if config.DBBackend != "memdb" && config.DBBackend != "leveldb" {
9078 cmn.Exit(cmn.Fmt("Param db_backend [%v] is invalid, use leveldb or memdb", config.DBBackend))
@@ -128,6 +116,10 @@ func NewNode(config *cfg.Config) *Node {
128116 log.WithFields(log.Fields{"module": logModule, "error": err}).Error("init NewWallet")
129117 }
130118
119+ if err = wallet.Run(); err != nil {
120+ log.WithFields(log.Fields{"module": logModule, "error": err}).Error("init NewWallet work running thread")
121+ }
122+
131123 // trigger rescan wallet
132124 if config.Wallet.Rescan {
133125 wallet.RescanBlocks()
@@ -170,6 +162,69 @@ func NewNode(config *cfg.Config) *Node {
170162 return node
171163 }
172164
165+// Rollback rollback chain from one height to targetHeight
166+func Rollback(config *cfg.Config, targetHeight uint64) error {
167+ if err := initNodeConfig(config); err != nil {
168+ return err
169+ }
170+
171+ // Get store
172+ if config.DBBackend != "leveldb" {
173+ return errors.New("Param db_backend is invalid, use leveldb")
174+ }
175+
176+ coreDB := dbm.NewDB("core", config.DBBackend, config.DBDir())
177+ store := database.NewStore(coreDB)
178+
179+ dispatcher := event.NewDispatcher()
180+ movCore := mov.NewMovCore(config.DBBackend, config.DBDir(), consensus.ActiveNetParams.MovStartHeight)
181+ txPool := protocol.NewTxPool(store, []protocol.DustFilterer{movCore}, dispatcher)
182+ chain, err := protocol.NewChain(store, txPool, []protocol.Protocoler{movCore}, dispatcher)
183+ if err != nil {
184+ return err
185+ }
186+
187+ hsm, err := pseudohsm.New(config.KeysDir())
188+ if err != nil {
189+ return err
190+ }
191+
192+ walletDB := dbm.NewDB("wallet", config.DBBackend, config.DBDir())
193+ walletStore := database.NewWalletStore(walletDB)
194+ accountStore := database.NewAccountStore(walletDB)
195+ accounts := account.NewManager(accountStore, chain)
196+ assets := asset.NewRegistry(walletDB, chain)
197+ wallet, err := w.NewWallet(walletStore, accounts, assets, hsm, chain, dispatcher, config.Wallet.TxIndex)
198+ if err != nil {
199+ return err
200+ }
201+
202+ if err := wallet.Rollback(targetHeight); err != nil {
203+ return err
204+ }
205+
206+ return chain.Rollback(targetHeight)
207+}
208+
209+func initNodeConfig(config *cfg.Config) error {
210+ if err := lockDataDirectory(config); err != nil {
211+ log.WithField("err", err).Info("Error: " + err.Error())
212+ return err
213+ }
214+
215+ if err := cfg.LoadFederationFile(config.FederationFile(), config); err != nil {
216+ log.WithField("err", err).Info("Failed to load federated information")
217+ return err
218+ }
219+
220+ if err := consensus.InitActiveNetParams(config.ChainID); err != nil {
221+ log.Fatalf("Failed to init ActiveNetParams:[%s]", err.Error())
222+ }
223+
224+ cfg.CommonConfig = config
225+ return nil
226+}
227+
173228 // find whether config xpubs equal genesis block xpubs
174229 func checkConfig(chain *protocol.Chain, config *cfg.Config) error {
175230 fedpegScript := cfg.FederationWScript(config)
--- a/protocol/block.go
+++ b/protocol/block.go
@@ -137,63 +137,140 @@ func (c *Chain) connectBlock(block *types.Block) (err error) {
137137 return nil
138138 }
139139
140-func (c *Chain) reorganizeChain(blockHeader *types.BlockHeader) error {
141- attachBlockHeaders, detachBlockHeaders, err := c.calcReorganizeChain(blockHeader, c.bestBlockHeader)
140+func (c *Chain) detachBlock(detachBlockHeader *types.BlockHeader, consensusResult *state.ConsensusResult, utxoView *state.UtxoViewpoint) (*types.Block, error) {
141+ detachHash := detachBlockHeader.Hash()
142+ block, err := c.store.GetBlock(&detachHash)
142143 if err != nil {
143- return err
144+ return block, err
144145 }
145146
146- utxoView := state.NewUtxoViewpoint()
147- consensusResults := []*state.ConsensusResult{}
148- consensusResult, err := c.getBestConsensusResult()
147+ detachBlock := types.MapBlock(block)
148+ if err := consensusResult.DetachBlock(block); err != nil {
149+ return block, err
150+ }
151+
152+ if err := c.store.GetTransactionsUtxo(utxoView, detachBlock.Transactions); err != nil {
153+ return block, err
154+ }
155+
156+ txStatus, err := c.GetTransactionStatus(&detachBlock.ID)
149157 if err != nil {
150- return err
158+ return block, err
151159 }
152160
161+ if err := utxoView.DetachBlock(detachBlock, txStatus); err != nil {
162+ return block, err
163+ }
164+
165+ for _, p := range c.subProtocols {
166+ if err := p.DetachBlock(block); err != nil {
167+ return block, errors.Wrap(err, p.Name(), "sub protocol detach block")
168+ }
169+ }
170+
171+ log.WithFields(log.Fields{"module": logModule, "height": detachBlockHeader.Height, "hash": detachHash.String()}).Debug("detach from mainchain")
172+ return block, nil
173+}
174+
175+func (c *Chain) syncSubProtocols() error {
153176 for _, p := range c.subProtocols {
154177 if err := c.syncProtocolStatus(p); err != nil {
155178 return errors.Wrap(err, p.Name(), "sync sub protocol status")
156179 }
157180 }
181+ return nil
182+}
183+
184+// Rollback rollback the chain from one blockHeight to targetBlockHeight
185+// WARNING: we recommend to use this only in commond line
186+func (c *Chain) Rollback(targetHeight uint64) error {
187+ c.cond.L.Lock()
188+ defer c.cond.L.Unlock()
189+
190+ utxoView := state.NewUtxoViewpoint()
191+ consensusResult, err := c.getBestConsensusResult()
192+ if err != nil {
193+ return err
194+ }
158195
159- txsToRestore := map[bc.Hash]*types.Tx{}
160- for _, detachBlockHeader := range detachBlockHeaders {
161- detachHash := detachBlockHeader.Hash()
162- b, err := c.store.GetBlock(&detachHash)
163- if err != nil {
164- return err
165- }
196+ if err = c.syncSubProtocols(); err != nil {
197+ return err
198+ }
166199
167- detachBlock := types.MapBlock(b)
168- if err := c.store.GetTransactionsUtxo(utxoView, detachBlock.Transactions); err != nil {
169- return err
170- }
200+ targetBlockHeader, err := c.GetHeaderByHeight(targetHeight)
201+ if err != nil {
202+ return err
203+ }
171204
172- txStatus, err := c.GetTransactionStatus(&detachBlock.ID)
205+ _, deletedBlockHeaders, err := c.calcReorganizeChain(targetBlockHeader, c.bestBlockHeader)
206+ if err != nil {
207+ return err
208+ }
209+
210+ deletedBlocks := []*types.Block{}
211+ for _, deletedBlockHeader := range deletedBlockHeaders {
212+ block, err := c.detachBlock(deletedBlockHeader, consensusResult, utxoView)
173213 if err != nil {
174214 return err
175215 }
176216
177- if err := utxoView.DetachBlock(detachBlock, txStatus); err != nil {
217+ deletedBlocks = append(deletedBlocks, block)
218+ }
219+
220+ setIrrBlockHeader := c.lastIrrBlockHeader
221+ if c.lastIrrBlockHeader.Height > targetBlockHeader.Height {
222+ setIrrBlockHeader = targetBlockHeader
223+ }
224+
225+ startSeq := state.CalcVoteSeq(c.bestBlockHeader.Height)
226+
227+ if err = c.setState(targetBlockHeader, setIrrBlockHeader, nil, utxoView, []*state.ConsensusResult{consensusResult.Fork()}); err != nil {
228+ return err
229+ }
230+
231+ for _, block := range deletedBlocks {
232+ if err := c.store.DeleteBlock(block); err != nil {
178233 return err
179234 }
235+ }
180236
181- if err := consensusResult.DetachBlock(b); err != nil {
237+ endSeq := state.CalcVoteSeq(targetHeight)
238+ for nowSeq := startSeq; nowSeq > endSeq; nowSeq-- {
239+ if err := c.store.DeleteConsensusResult(nowSeq); err != nil {
182240 return err
183241 }
242+ }
184243
185- for _, p := range c.subProtocols {
186- if err := p.DetachBlock(b); err != nil {
187- return errors.Wrap(err, p.Name(), "sub protocol detach block")
188- }
244+ return nil
245+}
246+
247+func (c *Chain) reorganizeChain(blockHeader *types.BlockHeader) error {
248+ attachBlockHeaders, detachBlockHeaders, err := c.calcReorganizeChain(blockHeader, c.bestBlockHeader)
249+ if err != nil {
250+ return err
251+ }
252+
253+ utxoView := state.NewUtxoViewpoint()
254+ consensusResults := []*state.ConsensusResult{}
255+ consensusResult, err := c.getBestConsensusResult()
256+ if err != nil {
257+ return err
258+ }
259+
260+ if err = c.syncSubProtocols(); err != nil {
261+ return err
262+ }
263+
264+ txsToRestore := map[bc.Hash]*types.Tx{}
265+ for _, detachBlockHeader := range detachBlockHeaders {
266+ b, err := c.detachBlock(detachBlockHeader, consensusResult, utxoView)
267+ if err != nil {
268+ return err
189269 }
190270
191271 for _, tx := range b.Transactions {
192272 txsToRestore[tx.ID] = tx
193273 }
194-
195- blockHash := blockHeader.Hash()
196- log.WithFields(log.Fields{"module": logModule, "height": blockHeader.Height, "hash": blockHash.String()}).Debug("detach from mainchain")
197274 }
198275
199276 txsToRemove := map[bc.Hash]*types.Tx{}
--- a/protocol/block_test.go
+++ b/protocol/block_test.go
@@ -26,6 +26,7 @@ func (s *mStore) GetUtxo(*bc.Hash) (*storage.UtxoEntry, error) {
2626 func (s *mStore) GetConsensusResult(uint64) (*state.ConsensusResult, error) { return nil, nil }
2727 func (s *mStore) GetMainChainHash(uint64) (*bc.Hash, error) { return nil, nil }
2828 func (s *mStore) GetBlockHashesByHeight(uint64) ([]*bc.Hash, error) { return nil, nil }
29+func (s *mStore) DeleteConsensusResult(seq uint64) error { return nil }
2930 func (s *mStore) DeleteBlock(*types.Block) error { return nil }
3031 func (s *mStore) SaveBlock(*types.Block, *bc.TransactionStatus) error { return nil }
3132 func (s *mStore) SaveBlockHeader(blockHeader *types.BlockHeader) error {
--- a/protocol/consensus_node_manager_test.go
+++ b/protocol/consensus_node_manager_test.go
@@ -735,6 +735,10 @@ func (s *dummyStore) GetBlockHashesByHeight(uint64) ([]*bc.Hash, error) {
735735 return nil, nil
736736 }
737737
738+func (s *dummyStore) DeleteConsensusResult(seq uint64) error {
739+ return nil
740+}
741+
738742 func (s *dummyStore) SaveBlock(block *types.Block, _ *bc.TransactionStatus) error {
739743 hash := block.Hash()
740744 s.blocks[hash.String()] = block
--- a/protocol/store.go
+++ b/protocol/store.go
@@ -27,6 +27,7 @@ type Store interface {
2727 GetMainChainHash(uint64) (*bc.Hash, error)
2828 GetBlockHashesByHeight(uint64) ([]*bc.Hash, error)
2929
30+ DeleteConsensusResult(uint64) error
3031 DeleteBlock(*types.Block) error
3132 SaveBlock(*types.Block, *bc.TransactionStatus) error
3233 SaveBlockHeader(*types.BlockHeader) error
--- a/protocol/txpool_test.go
+++ b/protocol/txpool_test.go
@@ -122,6 +122,7 @@ func (s *mockStore) GetConsensusResult(uint64) (*state.ConsensusResult, error)
122122 func (s *mockStore) GetMainChainHash(uint64) (*bc.Hash, error) { return nil, nil }
123123 func (s *mockStore) GetBlockHashesByHeight(uint64) ([]*bc.Hash, error) { return nil, nil }
124124 func (s *mockStore) SaveBlock(*types.Block, *bc.TransactionStatus) error { return nil }
125+func (s *mockStore) DeleteConsensusResult(seq uint64) error { return nil }
125126 func (s *mockStore) DeleteBlock(*types.Block) error { return nil }
126127 func (s *mockStore) SaveBlockHeader(*types.BlockHeader) error { return nil }
127128 func (s *mockStore) SaveChainStatus(*types.BlockHeader, *types.BlockHeader, []*types.BlockHeader, *state.UtxoViewpoint, []*state.ConsensusResult) error {
@@ -675,6 +676,7 @@ func (s *mockStore1) GetMainChainHash(uint64) (*bc.Hash, error)
675676 func (s *mockStore1) GetBlockHashesByHeight(uint64) ([]*bc.Hash, error) { return nil, nil }
676677 func (s *mockStore1) DeleteBlock(*types.Block) error { return nil }
677678 func (s *mockStore1) SaveBlock(*types.Block, *bc.TransactionStatus) error { return nil }
679+func (s *mockStore1) DeleteConsensusResult(seq uint64) error { return nil }
678680 func (s *mockStore1) SaveBlockHeader(*types.BlockHeader) error { return nil }
679681 func (s *mockStore1) SaveChainStatus(*types.BlockHeader, *types.BlockHeader, []*types.BlockHeader, *state.UtxoViewpoint, []*state.ConsensusResult) error {
680682 return nil
--- a/test/wallet_test_util.go
+++ b/test/wallet_test_util.go
@@ -251,6 +251,11 @@ func (cfg *walletTestConfig) Run() error {
251251 if err != nil {
252252 return err
253253 }
254+
255+ if err = wallet.Run(); err != nil {
256+ return err
257+ }
258+
254259 ctx := &walletTestContext{
255260 Wallet: wallet,
256261 Chain: chain,
--- a/wallet/wallet.go
+++ b/wallet/wallet.go
@@ -80,16 +80,22 @@ func NewWallet(store WalletStore, account *account.Manager, asset *asset.Registr
8080 return nil, err
8181 }
8282
83+ return w, nil
84+}
85+
86+// Run go to run some wallet recorvery and clean tx thread
87+func (w *Wallet) Run() error {
8388 var err error
8489 w.TxMsgSub, err = w.EventDispatcher.Subscribe(protocol.TxMsgEvent{})
8590 if err != nil {
86- return nil, err
91+ return err
8792 }
8893
8994 go w.walletUpdater()
9095 go w.delUnconfirmedTx()
9196 go w.MemPoolTxQueryLoop()
92- return w, nil
97+
98+ return nil
9399 }
94100
95101 // MemPoolTxQueryLoop constantly pass a transaction accepted by mempool to the wallet.
@@ -307,6 +313,22 @@ func (w *Wallet) DeleteAccount(accountID string) (err error) {
307313 return nil
308314 }
309315
316+// Rollback wallet to target height
317+func (w *Wallet) Rollback(targetHeight uint64) error {
318+ for w.Status.WorkHeight > targetHeight {
319+ block, err := w.Chain.GetBlockByHash(&w.Status.WorkHash)
320+ if err != nil {
321+ return err
322+ }
323+
324+ if err = w.DetachBlock(block); err != nil {
325+ return err
326+ }
327+ }
328+
329+ return nil
330+}
331+
310332 func (w *Wallet) UpdateAccountAlias(accountID string, newAlias string) (err error) {
311333 w.rw.Lock()
312334 defer w.rw.Unlock()
Show on old repository browser