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 precompile httpRequest2 that returns whole response #286

Merged
merged 2 commits into from
Dec 4, 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
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
Loading