diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go index 268db11ed32..5018653c76e 100644 --- a/chain/stmgr/forks.go +++ b/chain/stmgr/forks.go @@ -229,10 +229,17 @@ func (sm *StateManager) handleStateForks(ctx context.Context, root cid.Cid, heig var err error u := sm.stateMigrations[height] if u != nil && u.upgrade != nil { - retCid, err = u.upgrade(ctx, sm, u.cache, cb, root, height, ts) + // Yes, we clone the cache, even for the final upgrade epoch. Why? Reverts. We may + // have to migrate multiple times. + tmpCache := u.cache.Clone() + retCid, err = u.upgrade(ctx, sm, tmpCache, cb, root, height, ts) if err != nil { return cid.Undef, err } + // Yes, we update the cache, even for the final upgrade epoch. Why? Reverts. This + // can save us a _lot_ of time because very few actors will have changed if we + // do a small revert then need to re-run the migration. + u.cache.Update(tmpCache) } return retCid, nil @@ -279,11 +286,20 @@ func (sm *StateManager) preMigrationWorker(ctx context.Context) { wg.Add(1) go func() { defer wg.Done() + + // Clone the cache so we don't actually _update_ it + // till we're done. Otherwise, if we fail, the next + // migration to use the cache may assume that + // certain blocks exist, even if they don't. + tmpCache := cache.Clone() err := migrationFunc(preCtx, sm, cache, ts.ParentState(), ts.Height(), ts) if err != nil { log.Errorw("failed to run pre-migration", "error", err) + return } + // Finally, if everything worked, update the cache. + cache.Update(tmpCache) }() }, }) diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index b0018ddc01f..8598ac23d29 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -66,7 +66,7 @@ type versionSpec struct { type migration struct { upgrade MigrationFunc preMigrations []PreMigration - cache MigrationCache + cache *nv10.MemMigrationCache } type StateManager struct { diff --git a/go.mod b/go.mod index 5a062f34d49..0a4c4dfc3b5 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b github.com/filecoin-project/specs-actors v0.9.13 github.com/filecoin-project/specs-actors/v2 v2.3.4 - github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210126204401-0e4fdfa27dea + github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210127005641-3320300e4add github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 github.com/filecoin-project/test-vectors/schema v0.0.5 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 6f5f1699d03..7debbf8dc35 100644 --- a/go.sum +++ b/go.sum @@ -307,8 +307,8 @@ github.com/filecoin-project/specs-actors/v2 v2.3.2 h1:2Vcf4CGa29kRh4JJ02m+FbvD/p github.com/filecoin-project/specs-actors/v2 v2.3.2/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= github.com/filecoin-project/specs-actors/v2 v2.3.4 h1:NZK2oMCcA71wNsUzDBmLQyRMzcCnX9tDGvwZ53G67j8= github.com/filecoin-project/specs-actors/v2 v2.3.4/go.mod h1:UuJQLoTx/HPvvWeqlIFmC/ywlOLHNe8SNQ3OunFbu2Y= -github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210126204401-0e4fdfa27dea h1:TPMvEAUP4bUTDu7LaKkk0zKhtQHEPuOI5C4cEZls2ho= -github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210126204401-0e4fdfa27dea/go.mod h1:aVf248CfjfyCmVel4UuFAA3u+9UQjqtqHpgfYv+M+9U= +github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210127005641-3320300e4add h1:LvS5fTSY5HgibaXbFEscox2SfiuBlS8RrVgBdGbozOE= +github.com/filecoin-project/specs-actors/v3 v3.0.1-0.20210127005641-3320300e4add/go.mod h1:aVf248CfjfyCmVel4UuFAA3u+9UQjqtqHpgfYv+M+9U= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=