Skip to content

Commit

Permalink
Last fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranbt committed Nov 28, 2023
1 parent 78d1b54 commit 90959f7
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 14 deletions.
1 change: 1 addition & 0 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
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
26 changes: 22 additions & 4 deletions core/vm/contracts_suave.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"

Expand Down Expand Up @@ -146,17 +147,34 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error)
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 {
prts := strings.Split(header, ":")
if len(prts) != 2 {
return nil, fmt.Errorf("incorrect header format")
indx := strings.Index(header, ":")
if indx == -1 {
return nil, fmt.Errorf("incorrect header format '%s', no ':' present", header)
}
req.Header.Add(prts[0], prts[1])
req.Header.Add(header[:indx], header[indx+1:])
}

client := &http.Client{
Expand Down
10 changes: 5 additions & 5 deletions core/vm/contracts_suave_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,8 @@ func (b *suaveRuntime) submitEthBlockBidToRelay(relayUrl string, builderBidJson
Url: endpoint,
Body: builderBidJson,
Headers: []string{
"Content-Type: application/json",
"Accept: application/json",
"Content-Type:application/json",
"Accept:application/json",
},
}
if _, err := b.doHTTPRequest(httpReq); err != nil {
Expand Down Expand Up @@ -363,9 +363,9 @@ func (c *suaveRuntime) submitBundleJsonRPC(url string, method string, params []b
Url: url,
Body: body,
Headers: []string{
"Content-Type: application/json",
"Accept: application/json",
"X-Flashbots-Signature: " + signature,
"Content-Type:application/json",
"Accept:application/json",
"X-Flashbots-Signature:" + signature,
},
}
if _, err := c.doHTTPRequest(httpReq); err != nil {
Expand Down
20 changes: 18 additions & 2 deletions core/vm/contracts_suave_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,14 @@ func (h *httpTestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok1"))
}

func TestSuave_HttpRequest(t *testing.T) {
s := &suaveRuntime{}
func TestSuave_HttpRequest_Basic(t *testing.T) {
s := &suaveRuntime{
suaveContext: &SuaveContext{
Backend: &SuaveExecutionBackend{
ExternalWhitelist: []string{"127.0.0.1"},
},
},
}

srv := httptest.NewServer(&httpTestHandler{})
defer srv.Close()
Expand All @@ -300,6 +306,11 @@ func TestSuave_HttpRequest(t *testing.T) {
req: types.HttpRequest{Url: srv.URL},
err: true,
},
{
// url not allowed
req: types.HttpRequest{Url: "http://example.com", Method: "GET"},
err: true,
},
{
// incorrect header format
req: types.HttpRequest{Url: srv.URL, Method: "GET", Headers: []string{"a"}},
Expand All @@ -325,6 +336,11 @@ func TestSuave_HttpRequest(t *testing.T) {
req: types.HttpRequest{Url: srv.URL, Method: "POST", Headers: []string{"a:c"}},
resp: []byte("c"),
},
{
// POST request with headers with multiple :
req: types.HttpRequest{Url: srv.URL, Method: "POST", Headers: []string{"a:c:d"}},
resp: []byte("c:d"),
},
{
// POST with error
req: types.HttpRequest{Url: srv.URL, Method: "POST", Headers: []string{"fail:1"}},
Expand Down
1 change: 1 addition & 0 deletions core/vm/suave.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type SuaveContext struct {
type SuaveExecutionBackend struct {
EthBundleSigningKey *ecdsa.PrivateKey
EthBlockSigningKey *bls.SecretKey
ExternalWhitelist []string
ConfidentialStore ConfidentialStore
ConfidentialEthBackend suave.ConfidentialEthBackend
}
Expand Down
3 changes: 3 additions & 0 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type EthAPIBackend struct {
suaveEthBlockSigningKey *bls.SecretKey
suaveEngine *cstore.ConfidentialStoreEngine
suaveEthBackend suave.ConfidentialEthBackend
suaveExternalWhitelist []string
}

// For testing purposes
Expand Down Expand Up @@ -293,6 +294,7 @@ func (b *EthAPIBackend) GetMEVM(ctx context.Context, msg *core.Message, state *s
suaveCtxCopy.Backend = &vm.SuaveExecutionBackend{
EthBundleSigningKey: suaveCtx.Backend.EthBundleSigningKey,
EthBlockSigningKey: suaveCtx.Backend.EthBlockSigningKey,
ExternalWhitelist: suaveCtx.Backend.ExternalWhitelist,
ConfidentialStore: storeTransaction,
ConfidentialEthBackend: b.suaveEthBackend,
}
Expand Down Expand Up @@ -449,6 +451,7 @@ func (b *EthAPIBackend) SuaveContext(requestTx *types.Transaction, ccr *types.Co
Backend: &vm.SuaveExecutionBackend{
EthBundleSigningKey: b.suaveEthBundleSigningKey,
EthBlockSigningKey: b.suaveEthBlockSigningKey,
ExternalWhitelist: b.suaveExternalWhitelist,
ConfidentialStore: storeTransaction,
ConfidentialEthBackend: b.suaveEthBackend,
},
Expand Down
2 changes: 1 addition & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {

confidentialStoreEngine := cstore.NewConfidentialStoreEngine(confidentialStoreBackend, confidentialStoreTransport, suaveDaSigner, types.LatestSigner(chainConfig))

eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil, suaveEthBundleSigningKey, suaveEthBlockSigningKey, confidentialStoreEngine, suaveEthBackend}
eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil, suaveEthBundleSigningKey, suaveEthBlockSigningKey, confidentialStoreEngine, suaveEthBackend, config.Suave.ExternalWhitelist}
if eth.APIBackend.allowUnprotectedTxs {
log.Info("Unprotected transactions allowed")
}
Expand Down
1 change: 1 addition & 0 deletions suave/core/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type Config struct {
PebbleDbPath string
EthBundleSigningKeyHex string
EthBlockSigningKeyHex string
ExternalWhitelist []string
}

var DefaultConfig = Config{}
22 changes: 20 additions & 2 deletions suave/e2e/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,7 @@ func TestE2EOnChainStateTransition(t *testing.T) {
}

func TestE2ERemoteCalls(t *testing.T) {
fr := newFramework(t)
fr := newFramework(t, WithWhitelist([]string{"127.0.0.1"}))
defer fr.Close()

clt := fr.NewSDKClient()
Expand Down Expand Up @@ -1164,6 +1164,16 @@ func TestE2ERemoteCalls(t *testing.T) {
}
contract.SendTransaction("remoteCall", []interface{}{req}, nil)
})

t.Run("Not whitelisted", func(t *testing.T) {
req := &types.HttpRequest{
Method: "POST",
Url: "http://example.com",
Headers: []string{"b:c"},
}
_, err := contract.SendTransaction("remoteCall", []interface{}{req}, nil)
require.Error(t, err)
})
}

type clientWrapper struct {
Expand Down Expand Up @@ -1221,7 +1231,9 @@ type frameworkConfig struct {
var defaultFrameworkConfig = frameworkConfig{
kettleAddress: false,
redisStoreBackend: false,
suaveConfig: suave.Config{},
suaveConfig: suave.Config{
ExternalWhitelist: []string{"*"},
},
}

type frameworkOpt func(*frameworkConfig)
Expand Down Expand Up @@ -1261,6 +1273,12 @@ func WithBlockSigningKeyOpt(t *testing.T) (frameworkOpt, *bls.PublicKey) {
}, pk
}

func WithWhitelist(whitelist []string) frameworkOpt {
return func(c *frameworkConfig) {
c.suaveConfig.ExternalWhitelist = whitelist
}
}

func newFramework(t *testing.T, opts ...frameworkOpt) *framework {
cfg := defaultFrameworkConfig
for _, opt := range opts {
Expand Down

0 comments on commit 90959f7

Please sign in to comment.