Skip to content

Commit

Permalink
Make buildEthBlock multichain (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranbt authored Apr 30, 2024
1 parent 7630e09 commit 9455e50
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 30 deletions.
2 changes: 1 addition & 1 deletion core/types/suave_structs.go

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

54 changes: 31 additions & 23 deletions core/vm/contracts_suave.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,30 +223,11 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error)
body = bytes.NewReader(request.Body)
}

var allowed bool
// resolve dns if possible
if endpoint, ok := s.suaveContext.Backend.ServiceAliasRegistry[request.Url]; ok {
request.Url = endpoint
} else {
// decode the url and check if the domain is allowed
parsedURL, err := url.Parse(request.Url)
if err != nil {
panic(err)
}

// check if the domain is allowed
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())
}
url, err := s.resolveURL(request.Url)
if err != nil {
return nil, err
}

req, err := http.NewRequest(request.Method, request.Url, body)
req, err := http.NewRequest(request.Method, url, body)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -291,6 +272,33 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error)
return data, nil
}

func (s *suaveRuntime) resolveURL(urlOrServiceName string) (string, error) {
var allowed bool
// resolve dns if possible
if endpoint, ok := s.suaveContext.Backend.ServiceAliasRegistry[urlOrServiceName]; ok {
return endpoint, nil
}

// decode the url and check if the domain is allowed
parsedURL, err := url.Parse(urlOrServiceName)
if err != nil {
return "", err
}

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

return urlOrServiceName, nil
}

func (s *suaveRuntime) newBuilder() (string, error) {
return s.suaveContext.Backend.ConfidentialEthBackend.NewSession(context.Background())
}
Expand Down
22 changes: 20 additions & 2 deletions core/vm/contracts_suave_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
suave_backends "github.com/ethereum/go-ethereum/suave/backends"
suave "github.com/ethereum/go-ethereum/suave/core"
"github.com/flashbots/go-boost-utils/bls"
"github.com/flashbots/go-boost-utils/ssz"
"github.com/holiman/uint256"
Expand Down Expand Up @@ -113,8 +115,12 @@ func (b *suaveRuntime) ethcall(contractAddr common.Address, input []byte) ([]byt
return b.suaveContext.Backend.ConfidentialEthBackend.Call(context.Background(), contractAddr, input)
}

// This is a temp solution and will be replaced with block building session
func (b *suaveRuntime) buildEthBlock(blockArgs types.BuildBlockArgs, dataID types.DataId, relayUrl string) ([]byte, []byte, error) {
return b.buildEthBlockTo("", blockArgs, dataID, relayUrl)
}

// This is a temp solution and will be replaced with block building session
func (b *suaveRuntime) buildEthBlockTo(execNode string, blockArgs types.BuildBlockArgs, dataID types.DataId, relayUrl string) ([]byte, []byte, error) {
dataIDs := [][16]byte{}
// first check for merged record, else assume regular record
if mergedDataRecordsBytes, err := b.suaveContext.Backend.ConfidentialStore.Retrieve(dataID, buildEthBlockAddr, "default:v0:mergedDataRecords"); err == nil {
Expand Down Expand Up @@ -214,8 +220,20 @@ func (b *suaveRuntime) buildEthBlock(blockArgs types.BuildBlockArgs, dataID type

log.Info("requesting a block be built", "mergedBundles", mergedBundles)

envelope, err := b.suaveContext.Backend.ConfidentialEthBackend.BuildEthBlockFromBundles(context.TODO(), &blockArgs, mergedBundles)
var confBackend suave.ConfidentialEthBackend
if execNode == "" {
// Use the backend configured with --suave.eth.remote-endpoint
confBackend = b.suaveContext.Backend.ConfidentialEthBackend
} else {
// Resolve the url from the execNode
url, err := b.resolveURL(execNode)
if err != nil {
return nil, nil, err
}
confBackend = suave_backends.NewRemoteEthBackend(url)
}

envelope, err := confBackend.BuildEthBlockFromBundles(context.TODO(), &blockArgs, mergedBundles)
if err != nil {
return nil, nil, fmt.Errorf("could not build eth block: %w", err)
}
Expand Down
63 changes: 61 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 @@ -15,6 +15,10 @@ var _ SuaveRuntime = &mockRuntime{}
type mockRuntime struct {
}

func (m *mockRuntime) buildEthBlockTo(execNode string, blockArgs types.BuildBlockArgs, dataID types.DataId, relayUrl string) ([]byte, []byte, error) {
return nil, nil, nil
}

func (m *mockRuntime) buildEthBlock(blockArgs types.BuildBlockArgs, dataId types.DataId, namespace string) ([]byte, []byte, error) {
return []byte{0x1}, []byte{0x1}, 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.

24 changes: 24 additions & 0 deletions suave/gen/suave_spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,30 @@ functions:
- name: executionPayload
type: bytes
description: "Execution payload encoded in JSON"
- name: buildEthBlockTo
address: "0x0000000000000000000000000000000042100006"
description: "Constructs an Ethereum block based on the provided data records. No blobs are returned."
input:
- name: executionNodeURL
type: string
description: "URL (or service name) of the execution node"
- name: blockArgs
type: BuildBlockArgs
description: "Arguments to build the block"
- name: dataId
type: DataId
description: "ID of the data record with mev-share bundle data"
- name: relayUrl
type: string
description: "If specified the built block will be submitted to the relay"
output:
fields:
- name: blockBid
type: bytes
description: "Block Bid encoded in JSON"
- name: executionPayload
type: bytes
description: "Execution payload encoded in JSON"
- name: submitEthBlockToRelay
address: "0x0000000000000000000000000000000042100002"
description: "Submits a given builderBid to a mev-boost relay."
Expand Down
24 changes: 24 additions & 0 deletions suave/sol/libraries/Suave.sol
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ library Suave {

address public constant BUILD_ETH_BLOCK = 0x0000000000000000000000000000000042100001;

address public constant BUILD_ETH_BLOCK_TO = 0x0000000000000000000000000000000042100006;

address public constant CONFIDENTIAL_INPUTS = 0x0000000000000000000000000000000042010001;

address public constant CONFIDENTIAL_RETRIEVE = 0x0000000000000000000000000000000042020001;
Expand Down Expand Up @@ -179,6 +181,28 @@ library Suave {
return abi.decode(data, (bytes, bytes));
}

/// @notice Constructs an Ethereum block based on the provided data records. No blobs are returned.
/// @param executionNodeURL URL (or service name) of the execution node
/// @param blockArgs Arguments to build the block
/// @param dataId ID of the data record with mev-share bundle data
/// @param relayUrl If specified the built block will be submitted to the relay
/// @return blockBid Block Bid encoded in JSON
/// @return executionPayload Execution payload encoded in JSON
function buildEthBlockTo(
string memory executionNodeURL,
BuildBlockArgs memory blockArgs,
DataId dataId,
string memory relayUrl
) internal returns (bytes memory, bytes memory) {
(bool success, bytes memory data) =
BUILD_ETH_BLOCK_TO.call(abi.encode(executionNodeURL, blockArgs, dataId, relayUrl));
if (!success) {
revert PeekerReverted(BUILD_ETH_BLOCK_TO, data);
}

return abi.decode(data, (bytes, bytes));
}

/// @notice Provides the confidential inputs associated with a confidential computation request. Outputs are in bytes format.
/// @return confindentialData Confidential inputs
function confidentialInputs() internal returns (bytes memory) {
Expand Down

0 comments on commit 9455e50

Please sign in to comment.