forked from bnb-chain/bsc
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request bnb-chain#128 from ethereum-optimism/superchain-ve…
…rsion-signal introduce engine_signalSuperchainV1
- Loading branch information
Showing
9 changed files
with
462 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package catalyst | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/ethereum/go-ethereum/log" | ||
"github.com/ethereum/go-ethereum/metrics" | ||
"github.com/ethereum/go-ethereum/params" | ||
) | ||
|
||
var ( | ||
requiredProtocolDeltaGauge = metrics.NewRegisteredGauge("superchain/required/delta", nil) | ||
recommendedProtocolDeltaGauge = metrics.NewRegisteredGauge("superchain/recommended/delta", nil) | ||
) | ||
|
||
type SuperchainSignal struct { | ||
Recommended params.ProtocolVersion `json:"recommended"` | ||
Required params.ProtocolVersion `json:"required"` | ||
} | ||
|
||
func (api *ConsensusAPI) SignalSuperchainV1(signal *SuperchainSignal) (params.ProtocolVersion, error) { | ||
if signal == nil { | ||
log.Info("Received empty superchain version signal", "local", params.OPStackSupport) | ||
return params.OPStackSupport, nil | ||
} | ||
// update metrics and log any warnings/info | ||
requiredProtocolDeltaGauge.Update(int64(params.OPStackSupport.Compare(signal.Required))) | ||
recommendedProtocolDeltaGauge.Update(int64(params.OPStackSupport.Compare(signal.Recommended))) | ||
logger := log.New("local", params.OPStackSupport, "required", signal.Required, "recommended", signal.Recommended) | ||
LogProtocolVersionSupport(logger, params.OPStackSupport, signal.Recommended, "recommended") | ||
LogProtocolVersionSupport(logger, params.OPStackSupport, signal.Required, "required") | ||
|
||
if err := api.eth.HandleRequiredProtocolVersion(signal.Required); err != nil { | ||
log.Error("Failed to handle required protocol version", "err", err, "required", signal.Required) | ||
return params.OPStackSupport, err | ||
} | ||
|
||
return params.OPStackSupport, nil | ||
} | ||
|
||
func LogProtocolVersionSupport(logger log.Logger, local, other params.ProtocolVersion, name string) { | ||
switch local.Compare(other) { | ||
case params.AheadMajor: | ||
logger.Info(fmt.Sprintf("Ahead with major %s protocol version change", name)) | ||
case params.AheadMinor, params.AheadPatch, params.AheadPrerelease: | ||
logger.Debug(fmt.Sprintf("Ahead with compatible %s protocol version change", name)) | ||
case params.Matching: | ||
logger.Debug(fmt.Sprintf("Latest %s protocol version is supported", name)) | ||
case params.OutdatedMajor: | ||
logger.Error(fmt.Sprintf("Outdated with major %s protocol change", name)) | ||
case params.OutdatedMinor: | ||
logger.Warn(fmt.Sprintf("Outdated with minor backward-compatible %s protocol change", name)) | ||
case params.OutdatedPatch: | ||
logger.Info(fmt.Sprintf("Outdated with support backward-compatible %s protocol change", name)) | ||
case params.OutdatedPrerelease: | ||
logger.Debug(fmt.Sprintf("New %s protocol pre-release is available", name)) | ||
case params.DiffBuild: | ||
logger.Debug(fmt.Sprintf("Ignoring %s protocolversion signal, local build is different", name)) | ||
case params.DiffVersionType: | ||
logger.Warn(fmt.Sprintf("Failed to recognize %s protocol version signal version-type", name)) | ||
case params.EmptyVersion: | ||
logger.Debug(fmt.Sprintf("No %s protocol version available to check", name)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package catalyst | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/ethereum/go-ethereum/eth/downloader" | ||
"github.com/ethereum/go-ethereum/eth/ethconfig" | ||
"github.com/ethereum/go-ethereum/node" | ||
"github.com/ethereum/go-ethereum/params" | ||
) | ||
|
||
func TestSignalSuperchainV1(t *testing.T) { | ||
genesis, preMergeBlocks := generateMergeChain(2, false) | ||
n, ethservice := startEthService(t, genesis, preMergeBlocks) | ||
defer n.Close() | ||
api := NewConsensusAPI(ethservice) | ||
t.Run("matching", func(t *testing.T) { | ||
out, err := api.SignalSuperchainV1(&SuperchainSignal{ | ||
Recommended: params.OPStackSupport, | ||
Required: params.OPStackSupport, | ||
}) | ||
if err != nil { | ||
t.Fatalf("failed to process signal: %v", err) | ||
} | ||
if out != params.OPStackSupport { | ||
t.Fatalf("expected %s but got %s", params.OPStackSupport, out) | ||
} | ||
}) | ||
t.Run("null_arg", func(t *testing.T) { | ||
out, err := api.SignalSuperchainV1(nil) | ||
if err != nil { | ||
t.Fatalf("failed to process signal: %v", err) | ||
} | ||
if out != params.OPStackSupport { | ||
t.Fatalf("expected %s but got %s", params.OPStackSupport, out) | ||
} | ||
}) | ||
} | ||
|
||
func TestSignalSuperchainV1Halt(t *testing.T) { | ||
testCases := []struct { | ||
cfg string | ||
bump string | ||
halt bool | ||
}{ | ||
{"none", "major", false}, | ||
{"major", "major", true}, | ||
{"minor", "major", true}, | ||
{"patch", "major", true}, | ||
{"major", "minor", false}, | ||
{"minor", "minor", true}, | ||
{"patch", "minor", true}, | ||
{"major", "patch", false}, | ||
{"minor", "patch", false}, | ||
{"patch", "patch", true}, | ||
} | ||
for _, tc := range testCases { | ||
t.Run(tc.cfg+"_"+tc.bump, func(t *testing.T) { | ||
genesis, preMergeBlocks := generateMergeChain(2, false) | ||
ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256} | ||
ethcfg.RollupHaltOnIncompatibleProtocolVersion = tc.cfg // opt-in to halting (or not) | ||
n, ethservice := startEthServiceWithConfigFn(t, preMergeBlocks, ethcfg) | ||
defer n.Close() // close at the end, regardless of any prior (failed) closing | ||
api := NewConsensusAPI(ethservice) | ||
_, build, major, minor, patch, preRelease := params.OPStackSupport.Parse() | ||
majorSignal, minorSignal, patchSignal := major, minor, patch | ||
switch tc.bump { | ||
case "major": | ||
majorSignal += 1 | ||
case "minor": | ||
minorSignal += 1 | ||
case "patch": | ||
patchSignal += 1 | ||
} | ||
out, err := api.SignalSuperchainV1(&SuperchainSignal{ | ||
Recommended: params.OPStackSupport, // required version change should be enough | ||
Required: params.ProtocolVersionV0{Build: build, Major: majorSignal, Minor: minorSignal, Patch: patchSignal, PreRelease: preRelease}.Encode(), | ||
}) | ||
if err != nil { | ||
t.Fatalf("failed to process signal: %v", err) | ||
} | ||
if out != params.OPStackSupport { | ||
t.Fatalf("expected %s but got %s", params.OPStackSupport, out) | ||
} | ||
closeErr := n.Close() | ||
if tc.halt { | ||
// assert no halt by closing, and not getting any error | ||
if closeErr == nil { | ||
t.Fatalf("expected not to have closed already, but just closed without error") | ||
} | ||
} else { | ||
// assert halt by closing again, and seeing if things error | ||
if closeErr == node.ErrNodeStopped { | ||
t.Fatalf("expected to have already closed and get a ErrNodeStopped error, but got %v", closeErr) | ||
} | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.