Skip to content

Commit 3c7aa9a

Browse files
authored
Merge pull request #6468 from filecoin-project/fix/calibnet
Fix/calibnet
2 parents ee3b523 + 1786cc1 commit 3c7aa9a

File tree

15 files changed

+519
-133
lines changed

15 files changed

+519
-133
lines changed

fixtures/networks/butterfly.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func ButterflySnapNet() *NetworkConf {
6767
UpgradeTuktukHeight: -28,
6868
UpgradeTuktukPowerRampDurationEpochs: builtin.EpochsInYear,
6969
UpgradeTeepHeight: 100,
70-
UpgradeTockHeight: 200,
70+
UpgradeTockFixHeight: -29,
7171
},
7272
DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: config.DrandQuicknet},
7373
AddressNetwork: address.Testnet,
@@ -85,5 +85,7 @@ func ButterflySnapNet() *NetworkConf {
8585
},
8686
}
8787

88+
nc.Network.ForkUpgradeParam.UpgradeTockHeight = nc.Network.ForkUpgradeParam.UpgradeTeepHeight + builtin.EpochsInDay*2
89+
8890
return nc
8991
}

fixtures/networks/calibration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ func Calibration() *NetworkConf {
7575
UpgradeTuktukHeight: 2078794, // 2024-10-23T13:30:00Z
7676
UpgradeTuktukPowerRampDurationEpochs: builtin.EpochsInDay * 3,
7777
UpgradeTeepHeight: 2523454, // 2025-03-26T23:00:00Z
78+
UpgradeTockFixHeight: 2558014, // 2025-04-07T23:00:00Z
7879
},
7980
DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: 1},
8081
AddressNetwork: address.Testnet,

fixtures/networks/forcenet.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func ForceNet() *NetworkConf {
7070
UpgradeTuktukPowerRampDurationEpochs: 200,
7171
UpgradeTeepHeight: 200,
7272
UpgradeTockHeight: 300,
73+
UpgradeTockFixHeight: -29,
7374
},
7475
DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: config.DrandQuicknet},
7576
AddressNetwork: address.Testnet,

fixtures/networks/integrationtestnet.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func IntegrationNet() *NetworkConf {
6161
UpgradeWaffleHeight: 4154640,
6262
UpgradeTuktukHeight: 4461240,
6363
UpgradeTeepHeight: 4867320,
64+
UpgradeTockFixHeight: -29,
6465
},
6566
DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: 5, 51000: 1},
6667
AddressNetwork: address.Testnet,

fixtures/networks/interopnet.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func InteropNet() *NetworkConf {
6969
UpgradeTuktukPowerRampDurationEpochs: builtin.EpochsInYear,
7070
UpgradeTeepHeight: 50,
7171
UpgradeTockHeight: 100,
72+
UpgradeTockFixHeight: -29,
7273
},
7374
DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: config.DrandQuicknet},
7475
AddressNetwork: address.Testnet,

fixtures/networks/mainnet.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ func Mainnet() *NetworkConf {
7575
UpgradeWaffleHeight: 4154640, // 2024-08-06T12:00:00Z
7676
UpgradeTuktukHeight: 4461240, // 2024-11-20T23:00:00Z
7777
UpgradeTuktukPowerRampDurationEpochs: builtin2.EpochsInYear,
78-
UpgradeTeepHeight: 4867320, // 2025-04-10T23:00:00Z
78+
UpgradeTeepHeight: 4878840, // 2025-04-14T23:00:00Z
79+
UpgradeTockFixHeight: -1,
7980
},
8081
DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: 5, 51000: 1},
8182
AddressNetwork: address.Mainnet,

fixtures/networks/net_2k.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ func Net2k() *NetworkConf {
6464
UpgradeTuktukHeight: -28,
6565
UpgradeTeepHeight: 200,
6666
UpgradeTockHeight: 300,
67+
UpgradeTockFixHeight: -29,
6768
},
6869
DrandSchedule: map[abi.ChainEpoch]config.DrandEnum{0: config.DrandQuicknet},
6970
AddressNetwork: address.Testnet,

