github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/store_migration.go (about) 1 package gossip 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/unicornultrafoundation/go-helios/hash" 8 "github.com/unicornultrafoundation/go-helios/u2udb" 9 "github.com/unicornultrafoundation/go-u2u/common" 10 11 "github.com/unicornultrafoundation/go-u2u/native" 12 "github.com/unicornultrafoundation/go-u2u/native/iblockproc" 13 "github.com/unicornultrafoundation/go-u2u/utils/migration" 14 ) 15 16 func isEmptyDB(db u2udb.Iteratee) bool { 17 it := db.NewIterator(nil, nil) 18 defer it.Release() 19 return !it.Next() 20 } 21 22 func (s *Store) migrateData() error { 23 versions := migration.NewU2UdbIDStore(s.table.Version) 24 if isEmptyDB(s.table.Version) { 25 // short circuit if empty DB 26 versions.SetID(s.migrations().ID()) 27 return nil 28 } 29 30 _ = s.eraseGenesisDB() // force eraseGenesisDB migration for alternative versions 31 err := s.migrations().Exec(versions, s.flushDBs) 32 return err 33 } 34 35 func (s *Store) migrations() *migration.Migration { 36 return migration. 37 Begin("u2u-gossip-store"). 38 Next("used gas recovery", unsupportedMigration). 39 Next("tx hashes recovery", unsupportedMigration). 40 Next("DAG heads recovery", unsupportedMigration). 41 Next("DAG last events recovery", unsupportedMigration). 42 Next("BlockState recovery", unsupportedMigration). 43 Next("LlrState recovery", s.recoverLlrState). 44 Next("erase gossip-async db", s.eraseGossipAsyncDB). 45 Next("erase SFC API table", s.eraseSfcApiTable). 46 Next("erase legacy genesis DB", s.eraseGenesisDB). 47 Next("calculate upgrade heights", s.calculateUpgradeHeights) 48 } 49 50 func unsupportedMigration() error { 51 return fmt.Errorf("DB version isn't supported, please restart from scratch") 52 } 53 54 var ( 55 fixTxHash1 = common.HexToHash("0xb6840d4c0eb562b0b1731760223d91b36edc6c160958e23e773e6058eea30458") 56 fixTxEvent1 = hash.HexToEventHash("0x00001718000003d4d3955bf592e12fb80a60574fa4b18bd5805b4c010d75e86d") 57 fixTxHash2 = common.HexToHash("0x3aeede91740093cb8feb1296a34cf70d86d2f802cff860edd798978e94a40534") 58 fixTxEvent2 = hash.HexToEventHash("0x0000179e00000c464d756a7614d0ca067fcb37ee4452004bf308c9df561e85e8") 59 ) 60 61 const ( 62 fixTxEventPos1 = 2 63 fixTxBlock1 = 4738821 64 fixTxEventPos2 = 0 65 fixTxBlock2 = 4801307 66 ) 67 68 func fixEventTxHashes(e *native.EventPayload) { 69 if e.ID() == fixTxEvent1 { 70 e.Txs()[fixTxEventPos1].SetHash(fixTxHash1) 71 } 72 if e.ID() == fixTxEvent2 { 73 e.Txs()[fixTxEventPos2].SetHash(fixTxHash2) 74 } 75 } 76 77 func (s *Store) recoverLlrState() error { 78 v1, ok := s.rlp.Get(s.table.BlockEpochState, []byte(sKey), &BlockEpochState{}).(*BlockEpochState) 79 if !ok { 80 return errors.New("epoch state reading failed: genesis not applied") 81 } 82 83 epoch := v1.EpochState.Epoch + 1 84 block := v1.BlockState.LastBlock.Idx + 1 85 86 s.setLlrState(LlrState{ 87 LowestEpochToDecide: epoch, 88 LowestEpochToFill: epoch, 89 LowestBlockToDecide: block, 90 LowestBlockToFill: block, 91 }) 92 s.FlushLlrState() 93 return nil 94 } 95 96 func (s *Store) eraseSfcApiTable() error { 97 sfcapiTable, _ := s.dbs.OpenDB("gossip/S") 98 it := sfcapiTable.NewIterator(nil, nil) 99 defer it.Release() 100 for it.Next() { 101 err := sfcapiTable.Delete(it.Key()) 102 if err != nil { 103 return err 104 } 105 } 106 return nil 107 } 108 109 func (s *Store) eraseGossipAsyncDB() error { 110 asyncDB, err := s.dbs.OpenDB("gossip-async") 111 if err != nil { 112 return fmt.Errorf("failed to open gossip-async to drop: %v", err) 113 } 114 115 _ = asyncDB.Close() 116 asyncDB.Drop() 117 118 return nil 119 } 120 121 func (s *Store) eraseGenesisDB() error { 122 genesisDB, err := s.dbs.OpenDB("genesis") 123 if err != nil { 124 return nil 125 } 126 127 _ = genesisDB.Close() 128 genesisDB.Drop() 129 return nil 130 } 131 132 func (s *Store) calculateUpgradeHeights() error { 133 var prevEs *iblockproc.EpochState 134 s.ForEachHistoryBlockEpochState(func(bs iblockproc.BlockState, es iblockproc.EpochState) bool { 135 s.WriteUpgradeHeight(bs, es, prevEs) 136 prevEs = &es 137 return true 138 }) 139 if prevEs == nil { 140 // special case when no history is available 141 s.WriteUpgradeHeight(s.GetBlockState(), s.GetEpochState(), nil) 142 } 143 return nil 144 }