Skip to content

Commit

Permalink
Merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranbt committed Dec 19, 2023
2 parents edbb090 + 98fcf38 commit 559c3c6
Show file tree
Hide file tree
Showing 22 changed files with 465 additions and 77 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ^1.20
go-version: 1.21.1
id: go

- name: Check out code into the Go module directory
Expand Down
20 changes: 11 additions & 9 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ var (
utils.SuaveConfidentialStorePebbleDbPathFlag,
utils.SuaveEthBundleSigningKeyFlag,
utils.SuaveEthBlockSigningKeyFlag,
utils.SuaveExternalWhitelistFlag,
utils.SuaveDevModeFlag,
}
)
Expand Down Expand Up @@ -271,6 +272,16 @@ func main() {
// prepare manipulates memory cache allowance and setups metric system.
// This function should be called before launching devp2p stack.
func prepare(ctx *cli.Context) {
if err := prepareSuaveDev(ctx); err != nil {
log.Error("failed to setup suave dev mode", "err", err)
os.Exit(1)
}

if err := prepareSuaveNetworksRemapping(ctx); err != nil {
log.Error("failed to setup suave networks remapping", "err", err)
os.Exit(1)
}

// If we're running a known preset, log it for convenience.
switch {
case ctx.IsSet(utils.RinkebyFlag.Name):
Expand Down Expand Up @@ -340,14 +351,6 @@ func geth(ctx *cli.Context) error {
return fmt.Errorf("invalid command: %q", args[0])
}

if err := prepareSuaveDev(ctx); err != nil {
return fmt.Errorf("failed to setup suave development mode: %v", err)
}

if err := prepareSuaveNetworksRemapping(ctx); err != nil {
return err
}

prepare(ctx)
stack, backend := makeFullNode(ctx)
defer stack.Close()
Expand Down Expand Up @@ -531,7 +534,6 @@ func prepareSuaveDev(ctx *cli.Context) error {
utils.DeveloperFlag.Name: "true",
utils.DeveloperGasLimitFlag.Name: "30000000",
utils.HTTPEnabledFlag.Name: "true",
utils.HTTPPortFlag.Name: "8545",
utils.HTTPVirtualHostsFlag.Name: "*",
utils.HTTPCORSDomainFlag.Name: "*",
utils.WSEnabledFlag.Name: "true",
Expand Down
19 changes: 19 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,13 @@ var (
Category: flags.SuaveCategory,
}

SuaveExternalWhitelistFlag = &cli.StringSliceFlag{
Name: "suave.eth.external-whitelist",
EnvVars: []string{"SUAVE_EXTERNAL_WHITELIST"},
Usage: "List of external whitelisted addresses",
Category: flags.SuaveCategory,
}

SuaveDevModeFlag = &cli.BoolFlag{
Name: "suave.dev",
Usage: "Dev mode for suave",
Expand Down Expand Up @@ -1736,6 +1743,18 @@ func SetSuaveConfig(ctx *cli.Context, stack *node.Node, cfg *suave.Config) {
if ctx.IsSet(SuaveEthBlockSigningKeyFlag.Name) {
cfg.EthBlockSigningKeyHex = ctx.String(SuaveEthBlockSigningKeyFlag.Name)
}

if ctx.IsSet(SuaveEthBundleSigningKeyFlag.Name) {
cfg.EthBundleSigningKeyHex = ctx.String(SuaveEthBundleSigningKeyFlag.Name)
}

if ctx.IsSet(SuaveExternalWhitelistFlag.Name) {
cfg.ExternalWhitelist = ctx.StringSlice(SuaveEthBundleSigningKeyFlag.Name)
if len(cfg.ExternalWhitelist) == 0 {
// As of now, default to wildcard
cfg.ExternalWhitelist = []string{"*"}
}
}
}

// SetEthConfig applies eth-related command line flags to the config.
Expand Down
9 changes: 8 additions & 1 deletion core/types/suave_structs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 68 additions & 5 deletions core/vm/contracts_suave.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package vm

import (
"bytes"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"

"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -123,13 +128,71 @@ func mustParseMethodAbi(data string, method string) abi.Method {
return inoutAbi.Methods[method]
}

func formatPeekerError(format string, args ...any) ([]byte, error) {
err := fmt.Errorf(format, args...)
return []byte(err.Error()), err
}

type suaveRuntime struct {
suaveContext *SuaveContext
}

var _ SuaveRuntime = &suaveRuntime{}

func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error) {
if request.Method != "GET" && request.Method != "POST" {
return nil, fmt.Errorf("only GET and POST methods are supported")
}
if request.Url == "" {
return nil, fmt.Errorf("url is empty")
}

var body io.Reader
if request.Body != nil {
body = bytes.NewReader(request.Body)
}

// decode the url and check if the domain is allowed
parsedURL, err := url.Parse(request.Url)
if err != nil {
panic(err)
}

var allowed bool
for _, allowedDomain := range s.suaveContext.Backend.ExternalWhitelist {
if allowedDomain == "*" || allowedDomain == parsedURL.Hostname() {
allowed = true
break
}
}
if !allowed {
return nil, fmt.Errorf("domain %s is not allowed", parsedURL.Hostname())
}

req, err := http.NewRequest(request.Method, request.Url, body)
if err != nil {
return nil, err
}

for _, header := range request.Headers {
indx := strings.Index(header, ":")
if indx == -1 {
return nil, fmt.Errorf("incorrect header format '%s', no ':' present", header)
}
req.Header.Add(header[:indx], header[indx+1:])
}

client := &http.Client{
Timeout: 5 * time.Second, // TODO: test
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

if resp.StatusCode > 299 {
return nil, fmt.Errorf("http error: %s: %v", resp.Status, data)
}
return data, nil
}
76 changes: 22 additions & 54 deletions core/vm/contracts_suave_eth.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package vm

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"math/big"
"net/http"
"time"
Expand Down Expand Up @@ -280,35 +278,19 @@ func (b *suaveRuntime) buildEthBlock(blockArgs types.BuildBlockArgs, dataID type
}

func (b *suaveRuntime) submitEthBlockBidToRelay(relayUrl string, builderBidJson []byte) ([]byte, error) {
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(3*time.Second))
defer cancel()

endpoint := relayUrl + "/relay/v1/builder/blocks"
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(builderBidJson))
if err != nil {
return formatPeekerError("could not prepare request to relay: %w", err)
}

req.Header.Add("Content-Type", "application/json")

// Execute request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return formatPeekerError("could not send request to relay: %w", err)
httpReq := types.HttpRequest{
Method: http.MethodPost,
Url: endpoint,
Body: builderBidJson,
Headers: []string{
"Content-Type:application/json",
"Accept:application/json",
},
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusNoContent {
return nil, nil
}

if resp.StatusCode > 299 {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return formatPeekerError("could not read error response body for status code %d: %w", resp.StatusCode, err)
}

return formatPeekerError("relay request failed with code %d: %s", resp.StatusCode, string(bodyBytes))
if _, err := b.doHTTPRequest(httpReq); err != nil {
return nil, err
}

return nil, nil
Expand Down Expand Up @@ -356,9 +338,6 @@ func executableDataToCapellaExecutionPayload(data *engine.ExecutableData) (*spec
}

func (c *suaveRuntime) submitBundleJsonRPC(url string, method string, params []byte) ([]byte, error) {
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(3*time.Second))
defer cancel()

request := map[string]interface{}{
"id": json.RawMessage([]byte("1")),
"jsonrpc": "2.0",
Expand All @@ -379,29 +358,18 @@ func (c *suaveRuntime) submitBundleJsonRPC(url string, method string, params []b

signature := crypto.PubkeyToAddress(c.suaveContext.Backend.EthBundleSigningKey.PublicKey).Hex() + ":" + hexutil.Encode(sig)

req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(body))
if err != nil {
return formatPeekerError("could not prepare request to relay: %w", err)
}

req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
req.Header.Add("X-Flashbots-Signature", signature)

// Execute request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return formatPeekerError("could not send request to relay: %w", err)
}
defer resp.Body.Close()

if resp.StatusCode > 299 {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return formatPeekerError("request failed with code %d", resp.StatusCode)
}

return formatPeekerError("request failed with code %d: %s", resp.StatusCode, string(bodyBytes))
httpReq := types.HttpRequest{
Method: http.MethodPost,
Url: url,
Body: body,
Headers: []string{
"Content-Type:application/json",
"Accept:application/json",
"X-Flashbots-Signature:" + signature,
},
}
if _, err := c.doHTTPRequest(httpReq); err != nil {
return nil, err
}

return nil, nil
Expand Down
Loading

0 comments on commit 559c3c6

Please sign in to comment.