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

Add a onchain execution on forked network with Hardcoded values. #54

Merged
merged 19 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ba73d89
remove the authentication and execute a hardcoded transaction when cU…
Ethnical Aug 19, 2024
f0797b1
refactor: functions to add them as module of the `defender` struct.
Ethnical Aug 19, 2024
0383a17
refactor: clean code.
Ethnical Aug 20, 2024
2748955
feat: executor to mock object during testing
Ethnical Aug 28, 2024
a1743f5
refactor: Previous test are now working with the new executor mocking…
Ethnical Aug 28, 2024
e4dc520
gitignore: ignore the `run.sh` that is used with `.air.toml`.
Ethnical Aug 28, 2024
6889ef5
refactor: and the clean the code
Ethnical Aug 29, 2024
017aeca
feat: add the unit tests `TestHTTPServerHasOnlyPSPExecutionRoute` and…
Ethnical Aug 29, 2024
dc3af04
docs: update the docs of the current functions.
Ethnical Aug 29, 2024
bed5f84
docs: update the docs with necessaries fields
Ethnical Aug 30, 2024
a33efd7
refactor: clean up the codes + remove the `calldata` fields that is n…
Ethnical Aug 30, 2024
b55a4e6
docs: fix docs with typos
Ethnical Aug 30, 2024
cf7049c
remove the calldata from the tests
Ethnical Aug 30, 2024
73b8398
docs: improve the readme with the tab and the field used for the each…
Ethnical Aug 30, 2024
29cc01c
docs: improve the docs
Ethnical Aug 30, 2024
927def6
chore: fix alignement
Ethnical Aug 30, 2024
41cd2ac
Update op-defender/psp_executor/defender.go
Ethnical Aug 30, 2024
2e28dd5
Update op-defender/psp_executor/api_test.go
Ethnical Aug 30, 2024
d3e5ec3
refactor: replace `expectedErr` to `expectErr`.
Ethnical Aug 30, 2024
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
71 changes: 47 additions & 24 deletions op-defender/psp_executor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,60 @@

The PSP Executor service is a service designed to execute PSP onchain faster to increase our readiness and speed in case of incident response.

The service is design to listen on a port and execute a PSP onchain when a request is received.
The service is designed to listen on a port and execute a PSP onchain when a request is received.

⚠️ The service as to use a authentification method before calling this API ⚠️
⚠️ The service has to use an authentication method before calling this API ⚠️

### Options and Configuration
## 1. Usage

### 1 .Run HTTP API service

