Skip to content

Commit

Permalink
Add precompile httpRequest2 that returns whole response (#286)
Browse files Browse the repository at this point in the history
* Add precompile httpRequest2 that returns whole response

* Update foundry
  • Loading branch information
ferranbt authored Dec 4, 2024
1 parent cae71b7 commit 06b7e72
Show file tree
Hide file tree
Showing 14 changed files with 170 additions and 21 deletions.
8 changes: 7 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.

36 changes: 24 additions & 12 deletions core/vm/contracts_suave.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,12 @@ func (c *consoleLogPrecompile) Run(input []byte) ([]byte, error) {

var contextCookieKeyPrefix = "__cookie_"

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

var body io.Reader
Expand All @@ -234,11 +234,11 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error)

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

// add any cookies stored in the context
Expand All @@ -251,7 +251,7 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error)
for _, header := range request.Headers {
indx := strings.Index(header, ":")
if indx == -1 {
return nil, fmt.Errorf("incorrect header format '%s', no ':' present", header)
return types.HttpResponse{}, fmt.Errorf("incorrect header format '%s', no ':' present", header)
}
req.Header.Add(header[:indx], header[indx+1:])
}
Expand All @@ -261,7 +261,7 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error)
hashedBody := crypto.Keccak256Hash(request.Body).Hex()
sig, err := crypto.Sign(accounts.TextHash([]byte(hashedBody)), s.suaveContext.Backend.EthBundleSigningKey)
if err != nil {
return nil, err
return types.HttpResponse{}, err
}

signature := crypto.PubkeyToAddress(s.suaveContext.Backend.EthBundleSigningKey.PublicKey).Hex() + ":" + hexutil.Encode(sig)
Expand All @@ -280,17 +280,18 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
return types.HttpResponse{}, err
}
defer resp.Body.Close()

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

if resp.StatusCode > 299 {
return nil, fmt.Errorf("http error: %s: %v", resp.Status, data)
precResp := types.HttpResponse{
Status: uint64(resp.StatusCode),
Body: data,
}

// parse the LB cookies (AWSALB, AWSALBCORS) and set them in the context
Expand All @@ -300,7 +301,18 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error)
}
}

return data, nil
return precResp, nil
}

func (m *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error) {
resp, err := m.doHTTPRequest2(request)
if err != nil {
return nil, err
}
if resp.Status > 299 {
return nil, fmt.Errorf("http error: %d: %v", resp.Status, resp.Body)
}
return resp.Body, err
}

func (s *suaveRuntime) resolveURL(urlOrServiceName string) (string, error) {
Expand Down
52 changes: 50 additions & 2 deletions core/vm/contracts_suave_runtime_adapter.go

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

4 changes: 4 additions & 0 deletions core/vm/contracts_suave_runtime_adapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ func (m *mockRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error) {
return []byte{0x1}, nil
}

func (m *mockRuntime) doHTTPRequest2(request types.HttpRequest) (types.HttpResponse, error) {
return types.HttpResponse{}, nil
}

func (m *mockRuntime) newBuilder() (string, error) {
return "", nil
}
Expand Down
2 changes: 1 addition & 1 deletion suave/artifacts/SuaveLib.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion suave/artifacts/addresses.go

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

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"042632033115408fe18db1103f7f7c21","source_id_to_path":{"0":"lib/forge-std/src/console2.sol","1":"sol/libraries/Suave.sol","2":"sol/standard_peekers/bundles.sol","3":"sol/standard_peekers/example.sol"},"language":"Solidity"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"id":"a7b739ab8239814d5bc9f53cf4bf4268","source_id_to_path":{"0":"lib/forge-std/src/console2.sol","1":"sol/libraries/Suave.sol","2":"sol/standard_peekers/bundles.sol","3":"sol/standard_peekers/example.sol"},"language":"Solidity"}
19 changes: 18 additions & 1 deletion suave/e2e/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1191,7 +1191,7 @@ func TestE2EConsoleLog(t *testing.T) {
require.NoError(t, err)
}

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

Expand Down Expand Up @@ -1246,6 +1246,23 @@ func TestE2ERemoteCalls(t *testing.T) {
_, err := contract.SendTransaction("remoteCall", []interface{}{req}, nil)
require.Error(t, err)
})

t.Run("Status code", func(t *testing.T) {
srvAddr := fr.testHttpRelayer(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(301)
})

req := &types.HttpRequest{
Method: "POST",
Url: srvAddr,
Body: []byte{0x1},
}
_, err := contract.SendTransaction("remoteCall2", []interface{}{req, uint64(301)}, nil)
require.NoError(t, err)

_, err = contract.SendTransaction("remoteCall2", []interface{}{req, uint64(302)}, nil)
require.Error(t, err)
})
}

func TestE2ERemoteCallsWithDns(t *testing.T) {
Expand Down
3 changes: 3 additions & 0 deletions suave/gen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,11 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/suave/artifacts"
"github.com/mitchellh/mapstructure"
"math/big"
)
var _ = new(big.Int)
var (
errFailedToUnpackInput = fmt.Errorf("failed to decode input")
errFailedToDecodeField = fmt.Errorf("failed to decode field")
Expand Down
24 changes: 24 additions & 0 deletions suave/gen/suave_spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ structs:
- name: timeout
description: "Timeout of the request in milliseconds"
type: uint64
- name: HttpResponse
description: "Description of an HTTP response."
fields:
- name: status
description: "HTTP status code of the response"
type: uint64
- name: body
description: "Body of the response"
type: bytes
- name: error
description: "Error message if any"
type: bytes
- name: SimulateTransactionResult
description: "Result of a simulated transaction."
fields:
Expand Down Expand Up @@ -386,6 +398,18 @@ functions:
- name: httpResponse
type: bytes
description: "Body of the response"
- name: doHTTPRequest2
address: "0x0000000000000000000000000000000043200003"
description: "Performs an HTTP request and returns the response. `request` is the request to perform."
input:
- name: request
type: HttpRequest
description: "Request to perform"
output:
fields:
- name: httpResponse
type: HttpResponse
description: "Response of the request"
- name: newBuilder
address: "0x0000000000000000000000000000000053200001"
description: "Initializes a new remote builder session"
Expand Down
2 changes: 1 addition & 1 deletion suave/lib/forge-std
Submodule forge-std updated 1 files
+1 −1 package.json
Loading

0 comments on commit 06b7e72

Please sign in to comment.