@@ -111,6 +111,17 @@ After migration, start the node normally - it will automatically detect and use
111111 return err
112112 }
113113
114+ // Ensure all stores are stopped/closed in the right order on any exit path.
115+ // Order matters: stop header/data sync stores first, then close rollkit store,
116+ // then close Comet stores.
117+ defer func () {
118+ _ = rollkitStores .headerSyncStore .Stop (ctx )
119+ _ = rollkitStores .dataSyncStore .Stop (ctx )
120+ _ = rollkitStores .rollkitStore .Close ()
121+ _ = cometBlockStore .Close ()
122+ _ = cometStateStore .Close ()
123+ }()
124+
114125 // save current CometBFT state to the ABCI exec store
115126 if err = rollkitStores .abciExecStore .SaveState (ctx , & cometBFTstate ); err != nil {
116127 return fmt .Errorf ("failed to save CometBFT state to ABCI exec store: %w" , err )
@@ -126,21 +137,16 @@ After migration, start the node normally - it will automatically detect and use
126137 return err
127138 }
128139
129- if err = rollkitStores .rollkitStore .UpdateState (ctx , rollkitState ); err != nil {
130- return fmt .Errorf ("failed to update evolve state: %w" , err )
131- }
132-
133140 // create minimal rollkit genesis file for future startups
134141 if err := createRollkitMigrationGenesis (config .RootDir , cometBFTstate ); err != nil {
135142 return fmt .Errorf ("failed to create evolve migration genesis: %w" , err )
136143 }
137144
138- cmd .Println ("Created ev_genesis.json.json for migration - the node will use this on subsequent startups" )
145+ cmd .Println ("Created ev_genesis.json for migration - the node will use this on subsequent startups" )
139146
140147 // migrate all the blocks from the CometBFT block store to the evolve store
141148 // the migration is done in reverse order, starting from the last block
142149 missedBlocks := make (map [int64 ]bool )
143- initSyncStores := true
144150
145151 for height := lastBlockHeight ; height > 0 ; height -- {
146152 cmd .Printf ("Migrating block %d...\n " , height )
@@ -163,25 +169,17 @@ After migration, start the node normally - it will automatically detect and use
163169 return fmt .Errorf ("failed to save block data: %w" , err )
164170 }
165171
166- // set last data in sync stores
167- if initSyncStores {
168- if err := rollkitStores .headerSyncStore .Start (ctx ); err != nil {
169- return fmt .Errorf ("failed to start header sync store: %w" , err )
170- }
171-
172- if err = rollkitStores .headerSyncStore .Append (ctx , header ); err != nil {
173- return fmt .Errorf ("failed to initialize header sync store: %w" , err )
174- }
175-
176- if err := rollkitStores .dataSyncStore .Start (ctx ); err != nil {
177- return fmt .Errorf ("failed to start data sync store: %w" , err )
178- }
179-
180- if err = rollkitStores .dataSyncStore .Append (ctx , data ); err != nil {
181- return fmt .Errorf ("failed to initialize data sync store: %w" , err )
182- }
183-
184- initSyncStores = false
172+ // Save BlockID for this height so execution can build last commit post-migration
173+ blockParts , err := block .MakePartSet (cmttypes .BlockPartSizeBytes )
174+ if err != nil {
175+ return fmt .Errorf ("failed to build part set for block %d: %w" , height , err )
176+ }
177+ blockID := cmttypes.BlockID {
178+ Hash : block .Header .Hash (),
179+ PartSetHeader : blockParts .Header (),
180+ }
181+ if err := rollkitStores .abciExecStore .SaveBlockID (ctx , uint64 (block .Height ), & blockID ); err != nil {
182+ return fmt .Errorf ("failed to save BlockID for height %d: %w" , height , err )
185183 }
186184
187185 // Only save extended commit info if vote extensions are enabled
@@ -199,8 +197,38 @@ After migration, start the node normally - it will automatically detect and use
199197 return fmt .Errorf ("failed to set last height in Evolve store: %w" , err )
200198 }
201199
200+ // persist the rollkit state at the after SetHeight is called.
201+ if err = rollkitStores .rollkitStore .UpdateState (ctx , rollkitState ); err != nil {
202+ return fmt .Errorf ("failed to update evolve state at height %d: %w" , lastBlockHeight , err )
203+ }
204+
205+ cmd .Println ("Seeding sync stores head with latest migrated header/data ..." )
206+ if err := rollkitStores .headerSyncStore .Start (ctx ); err != nil {
207+ return fmt .Errorf ("failed to start header sync store: %w" , err )
208+ }
209+ if err := rollkitStores .dataSyncStore .Start (ctx ); err != nil {
210+ return fmt .Errorf ("failed to start data sync store: %w" , err )
211+ }
212+
213+ currentSyncHeight := rollkitStores .headerSyncStore .Height ()
214+ if currentSyncHeight == 0 {
215+ header , data , err := rollkitStores .rollkitStore .GetBlockData (ctx , uint64 (lastBlockHeight ))
216+ if err != nil {
217+ return fmt .Errorf ("failed to get block data for seeding sync stores at height %d: %w" , lastBlockHeight , err )
218+ }
219+ if err := rollkitStores .headerSyncStore .Append (ctx , header ); err != nil {
220+ return fmt .Errorf ("failed to append header to sync store at height %d: %w" , lastBlockHeight , err )
221+ }
222+ if err := rollkitStores .dataSyncStore .Append (ctx , data ); err != nil {
223+ return fmt .Errorf ("failed to append data to sync store at height %d: %w" , lastBlockHeight , err )
224+ }
225+ cmd .Printf ("Seeded sync stores head at height %d\n " , lastBlockHeight )
226+ } else {
227+ cmd .Println ("Sync stores already initialized. Skipping seeding" )
228+ }
229+ // Defer cleanup above will stop/close stores in correct order
202230 cmd .Println ("Migration completed successfully" )
203- return errors . Join ( rollkitStores . rollkitStore . Close (), cometBlockStore . Close (), cometStateStore . Close ())
231+ return nil
204232 },
205233 }
206234
0 commit comments