diff --git a/pkg/constants/env.go b/pkg/constants/env.go index 0d47c7be31..f531e7aa07 100644 --- a/pkg/constants/env.go +++ b/pkg/constants/env.go @@ -1,6 +1,12 @@ package constants -import "os" +import ( + "fmt" + "os" + "slices" + "strconv" + "strings" +) // FevmEnableEthRPC enables eth rpc, and enables storing a mapping of eth transaction hashes to filecoin message Cids. var FevmEnableEthRPC = os.Getenv("VENUS_FEVM_ENABLEETHRPC") == "1" @@ -16,3 +22,53 @@ var NoMigrationResultCache = os.Getenv("VENUS_NO_MIGRATION_RESULT_CACHE") == "1" // DisableF3 disable f3 var DisableF3 = os.Getenv("VENUS_DISABLE_F3") == "1" + +const F3DisableActivation = "VENUS_DISABLE_F3_ACTIVATION" + +func parseF3DisableActivationEnv() (contractAddrs []string, epochs []int64) { + v, envVarSet := os.LookupEnv(F3DisableActivation) + if !envVarSet || strings.TrimSpace(v) == "" { + // Environment variable is not set or empty, activation is not disabled + return + } + + // Parse the variable which can be in format "contract:addrs" or "epoch:epochnumber" or both + parts := strings.Split(v, ",") + for _, part := range parts { + kv := strings.SplitN(part, ":", 2) + if len(kv) != 2 { + continue + } + + key := strings.TrimSpace(strings.ToLower(kv[0])) + value := strings.TrimSpace(kv[1]) + + switch key { + case "contract": + // If contract address matches, disable activation + contractAddrs = append(contractAddrs, value) + case "epoch": + parsedEpoch, err := strconv.ParseInt(value, 10, 64) + if err == nil { + epochs = append(epochs, parsedEpoch) + } else { + fmt.Printf("error parsing %s env variable, cannot parse epoch\n", F3DisableActivation) + } + } + } + return contractAddrs, epochs +} + +// IsF3EpochActivationDisabled checks if F3 activation is disabled for the given +// epoch number based on environment variable configuration. +func IsF3EpochActivationDisabled(epoch int64) bool { + _, epochs := parseF3DisableActivationEnv() + return slices.Contains(epochs, epoch) +} + +// IsF3ContractActivationDisabled checks if F3 activation is disabled for the given contract address +// based on environment variable configuration. +func IsF3ContractActivationDisabled(contract string) bool { + contracts, _ := parseF3DisableActivationEnv() + return slices.Contains(contracts, contract) +} diff --git a/pkg/vf3/manifest.go b/pkg/vf3/manifest.go index 99cc8595cb..791ff5beed 100644 --- a/pkg/vf3/manifest.go +++ b/pkg/vf3/manifest.go @@ -23,6 +23,7 @@ import ( "github.com/filecoin-project/go-f3/manifest" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/venus/pkg/chain" + "github.com/filecoin-project/venus/pkg/constants" "github.com/filecoin-project/venus/venus-shared/types" must "github.com/filecoin-project/venus/venus-shared/utils" ) @@ -54,11 +55,26 @@ func NewManifestProvider(ctx context.Context, f3InitialPowerTableCID cid.Cid, ) (prov manifest.ManifestProvider, err error) { var primaryManifest manifest.ManifestProvider - if config.StaticManifest != nil { - log.Infof("using static maniest as primary") + + // Check if static manifest activation is disabled + staticDisabled := false + if config.StaticManifest != nil && constants.IsF3EpochActivationDisabled(config.StaticManifest.BootstrapEpoch) { + log.Warnf("F3 activation disabled by environment configuration for bootstrap epoch %d", config.StaticManifest.BootstrapEpoch) + staticDisabled = true + } + + // Check if contract manifest activation is disabled + contractDisabled := false + if config.ContractAddress != "" && constants.IsF3ContractActivationDisabled(config.ContractAddress) { + log.Warnf("F3 activation disabled by environment configuration for contract %s", config.ContractAddress) + contractDisabled = true + } + + if config.StaticManifest != nil && !staticDisabled { + log.Infof("using static manifest as primary") primaryManifest, err = manifest.NewStaticManifestProvider(config.StaticManifest) - } else if config.ContractAddress != "" { - log.Infow("using contract maniest as primary", "address", config.ContractAddress) + } else if config.ContractAddress != "" && !contractDisabled { + log.Infow("using contract manifest as primary", "address", config.ContractAddress) primaryManifest, err = NewContractManifestProvider(ctx, config, stateCaller, f3InitialPowerTableCID) } if err != nil {