Skip to content
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

feat: Add superchainconfig fetched from env variables. #57

Merged
merged 2 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions op-defender/psp_executor/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ func TestHTTPServerHasCorrectRoute(t *testing.T) {
metricsfactory := opmetrics.With(opmetrics.NewRegistry())
mockNodeUrl := "http://rpc.tenderly.co/fork/" // Need to have the "fork" in the URL to avoid mistake for now.
cfg := CLIConfig{
NodeURL: mockNodeUrl,
PortAPI: "8080",
privatekeyflag: GeneratePrivatekey(32),
NodeURL: mockNodeUrl,
PortAPI: "8080",
privatekeyflag: GeneratePrivatekey(32),
SuperChainConfigAddress: "0x1234567890abcdef1234567890abcdef12345678",
}
// Initialize the Defender with necessary mock or real components
defender, err := NewDefender(context.Background(), logger, metricsfactory, cfg, executor)
Expand Down Expand Up @@ -93,9 +94,10 @@ func TestDefenderInitialization(t *testing.T) {
metricsfactory := opmetrics.With(opmetrics.NewRegistry())
mockNodeUrl := "http://rpc.tenderly.co/fork/" // Need to have the "fork" in the URL to avoid mistake for now.
cfg := CLIConfig{
NodeURL: mockNodeUrl,
PortAPI: "8080",
privatekeyflag: GeneratePrivatekey(32),
NodeURL: mockNodeUrl,
PortAPI: "8080",
privatekeyflag: GeneratePrivatekey(32),
SuperChainConfigAddress: "0x1234567890abcdef1234567890abcdef12345678",
}
// Initialize the Defender with necessary mock or real components
_, err := NewDefender(context.Background(), logger, metricsfactory, cfg, executor)
Expand All @@ -115,9 +117,10 @@ func TestHandlePostMockFetch(t *testing.T) {
mockNodeUrl := "http://rpc.tenderly.co/fork/" // Need to have the "fork" in the URL to avoid mistake for now.
executor := &SimpleExecutor{}
cfg := CLIConfig{
NodeURL: mockNodeUrl,
PortAPI: "8080",
privatekeyflag: GeneratePrivatekey(32),
NodeURL: mockNodeUrl,
PortAPI: "8080",
privatekeyflag: GeneratePrivatekey(32),
SuperChainConfigAddress: "0x1234567890abcdef1234567890abcdef12345678",
}

defender, err := NewDefender(context.Background(), logger, metricsfactory, cfg, executor)
Expand Down
40 changes: 26 additions & 14 deletions op-defender/psp_executor/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,45 @@ import (
)

const (
NodeURLFlagName = "rpc.url"
PrivateKeyFlagName = "privatekey"
PortAPIFlagName = "port.api"
ReceiverAddressFlagName = "receiver.address"
DataFlagName = "data"
NodeURLFlagName = "rpc.url"
PrivateKeyFlagName = "privatekey"
PortAPIFlagName = "port.api"
ReceiverAddressFlagName = "receiver.address"
DataFlagName = "data"
SuperChainConfigAddressFlagName = "superchainconfig.address"
)

type CLIConfig struct {
NodeURL string
privatekeyflag string
PortAPI string
ReceiverAddress string
HexString string
NodeURL string
privatekeyflag string
PortAPI string
ReceiverAddress string
HexString string
SuperChainConfigAddress string
}

func ReadCLIFlags(ctx *cli.Context) (CLIConfig, error) {
cfg := CLIConfig{NodeURL: ctx.String(NodeURLFlagName)}
if len(PrivateKeyFlagName) == 0 {
return cfg, fmt.Errorf("must have a PrivateKeyFlagName set to execute the pause on mainnet")
return cfg, fmt.Errorf("must have a PrivateKeyFlagName set to execute the pause.")
}
cfg.privatekeyflag = ctx.String(PrivateKeyFlagName)
if len(PortAPIFlagName) == 0 {
return cfg, fmt.Errorf("must have a PortAPIFlagName set to execute the pause on mainnet")
return cfg, fmt.Errorf("must have a PortAPIFlagName set to execute the pause.")
}
cfg.PortAPI = ctx.String(PortAPIFlagName)
if len(ReceiverAddressFlagName) == 0 {
return cfg, fmt.Errorf("must have a ReceiverAddressFlagName set to receive the pause on mainnet.")
return cfg, fmt.Errorf("must have a ReceiverAddressFlagName set to receive the pause.")
}
cfg.ReceiverAddress = ctx.String(ReceiverAddressFlagName)
if len(DataFlagName) == 0 {
return cfg, fmt.Errorf("must have a `data` set to execute the calldata on mainnet.")
return cfg, fmt.Errorf("must have a `data` set to execute the calldata.")
}
cfg.HexString = ctx.String(DataFlagName)
if len(SuperChainConfigAddressFlagName) == 0 {
return cfg, fmt.Errorf("must have a `SuperChainConfigAddress` to know the current status of the superchainconfig.")
}
cfg.SuperChainConfigAddress = ctx.String(SuperChainConfigAddressFlagName)
return cfg, nil
}

Expand Down Expand Up @@ -81,5 +87,11 @@ func CLIFlags(envPrefix string) []cli.Flag {
EnvVars: opservice.PrefixEnvVar(envPrefix, "CALLDATA"),
Required: false,
},
&cli.StringFlag{
Name: SuperChainConfigAddressFlagName,
Usage: "SuperChainConfig address to know the current status of the superchainconfig.",
EnvVars: opservice.PrefixEnvVar(envPrefix, "SUPERCHAINCONFIG_ADDRESS"),
Required: true,
},
}
}
41 changes: 23 additions & 18 deletions op-defender/psp_executor/defender.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ type Executor interface {

// Defender is a struct that represents the Defender API server.
type Defender struct {
log log.Logger
port string
SuperChainConfigAddress string
l1Client *ethclient.Client
router *mux.Router
executor Executor
privatekey string
log log.Logger
port string
superchainconfig string
l1Client *ethclient.Client
router *mux.Router
executor Executor
privatekey string
// metrics
latestPspNonce *prometheus.GaugeVec
unexpectedRpcErrors *prometheus.CounterVec
Expand Down Expand Up @@ -141,12 +141,13 @@ func (d *Defender) handlePost(w http.ResponseWriter, r *http.Request) {
// NewAPI creates a new HTTP API Server for the PSP Executor and starts listening on the specified port from the args passed.
func NewDefender(ctx context.Context, log log.Logger, m metrics.Factory, cfg CLIConfig, executor Executor) (*Defender, error) {
// Set the route and handler function for the `/api/psp_execution` endpoint.
println("============================ Configuration Info ================================")
log.Info("============================ Configuration Info ================================")
log.Info("cfg.nodeurl", "cfg.nodeurl", cfg.NodeURL)
log.Info("cfg.portapi", "cfg.portapi", cfg.PortAPI)
log.Info("cfg.receiveraddress", "cfg.receiveraddress", cfg.ReceiverAddress)
log.Info("cfg.hexstring", "cfg.hexstring", cfg.HexString)
println("============================================================================")
log.Info("cfg.SuperChainConfigAddress", "cfg.SuperChainConfigAddress", cfg.SuperChainConfigAddress)
log.Info("===============================================================================")

l1client, err := CheckAndReturnRPC(cfg.NodeURL) //@todo: Need to check if the latest blocknumber returned is 0.

Expand All @@ -161,13 +162,17 @@ func NewDefender(ctx context.Context, log log.Logger, m metrics.Factory, cfg CLI
if cfg.PortAPI == "" {
return nil, fmt.Errorf("port.api is not set.")
}
if cfg.SuperChainConfigAddress == "" {
return nil, fmt.Errorf("superchainconfig.address is not set.")
}

defender := &Defender{
log: log,
l1Client: l1client,
port: cfg.PortAPI,
executor: executor,
privatekey: privatekey,
log: log,
l1Client: l1client,
port: cfg.PortAPI,
executor: executor,
privatekey: privatekey,
superchainconfig: cfg.SuperChainConfigAddress,
}
defender.router = mux.NewRouter()
defender.router.HandleFunc("/api/psp_execution", func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -183,12 +188,12 @@ func NewDefender(ctx context.Context, log log.Logger, m metrics.Factory, cfg CLI
// In the future, the function will fetch the PSPs from a secret file and execute it onchain through a EVM transaction.
func (e *DefenderExecutor) FetchAndExecute(d *Defender) {
ctx := context.Background()
configAddress, safeAddress, data, err := FetchPSPInGCP()
safeAddress, data, err := FetchPSPInGCP()
if err != nil {
d.log.Crit("Failed to fetch PSP data from GCP", "error", err)
return
}
PspExecutionOnChain(ctx, d.l1Client, configAddress, d.privatekey, safeAddress, data)
PspExecutionOnChain(ctx, d.l1Client, d.superchainconfig, d.privatekey, safeAddress, data)
}

// CheckAndReturnRPC() will return the L1 client based on the RPC provided in the config and ensure that the RPC is not production one.
Expand Down Expand Up @@ -239,9 +244,9 @@ func isValidHexString(s string) bool {
}

// FetchPSPInGCP() will fetch the correct PSPs into GCP and return the Data.
func FetchPSPInGCP() (string, string, []byte, error) {
func FetchPSPInGCP() (string, []byte, error) {
//In the future, we need to check first the nonce and then `checkPauseStatus` and then return the data for the latest PSPs.
return "0xC2Be75506d5724086DEB7245bd260Cc9753911Be", "0x4141414142424242414141414242424241414141", []byte{0x41, 0x42, 0x43}, nil
return "0x4141414142424242414141414242424241414141", []byte{0x41, 0x42, 0x43}, nil
}

// PSPexecution(): PSPExecutionOnChain is a core function that will check that status of the superchain is not paused and then send onchain transaction to pause the superchain.
Expand Down