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

Precompile refactor and signEthTx precompile #79

Closed
wants to merge 1 commit into from
Closed
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
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.

24 changes: 13 additions & 11 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,24 +87,26 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
// contracts used in the suave testnet. It's a superset of Berlin precompiles.
// Confidential contracts (implementing SuavePrecompiledContract)
// are ran with their respective RunConfidential in confidential setting
// TODO: should be autogenerated
var PrecompiledContractsSuave = map[common.Address]SuavePrecompiledContract{
isConfidentialAddress: &isConfidentialPrecompile{},
confidentialInputsAddress: &confidentialInputsPrecompile{},

confStoreStoreAddress: newConfStoreStore(),
confStoreRetrieveAddress: newConfStoreRetrieve(),
confStoreStoreAddress: &stubPrecompile{staticRequiredGas(1000)},
confStoreRetrieveAddress: &stubPrecompile{staticRequiredGas(1000)},

newBidAddress: newNewBid(),
fetchBidsAddress: newFetchBids(),
extractHintAddress: &extractHint{},
newBidAddress: &stubPrecompile{staticRequiredGas(1000)},
fetchBidsAddress: &stubPrecompile{staticRequiredGas(1000)},
extractHintAddress: &stubPrecompile{staticRequiredGas(1000)},

simulateBundleAddress: &simulateBundle{},
buildEthBlockAddress: &buildEthBlock{},
submitEthBlockBidToRelayAddress: &submitEthBlockBidToRelay{},
submitBundleJsonRPCAddress: &submitBundleJsonRPC{},
fillMevShareBundleAddress: &fillMevShareBundle{},
signEthTransactionAddress: &stubPrecompile{staticRequiredGas(1000)},
simulateBundleAddress: &stubPrecompile{staticRequiredGas(1000)},
buildEthBlockAddress: &stubPrecompile{staticRequiredGas(1000)},
submitEthBlockBidToRelayAddress: &stubPrecompile{staticRequiredGas(1000)},
submitBundleJsonRPCAddress: &stubPrecompile{staticRequiredGas(1000)},
fillMevShareBundleAddress: &stubPrecompile{staticRequiredGas(1000)},

ethcallAddr: &ethCallPrecompile{},
ethcallAddr: &stubPrecompile{staticRequiredGas(1000)},
}

// PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum
Expand Down
190 changes: 19 additions & 171 deletions core/vm/contracts_suave.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@ package vm
import (
"errors"
"fmt"
"strings"

"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/suave/artifacts"
suave "github.com/ethereum/go-ethereum/suave/core"
)

