-
Notifications
You must be signed in to change notification settings - Fork 49
Shutdown on upgrade #2648
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Shutdown on upgrade #2648
Changes from all commits
3e252c0
3cc2c72
f7642d7
cfee1a5
8af1a2c
74dda30
54d8199
d363119
237c9b4
f123468
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,11 +2,15 @@ package components | |
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
|
|
||
| "github.com/ethereum/go-ethereum/core/types" | ||
| gethlog "github.com/ethereum/go-ethereum/log" | ||
| "github.com/ten-protocol/go-ten/contracts/generated/NetworkConfig" | ||
| "github.com/ten-protocol/go-ten/go/common" | ||
| "github.com/ten-protocol/go-ten/go/common/errutil" | ||
| "github.com/ten-protocol/go-ten/go/enclave/storage" | ||
| "github.com/ten-protocol/go-ten/go/enclave/storage/enclavedb" | ||
| ) | ||
|
|
||
| // NetworkUpgradeConfirmationDepth retained for reference | ||
|
|
@@ -33,8 +37,141 @@ func (um *upgradeManager) RegisterUpgradeHandler(featureName string, handler Upg | |
| // keep API no-op | ||
| } | ||
|
|
||
| func (um *upgradeManager) StoreNetworkUpgrades(ctx context.Context, blockHeader *types.Header, upgrades []NetworkConfig.NetworkConfigUpgraded) error { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be public? |
||
| if len(upgrades) == 0 { | ||
| return nil | ||
| } | ||
|
|
||
| for _, upgrade := range upgrades { | ||
| um.logger.Info("Upgrade detected", "featureName", upgrade.FeatureName, "featureData", upgrade.FeatureData) | ||
| blockHeight := blockHeader.Number.Uint64() + 64 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not use |
||
| blockHeightActive := upgrade.ValidAtBlock.Uint64() | ||
|
|
||
| err := um.storage.StoreNetworkUpgrade(ctx, &enclavedb.NetworkUpgrade{ | ||
| FeatureName: upgrade.FeatureName, | ||
| FeatureData: upgrade.FeatureData, | ||
| BlockHash: blockHeader.Hash(), | ||
| BlockHeightFinal: &blockHeight, | ||
| BlockHeightActive: &blockHeightActive, | ||
| }) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to store network upgrade. Cause: %w", err) | ||
| } | ||
| } | ||
| um.logger.Info("Stored network upgrades", "upgrades", len(upgrades)) | ||
| return nil | ||
| } | ||
|
|
||
| // collectNetworkUpgrades extracts all NetworkConfigUpgraded from L1 data | ||
| func (um *upgradeManager) collectNetworkUpgrades(processed *common.ProcessedL1Data) []NetworkConfig.NetworkConfigUpgraded { | ||
| upgradeTxs := processed.GetEvents(common.NetworkUpgradedTx) | ||
| allUpgrades := make([]NetworkConfig.NetworkConfigUpgraded, 0) | ||
| for _, tx := range upgradeTxs { | ||
| allUpgrades = append(allUpgrades, tx.NetworkUpgrades...) | ||
| } | ||
| return allUpgrades | ||
| } | ||
|
|
||
| // filterSupportedUpgrades filters upgrades to only include supported ones | ||
| func (um *upgradeManager) filterSupportedUpgrades(ctx context.Context, allUpgrades []NetworkConfig.NetworkConfigUpgraded) []NetworkConfig.NetworkConfigUpgraded { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this method feels too hypothetical. |
||
| supportedUpgrades := make([]NetworkConfig.NetworkConfigUpgraded, 0) | ||
| for _, upgrade := range allUpgrades { | ||
| um.logger.Info("Upgrade detected", "featureName", upgrade.FeatureName, "featureData", upgrade.FeatureData) | ||
|
|
||
| // Check if handler is registered for this upgrade | ||
| handlers, ok := um.handlers[upgrade.FeatureName] | ||
| if !ok { | ||
| um.logger.Warn("No handler registered for upgrade, filtering out", "featureName", upgrade.FeatureName) | ||
| continue | ||
| } | ||
|
|
||
| // Check if all handlers support this upgrade | ||
| upgradeSupported := true | ||
| for _, handler := range handlers { | ||
| canUpgrade := handler.CanUpgrade(ctx, upgrade.FeatureName, upgrade.FeatureData) | ||
| if !canUpgrade { | ||
| um.logger.Warn("Upgrade not supported by handler, filtering out", "featureName", upgrade.FeatureName) | ||
| upgradeSupported = false | ||
| break | ||
| } | ||
| } | ||
|
|
||
| if upgradeSupported { | ||
| supportedUpgrades = append(supportedUpgrades, upgrade) | ||
| um.logger.Info("Upgrade supported and included", "featureName", upgrade.FeatureName) | ||
| } | ||
| } | ||
|
|
||
| um.logger.Info("Filtered upgrades", "total", len(allUpgrades), "supported", len(supportedUpgrades)) | ||
| return supportedUpgrades | ||
| } | ||
|
|
||
| func (um *upgradeManager) getUpgradesFor(blockHeader *types.Header) ([]NetworkConfig.NetworkConfigUpgraded, error) { | ||
| ctx := context.Background() | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not pass the context? |
||
|
|
||
| // Ensure the current block is canonical before proceeding | ||
| isCanonical, err := um.storage.IsBlockCanonical(ctx, blockHeader.Hash()) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since this is called from OnL1Block, it means only canonical l1 blocks are sent in. I dont think this check is necessary, maybe just leave a comment |
||
| if err != nil { | ||
| um.logger.Error("Failed to check block canonicality", "hash", blockHeader.Hash(), "error", err) | ||
| return nil, fmt.Errorf("failed to check block canonicality: %w", err) | ||
| } | ||
| if !isCanonical { | ||
| return nil, fmt.Errorf("block %s is not canonical", blockHeader.Hash()) | ||
| } | ||
|
|
||
| // Load activated upgrades up to current block height | ||
| currentHeight := blockHeader.Number.Uint64() | ||
| stored, err := um.storage.GetActivatedNetworkUpgrades(ctx, currentHeight) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't you have to adjust with the 64 constant? |
||
| if err != nil { | ||
| um.logger.Error("Failed to load activated network upgrades from storage", "error", err, "height", currentHeight) | ||
| return nil, fmt.Errorf("failed to load activated network upgrades: %w", err) | ||
| } | ||
|
|
||
| // Filter: only upgrades whose saved block hash is canonical | ||
| candidates := make([]NetworkConfig.NetworkConfigUpgraded, 0) | ||
| for _, u := range stored { | ||
| // The upgrade must have been recorded for a canonical block hash | ||
| upgradeBlockCanonical, err := um.storage.IsBlockCanonical(ctx, u.BlockHash) | ||
| if err != nil { | ||
| um.logger.Error("Failed to check canonicality for upgrade's block", "hash", u.BlockHash, "error", err) | ||
| return nil, fmt.Errorf("failed to check canonicality for upgrade's block: %w", err) | ||
| } | ||
| if !upgradeBlockCanonical { | ||
| continue | ||
| } | ||
|
|
||
| candidates = append(candidates, NetworkConfig.NetworkConfigUpgraded{ | ||
| FeatureName: u.FeatureName, | ||
| FeatureData: u.FeatureData, | ||
| }) | ||
| } | ||
|
|
||
| // Verify all selected upgrades are supported by registered handlers | ||
| supported := um.filterSupportedUpgrades(ctx, candidates) | ||
| if len(supported) != len(candidates) { | ||
| return nil, fmt.Errorf("unsupported upgrades detected at height %d: total=%d supported=%d", currentHeight, len(candidates), len(supported)) | ||
| } | ||
|
|
||
| return supported, nil | ||
| } | ||
|
|
||
| func (um *upgradeManager) OnL1Block(ctx context.Context, blockHeader *types.Header, processed *common.ProcessedL1Data) error { | ||
| // no-op: upgrades disabled | ||
| // Collect all upgrades from L1 data | ||
| allUpgrades := um.collectNetworkUpgrades(processed) | ||
|
|
||
| // Store all upgrades (both supported and unsupported) | ||
| err := um.StoreNetworkUpgrades(ctx, blockHeader, allUpgrades) | ||
| if err != nil { | ||
| um.logger.Error("Failed to store network upgrades", "error", err) | ||
| return err | ||
| } | ||
|
|
||
| _, err = um.getUpgradesFor(blockHeader) | ||
| if err != nil { | ||
| um.logger.Error("Failed to get upgrades for block", "error", err) | ||
| return errutil.ErrUpgradeNotSupported | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wasn't this already merged as a separate pr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah i split it out of this