pkg/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ type ForkUpgradeConfig struct {
357357
UpgradeTuktukPowerRampDurationEpochs abi.ChainEpoch `json:"upgradeTuktukPowerRampDurationEpochs"`
358358
UpgradeTeepHeight abi.ChainEpoch `json:"upgradeTeepHeight"`
359359
UpgradeTockHeight abi.ChainEpoch `json:"upgradeTockHeight"`
360+
UpgradeTockFixHeight abi.ChainEpoch `json:"upgradeTockFixHeight"`
360361
}
361362

362363
func IsNearUpgrade(epoch, upgradeEpoch abi.ChainEpoch) bool {
@@ -402,6 +403,7 @@ var DefaultForkUpgradeParam = &ForkUpgradeConfig{
402403
UpgradeTuktukPowerRampDurationEpochs: 200,
403404
UpgradeTeepHeight: 4867320,
404405
UpgradeTockHeight: 4867320 + 90*builtin.EpochsInDay,
406+
UpgradeTockFixHeight: -29,
405407
}
406408

407409
func newDefaultNetworkParamsConfig() *NetworkParamsConfig {

pkg/fork/fork.go

Lines changed: 231 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,10 @@ func DefaultUpgradeSchedule(cf *ChainFork, upgradeHeight *config.ForkUpgradeConf
475475
Height: upgradeHeight.UpgradeTockHeight,
476476
Network: network.Version26,
477477
Migration: nil,
478+
}, {
479+
Height: upgradeHeight.UpgradeTockFixHeight,
480+
Network: network.Version26,
481+
Migration: cf.UpgradeActorsV16Fix,
478482
},
479483
}
480484

@@ -2787,6 +2791,10 @@ var (
27872791

27882792
calibnetv13BuggyManifestCID1 = cid.MustParse("bafy2bzacea4firkyvt2zzdwqjrws5pyeluaesh6uaid246tommayr4337xpmi")
27892793
calibnetv13CorrectManifestCID1 = cid.MustParse("bafy2bzacect4ktyujrwp6mjlsitnpvuw2pbuppz6w52sfljyo4agjevzm75qs")
2794+
2795+
// Some v16.0.0 bundles are included in the v16 bundles tarball along with the v16.0.1 bundles.
2796+
// But the v16.0.0 ones have a -v16.0.0.car suffix instead of just .car.
2797+
v1600BundleSuffix = "v16.0.0"
27902798
)
27912799

27922800
func (c *ChainFork) upgradeActorsV12Common(
@@ -3661,9 +3669,50 @@ func (c *ChainFork) upgradeActorsV16Common(
36613669
) (cid.Cid, error) {
36623670
writeStore := blockstoreutil.NewAutobatch(ctx, c.bs, units.GiB/4)
36633671
adtStore := adt.WrapStore(ctx, cbor.NewCborStore(writeStore))
3664-
// ensure that the manifest is loaded in the blockstore
3665-
if err := actors.LoadBundles(ctx, writeStore, actorstypes.Version16); err != nil {
3666-
return cid.Undef, fmt.Errorf("failed to load manifest bundle: %w", err)
3672+
3673+
manifest, ok := actors.GetManifest(actorstypes.Version16)
3674+
if !ok {
3675+
return cid.Undef, fmt.Errorf("no manifest CID for v16 upgrade")
3676+
}
3677+
3678+
if c.forkUpgrade.UpgradeTockFixHeight > 0 {
3679+
// If there is a UpgradeTockFixHeight height set, then we are expected to load v16.0.0 here and
3680+
// then UpgradeTockFixHeight will take care of setting the actors to v16.0.1. If it's not set
3681+
// then there's nothing to fix and we'll proceed as normal.
3682+
3683+
var initState init12.State
3684+
if actorsIn, err := vmstate.LoadState(ctx, adtStore, root); err != nil {
3685+
return cid.Undef, fmt.Errorf("loading state tree: %w", err)
3686+
} else if initActor, found, err := actorsIn.GetActor(ctx, builtin.InitActorAddr); err != nil || !found {
3687+
return cid.Undef, fmt.Errorf("failed to get system actor: %w", err)
3688+
} else if err := adtStore.Get(ctx, initActor.Head, &initState); err != nil {
3689+
return cid.Undef, fmt.Errorf("failed to get system actor state: %w", err)
3690+
}
3691+
3692+
// The v16.0.0 bundle is embedded in the v16 tarball, we just need to load it with the right
3693+
// name (builtin-actors-<network>-v16.0.0.car).
3694+
embedded, ok := actors.GetEmbeddedBuiltinActorsBundle(actorstypes.Version16, fmt.Sprintf("%s-%s", initState.NetworkName, v1600BundleSuffix))
3695+
if !ok {
3696+
return cid.Undef, fmt.Errorf("didn't find v16.0.0 %s bundle with suffix %s", initState.NetworkName, v1600BundleSuffix)
3697+
}
3698+
3699+
var err error
3700+
manifest, err = actors.LoadBundle(ctx, writeStore, bytes.NewReader(embedded))
3701+
if err != nil {
3702+
return cid.Undef, fmt.Errorf("failed to load buggy calibnet bundle: %w", err)
3703+
}
3704+
3705+
// Sanity check that we loaded what we were supposed to
3706+
if metadata := actors.BuggyBuiltinActorsMetadataForNetwork(initState.NetworkName, actorstypes.Version16); metadata == nil {
3707+
return cid.Undef, fmt.Errorf("didn't find expected v16.0.0 bundle metadata for %s", initState.NetworkName)
3708+
} else if manifest != metadata.ManifestCid {
3709+
return cid.Undef, fmt.Errorf("didn't load expected v16.0.0 bundle manifest: %s != %s", manifest, metadata.ManifestCid)
3710+
}
3711+
} else {
3712+
// ensure that the manifest is loaded in the blockstore
3713+
if err := actors.LoadBundles(ctx, c.bs, actorstypes.Version16); err != nil {
3714+
return cid.Undef, fmt.Errorf("failed to load manifest bundle: %w", err)
3715+
}
36673716
}
36683717

36693718
// Load the state root.
@@ -3679,11 +3728,6 @@ func (c *ChainFork) upgradeActorsV16Common(
36793728
)
36803729
}
36813730

3682-
manifest, ok := actors.GetManifest(actorstypes.Version16)
3683-
if !ok {
3684-
return cid.Undef, fmt.Errorf("no manifest CID for v16 upgrade")
3685-
}
3686-
36873731
// Perform the migration
36883732
newHamtRoot, err := nv25.MigrateStateTree(ctx, adtStore, manifest, stateRoot.Actors, epoch, config,
36893733
migrationLogger{}, cache)
@@ -3713,6 +3757,185 @@ func (c *ChainFork) upgradeActorsV16Common(
37133757
return newRoot, nil
37143758
}
37153759

3760+
// UpgradeActorsV16Fix should _not_ be used on mainnet. It performs an upgrade to v16.0.1 on top of
3761+
// the existing v16.0.0 that was already deployed.
3762+
// The actual mainnet upgrade is performed with UpgradeActorsV16 with the v16.0.1 bundle.
3763+
// This upgrade performs an inefficient form of the migration that go-state-types normally performs.
3764+
func (c *ChainFork) UpgradeActorsV16Fix(
3765+
ctx context.Context,
3766+
cache MigrationCache,
3767+
root cid.Cid,
3768+
epoch abi.ChainEpoch,
3769+
ts *types.TipSet,
3770+
) (cid.Cid, error) {
3771+
stateStore := c.bs
3772+
adtStore := adt.WrapStore(ctx, cbor.NewCborStore(stateStore))
3773+
3774+
// Get the real v16 manifest, which should be for v16.0.1
3775+
manifestCid, ok := actors.GetManifest(actorstypes.Version16)
3776+
if !ok {
3777+
return cid.Undef, fmt.Errorf("no manifest CID for v16 upgrade")
3778+
}
3779+
// ensure that the manifest is loaded in the blockstore, it will load the correct v16.0.1 bundle
3780+
if err := actors.LoadBundles(ctx, stateStore, actorstypes.Version16); err != nil {
3781+
return cid.Undef, fmt.Errorf("failed to load manifest bundle: %w", err)
3782+
}
3783+
3784+
// Load input state tree
3785+
actorsIn, err := vmstate.LoadState(ctx, adtStore, root)
3786+
if err != nil {
3787+
return cid.Undef, fmt.Errorf("loading state tree: %w", err)
3788+
}
3789+
3790+
// load old manifest data
3791+
oldSystemActor, found, err := actorsIn.GetActor(ctx, builtin.SystemActorAddr)
3792+
if err != nil {
3793+
return cid.Undef, fmt.Errorf("failed to get system actor: %w", err)
3794+
}
3795+
if !found {
3796+
return cid.Undef, fmt.Errorf("system actor not found")
3797+
}
3798+
// load old manifest data directly from the system actor
3799+
var oldManifestData manifest.ManifestData
3800+
var oldSystemState system12.State
3801+
if err := adtStore.Get(ctx, oldSystemActor.Head, &oldSystemState); err != nil {
3802+
return cid.Undef, fmt.Errorf("failed to get system actor state: %w", err)
3803+
} else if err := adtStore.Get(ctx, oldSystemState.BuiltinActors, &oldManifestData); err != nil {
3804+
return cid.Undef, fmt.Errorf("failed to get old manifest data: %w", err)
3805+
}
3806+
3807+
// load new manifest from the blockstore
3808+
var newManifest manifest.Manifest
3809+
if err := adtStore.Get(ctx, manifestCid, &newManifest); err != nil {
3810+
return cid.Undef, fmt.Errorf("error reading actor manifest: %w", err)
3811+
} else if err := newManifest.Load(ctx, adtStore); err != nil {
3812+
return cid.Undef, fmt.Errorf("error loading actor manifest: %w", err)
3813+
}
3814+
3815+
// build an actor CID mapping
3816+
codeMapping := make(map[cid.Cid]cid.Cid, len(oldManifestData.Entries))
3817+
for _, oldEntry := range oldManifestData.Entries {
3818+
newCID, ok := newManifest.Get(oldEntry.Name)
3819+
if !ok {
3820+
return cid.Undef, fmt.Errorf("missing manifest entry for %s", oldEntry.Name)
3821+
}
3822+
codeMapping[oldEntry.Code] = newCID
3823+
}
3824+
3825+
// Create empty state tree
3826+
actorsOut, err := vmstate.NewState(adtStore, actorsIn.Version())
3827+
if err != nil {
3828+
return cid.Undef, fmt.Errorf("failed to create new tree: %w", err)
3829+
}
3830+
3831+
// Perform the migration
3832+
err = actorsIn.ForEach(func(a address.Address, actor *types.Actor) error {
3833+
newCid, ok := codeMapping[actor.Code]
3834+
if !ok {
3835+
return fmt.Errorf("didn't find mapping for %s", actor.Code)
3836+
}
3837+
3838+
return actorsOut.SetActor(ctx, a, &types.Actor{
3839+
Code: newCid,
3840+
Head: actor.Head,
3841+
Nonce: actor.Nonce,
3842+
Balance: actor.Balance,
3843+
DelegatedAddress: actor.DelegatedAddress,
3844+
})
3845+
})
3846+
if err != nil {
3847+
return cid.Undef, fmt.Errorf("failed to perform migration: %w", err)
3848+
}
3849+
3850+
// Setup the system actor with the new manifest, fetching it from actorsOut where it's already
3851+
// had its code CID changed, changing the manifest, then writing back to actorsOut
3852+
newSystemActor, found, err := actorsOut.GetActor(ctx, builtin.SystemActorAddr)
3853+
if err != nil {
3854+
return cid.Undef, fmt.Errorf("failed to get system actor: %w", err)
3855+
}
3856+
if !found {
3857+
return cid.Undef, fmt.Errorf("system actor not found")
3858+
}
3859+
var newSystemState system12.State
3860+
if err := adtStore.Get(ctx, newSystemActor.Head, &newSystemState); err != nil {
3861+
return cid.Undef, fmt.Errorf("failed to get system actor state: %w", err)
3862+
} else if err := adtStore.Get(ctx, newSystemState.BuiltinActors, &oldManifestData); err != nil {
3863+
return cid.Undef, fmt.Errorf("failed to get old manifest data: %w", err)
3864+
}
3865+
newSystemState.BuiltinActors = newManifest.Data
3866+
newSystemHead, err := adtStore.Put(ctx, &newSystemState)
3867+
if err != nil {
3868+
return cid.Undef, fmt.Errorf("failed to put new system state: %w", err)
3869+
}
3870+
newSystemActor.Head = newSystemHead
3871+
if err = actorsOut.SetActor(ctx, builtin.SystemActorAddr, newSystemActor); err != nil {
3872+
return cid.Undef, fmt.Errorf("failed to put new system actor: %w", err)
3873+
}
3874+
3875+
// Sanity check that the migration worked by re-iterating over the old tree and checking
3876+
// against the new tree's actors.
3877+
3878+
// initState for networkName
3879+
var initState init12.State
3880+
if actorsIn, err := vmstate.LoadState(ctx, adtStore, root); err != nil {
3881+
return cid.Undef, fmt.Errorf("loading state tree: %w", err)
3882+
} else if initActor, found, err := actorsIn.GetActor(ctx, builtin.InitActorAddr); err != nil || !found {
3883+
return cid.Undef, fmt.Errorf("failed to get system actor: %v", err)
3884+
} else if err := adtStore.Get(ctx, initActor.Head, &initState); err != nil {
3885+
return cid.Undef, fmt.Errorf("failed to get system actor state: %w", err)
3886+
}
3887+
3888+
v1600metadata := actors.BuggyBuiltinActorsMetadataForNetwork(initState.NetworkName, actorstypes.Version16)
3889+
if v1600metadata == nil {
3890+
return cid.Undef, fmt.Errorf("expected v16.0.0 metadata for network %s", initState.NetworkName)
3891+
}
3892+
3893+
err = actorsIn.ForEach(func(a address.Address, inActor *types.Actor) error {
3894+
outActor, found, err := actorsOut.GetActor(ctx, a)
3895+
if err != nil {
3896+
return fmt.Errorf("failed to get actor in outTree: %w", err)
3897+
}
3898+
if !found {
3899+
return fmt.Errorf("actor %s not found in outTree", a)
3900+
}
3901+
3902+
if inActor.Nonce != outActor.Nonce {
3903+
return fmt.Errorf("mismatched nonce for actor %s", a)
3904+
} else if !inActor.Balance.Equals(outActor.Balance) {
3905+
return fmt.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance)
3906+
} else if inActor.DelegatedAddress != outActor.DelegatedAddress && inActor.DelegatedAddress.String() != outActor.DelegatedAddress.String() {
3907+
return fmt.Errorf("mismatched address for actor %s: %s != %s", a, inActor.DelegatedAddress, outActor.DelegatedAddress)
3908+
} else if inActor.Head != outActor.Head && a != builtin.SystemActorAddr {
3909+
return fmt.Errorf("mismatched head for actor %s", a)
3910+
}
3911+
3912+
// Check that the actor code has changed to the new expected value; work backward by getting the
3913+
// actor name from the new code CID.
3914+
if actorName, version, ok := actors.GetActorMetaByCode(outActor.Code); !ok {
3915+
return fmt.Errorf("failed to get actor meta for code %s", outActor.Code)
3916+
} else if version != actorstypes.Version16 {
3917+
return fmt.Errorf("unexpected actor version for %s: %d", actorName, version)
3918+
} else if oldCode, ok := v1600metadata.Actors[actorName]; !ok {
3919+
return fmt.Errorf("missing actor %s in v16.0.0 metadata", actorName)
3920+
} else if oldCode != inActor.Code {
3921+
return fmt.Errorf("unexpected actor code for %s: %s != %s", actorName, oldCode, outActor.Code)
3922+
}
3923+
3924+
return nil
3925+
})
3926+
if err != nil {
3927+
return cid.Undef, fmt.Errorf("failed to sanity check migration: %w", err)
3928+
}
3929+
3930+
// Persist the result.
3931+
newRoot, err := actorsOut.Flush(ctx)
3932+
if err != nil {
3933+
return cid.Undef, fmt.Errorf("failed to persist new state root: %w", err)
3934+
}
3935+
3936+
return newRoot, nil
3937+
}
3938+
37163939
func (c *ChainFork) GetForkUpgrade() *config.ForkUpgradeConfig {
37173940
return c.forkUpgrade
37183941
}

0 commit comments

Comments
 (0)