Expand Down Expand Up @@ -79,45 +76,7 @@ func (c *confidentialInputsPrecompile) RunConfidential(suaveContext *SuaveContex

/* Confidential store precompiles */

type confStoreStore struct {
inoutAbi abi.Method
}

func newConfStoreStore() *confStoreStore {
inoutAbi := mustParseMethodAbi(`[{"inputs":[{"type":"bytes16"}, {"type":"bytes16"}, {"type":"string"}, {"type":"bytes"}],"name":"store","outputs":[],"stateMutability":"nonpayable","type":"function"}]`, "store")

return &confStoreStore{inoutAbi}
}

func (c *confStoreStore) RequiredGas(input []byte) uint64 {
return uint64(100 * len(input))
}

func (c *confStoreStore) Run(input []byte) ([]byte, error) {
return nil, errors.New("not available in this suaveContext")
}

func (c *confStoreStore) RunConfidential(suaveContext *SuaveContext, input []byte) ([]byte, error) {
if len(suaveContext.CallerStack) == 0 {
return []byte("not allowed"), errors.New("not allowed in this suaveContext")
}

unpacked, err := c.inoutAbi.Inputs.Unpack(input)
if err != nil {
return []byte(err.Error()), err
}

bidId := unpacked[0].(types.BidId)
key := unpacked[1].(string)
data := unpacked[2].([]byte)

if err := c.runImpl(suaveContext, bidId, key, data); err != nil {
return []byte(err.Error()), err
}
return nil, nil
}

func (c *confStoreStore) runImpl(suaveContext *SuaveContext, bidId suave.BidId, key string, data []byte) error {
func confStoreStoreImpl(suaveContext *SuaveContext, bidId suave.BidId, key string, data []byte) error {
bid, err := suaveContext.Backend.ConfidentialStore.FetchBidById(bidId)
if err != nil {
return suave.ErrBidNotFound
Expand All @@ -140,37 +99,7 @@ func (c *confStoreStore) runImpl(suaveContext *SuaveContext, bidId suave.BidId,
return nil
}

type confStoreRetrieve struct{}

func newConfStoreRetrieve() *confStoreRetrieve {
return &confStoreRetrieve{}
}

func (c *confStoreRetrieve) RequiredGas(input []byte) uint64 {
return 100
}

func (c *confStoreRetrieve) Run(input []byte) ([]byte, error) {
return nil, errors.New("not available in this suaveContext")
}

func (c *confStoreRetrieve) RunConfidential(suaveContext *SuaveContext, input []byte) ([]byte, error) {
if len(suaveContext.CallerStack) == 0 {
return []byte("not allowed"), errors.New("not allowed in this suaveContext")
}

unpacked, err := artifacts.SuaveAbi.Methods["retrieve"].Inputs.Unpack(input)
if err != nil {
return []byte(err.Error()), err
}

bidId := unpacked[0].(suave.BidId)
key := unpacked[1].(string)

return c.runImpl(suaveContext, bidId, key)
}

func (c *confStoreRetrieve) runImpl(suaveContext *SuaveContext, bidId suave.BidId, key string) ([]byte, error) {
func confStoreRetrieveImpl(suaveContext *SuaveContext, bidId suave.BidId, key string) ([]byte, error) {
bid, err := suaveContext.Backend.ConfidentialStore.FetchBidById(bidId)
if err != nil {
return nil, suave.ErrBidNotFound
Expand All @@ -195,43 +124,7 @@ func (c *confStoreRetrieve) runImpl(suaveContext *SuaveContext, bidId suave.BidI

/* Bid precompiles */

type newBid struct {
inoutAbi abi.Method
}

func newNewBid() *newBid {
inoutAbi := mustParseMethodAbi(`[{ "inputs": [ { "internalType": "uint64", "name": "decryptionCondition", "type": "uint64" }, { "internalType": "address[]", "name": "allowedPeekers", "type": "address[]" }, { "internalType": "string", "name": "BidType", "type": "string" } ], "name": "newBid", "outputs": [ { "components": [ { "internalType": "Suave.BidId", "name": "id", "type": "bytes16" }, { "internalType": "Suave.BidId", "name": "salt", "type": "bytes16" }, { "internalType": "uint64", "name": "decryptionCondition", "type": "uint64" }, { "internalType": "address[]", "name": "allowedPeekers", "type": "address[]" } ], "internalType": "struct Suave.Bid", "name": "", "type": "tuple" } ], "stateMutability": "view", "type": "function" }]`, "newBid")

return &newBid{inoutAbi}
}

func (c *newBid) RequiredGas(input []byte) uint64 {
return 1000
}

func (c *newBid) Run(input []byte) ([]byte, error) {
return input, nil
}

func (c *newBid) RunConfidential(suaveContext *SuaveContext, input []byte) ([]byte, error) {
unpacked, err := c.inoutAbi.Inputs.Unpack(input)
if err != nil {
return []byte(err.Error()), err
}
version := unpacked[2].(string)

decryptionCondition := unpacked[0].(uint64)
allowedPeekers := unpacked[1].([]common.Address)

bid, err := c.runImpl(suaveContext, version, decryptionCondition, allowedPeekers, []common.Address{})
if err != nil {
return []byte(err.Error()), err
}

return c.inoutAbi.Outputs.Pack(bid)
}

func (c *newBid) runImpl(suaveContext *SuaveContext, version string, decryptionCondition uint64, allowedPeekers []common.Address, allowedStores []common.Address) (*types.Bid, error) {
func newBidImpl(suaveContext *SuaveContext, version string, decryptionCondition uint64, allowedPeekers []common.Address, allowedStores []common.Address) (*types.Bid, error) {
if suaveContext.ConfidentialComputeRequestTx == nil {
panic("newBid: source transaction not present")
}
Expand All @@ -250,42 +143,7 @@ func (c *newBid) runImpl(suaveContext *SuaveContext, version string, decryptionC
return &bid, nil
}

type fetchBids struct {
inoutAbi abi.Method
}

func newFetchBids() *fetchBids {
inoutAbi := mustParseMethodAbi(`[ { "inputs": [ { "internalType": "uint64", "name": "cond", "type": "uint64" }, { "internalType": "string", "name": "namespace", "type": "string" } ], "name": "fetchBids", "outputs": [ { "components": [ { "internalType": "Suave.BidId", "name": "id", "type": "bytes16" }, { "internalType": "Suave.BidId", "name": "salt", "type": "bytes16" }, { "internalType": "uint64", "name": "decryptionCondition", "type": "uint64" }, { "internalType": "address[]", "name": "allowedPeekers", "type": "address[]" }, { "internalType": "address[]", "name": "allowedStores", "type": "address[]" }, { "internalType": "string", "name": "version", "type": "string" } ], "internalType": "struct Suave.Bid[]", "name": "", "type": "tuple[]" } ], "stateMutability": "view", "type": "function" } ]`, "fetchBids")

return &fetchBids{inoutAbi}
}

func (c *fetchBids) RequiredGas(input []byte) uint64 {
return 1000
}

func (c *fetchBids) Run(input []byte) ([]byte, error) {
return input, nil
}

func (c *fetchBids) RunConfidential(suaveContext *SuaveContext, input []byte) ([]byte, error) {
unpacked, err := c.inoutAbi.Inputs.Unpack(input)
if err != nil {
return []byte(err.Error()), err
}

targetBlock := unpacked[0].(uint64)
namespace := unpacked[1].(string)

bids, err := c.runImpl(suaveContext, targetBlock, namespace)
if err != nil {
return []byte(err.Error()), err
}

return c.inoutAbi.Outputs.Pack(bids)
}

func (c *fetchBids) runImpl(suaveContext *SuaveContext, targetBlock uint64, namespace string) ([]types.Bid, error) {
func fetchBidsImpl(suaveContext *SuaveContext, targetBlock uint64, namespace string) ([]types.Bid, error) {
bids1 := suaveContext.Backend.ConfidentialStore.FetchBidsByProtocolAndBlock(targetBlock, namespace)

bids := make([]types.Bid, 0, len(bids1))
Expand All @@ -296,20 +154,6 @@ func (c *fetchBids) runImpl(suaveContext *SuaveContext, targetBlock uint64, name
return bids, nil
}

func mustParseAbi(data string) abi.ABI {
inoutAbi, err := abi.JSON(strings.NewReader(data))
if err != nil {
panic(err.Error())
}

return inoutAbi
}

func mustParseMethodAbi(data string, method string) abi.Method {
inoutAbi := mustParseAbi(data)
return inoutAbi.Methods[method]
}

func formatPeekerError(format string, args ...any) ([]byte, error) {
err := fmt.Errorf(format, args...)
return []byte(err.Error()), err
Expand All @@ -322,61 +166,65 @@ type suaveRuntime struct {
var _ SuaveRuntime = &suaveRuntime{}

func (b *suaveRuntime) ethcall(contractAddr common.Address, input []byte) ([]byte, error) {
return (&ethCallPrecompile{}).runImpl(b.suaveContext, contractAddr, input)
return ethCallPrecompileImpl(b.suaveContext, contractAddr, input)
}

func (b *suaveRuntime) buildEthBlock(blockArgs types.BuildBlockArgs, bid types.BidId, namespace string) ([]byte, []byte, error) {
return (&buildEthBlock{}).runImpl(b.suaveContext, blockArgs, bid, namespace)
return buildEthBlockImpl(b.suaveContext, blockArgs, bid, namespace)
}

func (b *suaveRuntime) confidentialInputs() ([]byte, error) {
return nil, nil
}

func (b *suaveRuntime) confidentialStoreRetrieve(bidId types.BidId, key string) ([]byte, error) {
return (&confStoreRetrieve{}).runImpl(b.suaveContext, bidId, key)
return confStoreRetrieveImpl(b.suaveContext, bidId, key)
}

func (b *suaveRuntime) confidentialStoreStore(bidId types.BidId, key string, data []byte) error {
return (&confStoreStore{}).runImpl(b.suaveContext, bidId, key, data)
return confStoreStoreImpl(b.suaveContext, bidId, key, data)
}

func (b *suaveRuntime) extractHint(bundleData []byte) ([]byte, error) {
return (&extractHint{}).runImpl(b.suaveContext, bundleData)
return extractHintImpl(b.suaveContext, bundleData)
}

func (b *suaveRuntime) fetchBids(cond uint64, namespace string) ([]types.Bid, error) {
bids, err := (&fetchBids{}).runImpl(b.suaveContext, cond, namespace)
bids, err := fetchBidsImpl(b.suaveContext, cond, namespace)
if err != nil {
return nil, err
}
return bids, nil
}

func (b *suaveRuntime) newBid(decryptionCondition uint64, allowedPeekers []common.Address, allowedStores []common.Address, BidType string) (types.Bid, error) {
bid, err := (&newBid{}).runImpl(b.suaveContext, BidType, decryptionCondition, allowedPeekers, allowedStores)
bid, err := newBidImpl(b.suaveContext, BidType, decryptionCondition, allowedPeekers, allowedStores)
if err != nil {
return types.Bid{}, err
}
return *bid, nil
}

func (b *suaveRuntime) signEthTransaction(txn []byte, chainId string, signingKey string) ([]byte, error) {
return signEthTransactionImpl(txn, chainId, signingKey)
}

func (b *suaveRuntime) simulateBundle(bundleData []byte) (uint64, error) {
num, err := (&simulateBundle{}).runImpl(b.suaveContext, bundleData)
num, err := simulateBundleImpl(b.suaveContext, bundleData)
if err != nil {
return 0, err
}
return num.Uint64(), nil
}

func (b *suaveRuntime) submitEthBlockBidToRelay(relayUrl string, builderBid []byte) ([]byte, error) {
return (&submitEthBlockBidToRelay{}).runImpl(b.suaveContext, relayUrl, builderBid)
return submitEthBlockBidToRelayImpl(b.suaveContext, relayUrl, builderBid)
}

func (b *suaveRuntime) fillMevShareBundle(bidId types.BidId) ([]byte, error) {
return (&fillMevShareBundle{}).runImpl(b.suaveContext, bidId)
return fillMevShareBundleImpl(b.suaveContext, bidId)
}

func (b *suaveRuntime) submitBundleJsonRPC(url string, method string, params []byte) ([]byte, error) {
return (&submitBundleJsonRPC{}).runImpl(b.suaveContext, url, method, params)
return submitBundleJsonRPCImpl(b.suaveContext, url, method, params)
}
Loading
Loading