To start the HTTP API service we can use the following oneliner command:
![f112841bad84c59ea3ed1ca380740f5694f553de8755b96b1a40ece4d1c26f81](https://github.com/user-attachments/assets/17235e99-bf25-40a5-af2c-a0d9990c6276)
Settings of the HTTP API service:

| Port | API Path | HTTP Method |
| ----------------------------- | -------------------- | ----------- |
| 8080 (Default can be changed) | `/api/psp_execution` | POST |

```shell
go run ../cmd/defender psp_executor --privatekey XXXXXX --receiver.address 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF --rpc.url http://localhost:8545 --port.api 8080
```

### 2. Request the HTTP API

To use the HTTP API you can use the following `curl` command with the following fields:

![image](https://github.com/user-attachments/assets/3edc2ee5-6dfd-4872-9bc6-e3ead7444a96)

```bash
curl -X POST http://${HTTP_API_PSP}:${PORT}/api/psp_execution \-H "Content-Type: application/json" \-d '{"pause": true, "timestamp": 1719432011, "operator": "Tom"}'
```

Explanation of the _mandatory_ fields:
| Field | Description |
| --------- | -------------------------------------------------------------------------------- |
| pause | A boolean value indicating whether to pause (true) or unpause (false) the SuperchainConfig.|
| timestamp | The Unix timestamp when the request is made. |
| operator | The name or identifier of the person initiating the PSP execution. |

### 3. Metrics Server

To monitor the _PSPexecutor service_ the metrics server can be enabled. The metrics server will expose the metrics on the specified address and port.
The metrics are using **Prometheus** and can be set with the following options:
| Option | Description | Default Value | Environment Variable |
| ------------------- | ------------------------- | ------------- | ----------------------------- |
| `--metrics.enabled` | Enable the metrics server | `false` | `$MONITORISM_METRICS_ENABLED` |
| `--metrics.addr` | Metrics listening address | `"0.0.0.0"` | `$MONITORISM_METRICS_ADDR` |
| `--metrics.port` | Metrics listening port | `7300` | `$MONITORISM_METRICS_PORT` |

### 4. Options and Configuration

The current options are the following:

```
OPTIONS:
--rpc-url value Node URL of a peer (default: "http://127.0.0.1:8545") [$PSPEXECUTOR_MON_NODE_URL]
--rpc.url value Node URL of a peer (default: "http://127.0.0.1:8545") [$PSPEXECUTOR_MON_NODE_URL]
--privatekey value Private key of the account that will issue the pause () [$PSPEXECUTOR_MON_PRIVATE_KEY]
--receiver.address value The receiver address of the pause request. [$PSPEXECUTOR_MON_RECEIVER_ADDRESS]
--port.api value Port of the API server you want to listen on (e.g. 8080). (default: "8080") [$PSPEXECUTOR_MON_PORT_API]
Expand All @@ -26,23 +69,3 @@ OPTIONS:
--loop.interval.msec value Loop interval of the monitor in milliseconds (default: 60000) [$MONITORISM_LOOP_INTERVAL_MSEC]
--help, -h show help
```

## Usage
### HTTP API service
To start the HTTP API service we can use the following oneliner command:
![f112841bad84c59ea3ed1ca380740f5694f553de8755b96b1a40ece4d1c26f81](https://github.com/user-attachments/assets/17235e99-bf25-40a5-af2c-a0d9990c6276)

```shell
go run ../cmd/defender psp_executor --privatekey XXXXXX --receiver.address 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF --rpc.url http://localhost:8545 --port.api 8080
```

### cURL HTTP API

To use the HTTP API you can use the following `curl` command:

![image](https://github.com/user-attachments/assets/3edc2ee5-6dfd-4872-9bc6-e3ead7444a96)

```bash
curl -X POST http://${HTTP_API_PSP}:${PORT}/api/psp_execution \-H "Content-Type: application/json" \-d '{"pause": true, "timestamp": 1719432011, "operator": "Tom"}'
```

18 changes: 9 additions & 9 deletions op-defender/psp_executor/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ func TestHandlePostMockFetch(t *testing.T) {
{
path: "/api/psp_execution",
name: "Valid Request", // Check if the request is valid as expected return the 200 status code.
body: `{"pause":true,"timestamp":1596240000,"operator":"0x123","calldata":"0xabc"}`,
body: `{"pause":true,"timestamp":1596240000,"operator":"0x123"}`,
expectedStatus: http.StatusOK,
},
{
path: "/api/psp_execution",
name: "Invalid JSON", // Check if the JSON is invalid return the 400 status code.
body: `{"pause":true, "timestamp":"invalid","operator":"0x123"}`,
body: `{"pause":true, "timestamp":"invalid","operator":}`,
expectedStatus: http.StatusBadRequest,
},
{
Expand All @@ -133,7 +133,7 @@ func TestHandlePostMockFetch(t *testing.T) {
{
path: "/api/",
name: "Incorrect Path Fields", // Check if the path is incorrect return the 404 status code.
body: `{"pause":true,"timestamp":1596240000,"operator":"0x123","calldata":"0xabc"}`,
body: `{"pause":true,"timestamp":1596240000,"operator":"0x123"}`,
expectedStatus: http.StatusNotFound,
},
}
Expand Down Expand Up @@ -162,9 +162,9 @@ func TestHandlePostMockFetch(t *testing.T) {
// TestCheckAndReturnRPC tests that the CheckAndReturnRPC function returns the correct client or error for an incorrect URL provided.
func TestCheckAndReturnRPC(t *testing.T) {
tests := []struct {
name string
rpcURL string
wantErr bool
name string
rpcURL string
expectedErr bool
Ethnical marked this conversation as resolved.
Show resolved Hide resolved
}{
{"Empty URL", "", true},
{"Production URL", "https://mainnet.infura.io", true},
Expand All @@ -174,11 +174,11 @@ func TestCheckAndReturnRPC(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client, err := CheckAndReturnRPC(tt.rpcURL)
if (err != nil) != tt.wantErr {
t.Errorf("CheckAndReturnRPC() error = %v, wantErr %v", err, tt.wantErr)
if (err != nil) != tt.expectedErr {
Ethnical marked this conversation as resolved.
Show resolved Hide resolved
t.Errorf("CheckAndReturnRPC() error = %v, expectedErr %v", err, tt.expectedErr)
Ethnical marked this conversation as resolved.
Show resolved Hide resolved
return
}
if !tt.wantErr && client == nil {
if !tt.expectedErr && client == nil {
Ethnical marked this conversation as resolved.
Show resolved Hide resolved
t.Errorf("CheckAndReturnRPC() returned nil client for valid URL")
}
})
Expand Down
8 changes: 4 additions & 4 deletions op-defender/psp_executor/defender.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type DefenderExecutor struct{}

// Executor is an interface that defines the FetchAndExecute method.
type Executor interface {
FetchAndExecute(d *Defender)
FetchAndExecute(d *Defender) // For doc see the `FetchAndExecute()` function.
}

// Defender is a struct that represents the Defender API server.
Expand All @@ -71,7 +71,6 @@ type RequestData struct {
Pause bool `json:"pause"`
Timestamp int64 `json:"timestamp"`
Operator string `json:"operator"`
Calldata string `json:"calldata"` //temporary field as the calldata will be fetched from the GCP in the future (so will be removed in the future PR).
}

// handlePost handles POST requests and processes the JSON body
Expand All @@ -85,7 +84,7 @@ func (d *Defender) handlePost(w http.ResponseWriter, r *http.Request) {
return
}
//check that all the fields are set
if data.Pause == false || data.Timestamp == 0 || data.Operator == "" || data.Calldata == "" {
if data.Pause == false || data.Timestamp == 0 || data.Operator == "" {
http.Error(w, "Missing fields in the request", http.StatusBadRequest)
return
}
Expand Down Expand Up @@ -120,7 +119,8 @@ func NewDefender(ctx context.Context, log log.Logger, m metrics.Factory, cfg CLI
}

// FetchAndExecute() will fetch the PSP and execute it this onchain.
// For now the function is now fully implemented and will make a dummy transaction on chain (see `pspExecutionOnChain()`).
// For now, the function is now fully implemented and will make a dummy transaction on chain (see `pspExecutionOnChain()`).
Ethnical marked this conversation as resolved.
Show resolved Hide resolved
// 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()
privateKey, err := FetchPrivateKeyInGcp()
Expand Down