diff --git a/core/types/suave_structs.go b/core/types/suave_structs.go index 718de0317..05d9d97c3 100755 --- a/core/types/suave_structs.go +++ b/core/types/suave_structs.go @@ -1,5 +1,5 @@ // Code generated by suave/gen. DO NOT EDIT. -// Hash: 80e00d3e46ad61ee6925143b317f91c0ad551d66908d0ab20e244db63b40ff40 +// Hash: 2a5b71b16af5f16c11664cd066b385df56e26e58a67f1ed420573064ec45740a package types import "github.com/ethereum/go-ethereum/common" diff --git a/core/vm/contracts_suave_eth.go b/core/vm/contracts_suave_eth.go index bfca64caf..c276cc7d5 100644 --- a/core/vm/contracts_suave_eth.go +++ b/core/vm/contracts_suave_eth.go @@ -75,6 +75,7 @@ func (b *suaveRuntime) simulateBundle(input []byte) (uint64, error) { return 0, err } + // BUG: err == nil here, so we won't actually report an error to the caller. if envelope.ExecutionPayload.GasUsed == 0 { return 0, err } @@ -461,3 +462,23 @@ func (c *suaveRuntime) fillMevShareBundle(dataID types.DataId) ([]byte, error) { return json.Marshal(shareBundle) } + +func (s *suaveRuntime) ensureTxnValid(txn []byte) error { + var tx types.Transaction + if err := tx.UnmarshalBinary(txn); err != nil { + return err + } + + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second)) + defer cancel() + + ts := types.Transactions{&tx} + _, err := s.suaveContext.Backend.ConfidentialEthBackend.BuildEthBlock(ctx, nil, ts) + return err +} + +func (s *suaveRuntime) getCallData(txn []byte) ([]byte, error) { + var tx types.Transaction + err := tx.UnmarshalBinary(txn) + return tx.Data(), err +} diff --git a/core/vm/contracts_suave_runtime_adapter.go b/core/vm/contracts_suave_runtime_adapter.go index d42579bc7..72bddad4a 100644 --- a/core/vm/contracts_suave_runtime_adapter.go +++ b/core/vm/contracts_suave_runtime_adapter.go @@ -1,5 +1,5 @@ // Code generated by suave/gen. DO NOT EDIT. -// Hash: 80e00d3e46ad61ee6925143b317f91c0ad551d66908d0ab20e244db63b40ff40 +// Hash: 2a5b71b16af5f16c11664cd066b385df56e26e58a67f1ed420573064ec45740a package vm import ( @@ -22,10 +22,12 @@ type SuaveRuntime interface { confidentialRetrieve(dataId types.DataId, key string) ([]byte, error) confidentialStore(dataId types.DataId, key string, data1 []byte) error doHTTPRequest(request types.HttpRequest) ([]byte, error) + ensureTxnValid(txn []byte) error ethcall(contractAddr common.Address, input1 []byte) ([]byte, error) extractHint(bundleData []byte) ([]byte, error) fetchDataRecords(cond uint64, namespace string) ([]types.DataRecord, error) fillMevShareBundle(dataId types.DataId) ([]byte, error) + getCallData(txn []byte) ([]byte, error) newDataRecord(decryptionCondition uint64, allowedPeekers []common.Address, allowedStores []common.Address, dataType string) (types.DataRecord, error) signEthTransaction(txn []byte, chainId string, signingKey string) ([]byte, error) simulateBundle(bundleData []byte) (uint64, error) @@ -39,10 +41,12 @@ var ( confidentialRetrieveAddr = common.HexToAddress("0x0000000000000000000000000000000042020001") confidentialStoreAddr = common.HexToAddress("0x0000000000000000000000000000000042020000") doHTTPRequestAddr = common.HexToAddress("0x0000000000000000000000000000000043200002") + ensureTxnValidAddr = common.HexToAddress("0x0000000000000000000000000000000043200004") ethcallAddr = common.HexToAddress("0x0000000000000000000000000000000042100003") extractHintAddr = common.HexToAddress("0x0000000000000000000000000000000042100037") fetchDataRecordsAddr = common.HexToAddress("0x0000000000000000000000000000000042030001") fillMevShareBundleAddr = common.HexToAddress("0x0000000000000000000000000000000043200001") + getCallDataAddr = common.HexToAddress("0x0000000000000000000000000000000043200003") newDataRecordAddr = common.HexToAddress("0x0000000000000000000000000000000042030000") signEthTransactionAddr = common.HexToAddress("0x0000000000000000000000000000000040100001") simulateBundleAddr = common.HexToAddress("0x0000000000000000000000000000000042100000") @@ -51,7 +55,7 @@ var ( ) var addrList = []common.Address{ - buildEthBlockAddr, confidentialInputsAddr, confidentialRetrieveAddr, confidentialStoreAddr, doHTTPRequestAddr, ethcallAddr, extractHintAddr, fetchDataRecordsAddr, fillMevShareBundleAddr, newDataRecordAddr, signEthTransactionAddr, simulateBundleAddr, submitBundleJsonRPCAddr, submitEthBlockBidToRelayAddr, + buildEthBlockAddr, confidentialInputsAddr, confidentialRetrieveAddr, confidentialStoreAddr, doHTTPRequestAddr, ensureTxnValidAddr, ethcallAddr, extractHintAddr, fetchDataRecordsAddr, fillMevShareBundleAddr, getCallDataAddr, newDataRecordAddr, signEthTransactionAddr, simulateBundleAddr, submitBundleJsonRPCAddr, submitEthBlockBidToRelayAddr, } type SuaveRuntimeAdapter struct { @@ -75,6 +79,9 @@ func (b *SuaveRuntimeAdapter) run(addr common.Address, input []byte) ([]byte, er case doHTTPRequestAddr: return b.doHTTPRequest(input) + case ensureTxnValidAddr: + return b.ensureTxnValid(input) + case ethcallAddr: return b.ethcall(input) @@ -87,6 +94,9 @@ func (b *SuaveRuntimeAdapter) run(addr common.Address, input []byte) ([]byte, er case fillMevShareBundleAddr: return b.fillMevShareBundle(input) + case getCallDataAddr: + return b.getCallData(input) + case newDataRecordAddr: return b.newDataRecord(input) @@ -308,6 +318,37 @@ func (b *SuaveRuntimeAdapter) doHTTPRequest(input []byte) (res []byte, err error } +func (b *SuaveRuntimeAdapter) ensureTxnValid(input []byte) (res []byte, err error) { + var ( + unpacked []interface{} + result []byte + ) + + _ = unpacked + _ = result + + unpacked, err = artifacts.SuaveAbi.Methods["ensureTxnValid"].Inputs.Unpack(input) + if err != nil { + err = errFailedToUnpackInput + return + } + + var ( + txn []byte + ) + + txn = unpacked[0].([]byte) + + var () + + if err = b.impl.ensureTxnValid(txn); err != nil { + return + } + + return nil, nil + +} + func (b *SuaveRuntimeAdapter) ethcall(input []byte) (res []byte, err error) { var ( unpacked []interface{} @@ -459,6 +500,40 @@ func (b *SuaveRuntimeAdapter) fillMevShareBundle(input []byte) (res []byte, err } +func (b *SuaveRuntimeAdapter) getCallData(input []byte) (res []byte, err error) { + var ( + unpacked []interface{} + result []byte + ) + + _ = unpacked + _ = result + + unpacked, err = artifacts.SuaveAbi.Methods["getCallData"].Inputs.Unpack(input) + if err != nil { + err = errFailedToUnpackInput + return + } + + var ( + txn []byte + ) + + txn = unpacked[0].([]byte) + + var ( + calldata []byte + ) + + if calldata, err = b.impl.getCallData(txn); err != nil { + return + } + + result = calldata + return result, nil + +} + func (b *SuaveRuntimeAdapter) newDataRecord(input []byte) (res []byte, err error) { var ( unpacked []interface{} diff --git a/core/vm/contracts_suave_runtime_adapter_test.go b/core/vm/contracts_suave_runtime_adapter_test.go index cc131f403..3e3cf18f9 100644 --- a/core/vm/contracts_suave_runtime_adapter_test.go +++ b/core/vm/contracts_suave_runtime_adapter_test.go @@ -71,6 +71,16 @@ func (m *mockRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error) { return []byte{0x1}, nil } +func (m *mockRuntime) ensureTxnValid(txn []byte) error { + return nil +} + +func (m *mockRuntime) getCallData(txn []byte) ([]byte, error) { + var tx types.Transaction + err := tx.UnmarshalBinary(txn) + return tx.Data(), err +} + func TestRuntimeAdapter(t *testing.T) { adapter := &SuaveRuntimeAdapter{ impl: &mockRuntime{}, diff --git a/core/vm/contracts_suave_test.go b/core/vm/contracts_suave_test.go index 6bc50ca33..2a2522f21 100644 --- a/core/vm/contracts_suave_test.go +++ b/core/vm/contracts_suave_test.go @@ -2,6 +2,7 @@ package vm import ( "context" + "math/big" "net/http" "net/http/httptest" "testing" @@ -257,3 +258,31 @@ func TestSuave_HttpRequest_Basic(t *testing.T) { }) } } + +func TestEnsureTxnValid(t *testing.T) { + t.Parallel() + + bk := newTestBackend(t) + + tx := types.NewTransaction(0, common.Address{}, big.NewInt(42), 1000, big.NewInt(1), []byte("hello, world!")) + b, err := tx.MarshalBinary() + require.NoError(t, err) + require.NotNil(t, b) + + bk.ensureTxnValid(b) +} + +func TestGetABIEncodedCallData(t *testing.T) { + t.Parallel() + + bk := newTestBackend(t) + + tx := types.NewTransaction(0, common.Address{}, big.NewInt(42), 1000, big.NewInt(1), []byte("hello, world!")) + b, err := tx.MarshalBinary() + require.NoError(t, err) + require.NotNil(t, b) + + cd, err := bk.getCallData(b) + require.NoError(t, err) + require.Equal(t, "hello, world!", string(cd)) +} diff --git a/suave/artifacts/SuaveLib.json b/suave/artifacts/SuaveLib.json index 0621c8e46..cbe1f4c50 100644 --- a/suave/artifacts/SuaveLib.json +++ b/suave/artifacts/SuaveLib.json @@ -1 +1 @@ -[{"type":"error","name":"PeekerReverted","inputs":[{"name":"addr","type":"address"},{"name":"err","type":"bytes"}]},{"type":"function","name":"buildEthBlock","inputs":[{"name":"blockArgs","type":"tuple","internalType":"struct Suave.BuildBlockArgs","components":[{"name":"slot","type":"uint64","internalType":"uint64"},{"name":"proposerPubkey","type":"bytes","internalType":"bytes"},{"name":"parent","type":"bytes32","internalType":"bytes32"},{"name":"timestamp","type":"uint64","internalType":"uint64"},{"name":"feeRecipient","type":"address","internalType":"address"},{"name":"gasLimit","type":"uint64","internalType":"uint64"},{"name":"random","type":"bytes32","internalType":"bytes32"},{"name":"withdrawals","type":"tuple[]","internalType":"struct Suave.Withdrawal[]","components":[{"name":"index","type":"uint64","internalType":"uint64"},{"name":"validator","type":"uint64","internalType":"uint64"},{"name":"Address","type":"address","internalType":"address"},{"name":"amount","type":"uint64","internalType":"uint64"}]},{"name":"extra","type":"bytes","internalType":"bytes"}]},{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"},{"name":"output2","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialInputs","outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialRetrieve","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialStore","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"},{"name":"data1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"doHTTPRequest","inputs":[{"name":"request","type":"tuple","internalType":"struct Suave.HttpRequest","components":[{"name":"url","type":"string","internalType":"string"},{"name":"method","type":"string","internalType":"string"},{"name":"headers","type":"string[]","internalType":"string[]"},{"name":"body","type":"bytes","internalType":"bytes"}]}],"outputs":[{"name":"response","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"ethcall","inputs":[{"name":"contractAddr","type":"address","internalType":"address"},{"name":"input1","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"extractHint","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"fetchDataRecords","inputs":[{"name":"cond","type":"uint64","internalType":"uint64"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"dataRecords","type":"tuple[]","internalType":"struct Suave.DataRecord[]","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"version","type":"string","internalType":"string"}]}]},{"type":"function","name":"fillMevShareBundle","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"}],"outputs":[{"name":"encodedBundle","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"newDataRecord","inputs":[{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"dataType","type":"string","internalType":"string"}],"outputs":[{"name":"dataRecord","type":"tuple","internalType":"struct Suave.DataRecord","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"version","type":"string","internalType":"string"}]}]},{"type":"function","name":"signEthTransaction","inputs":[{"name":"txn","type":"bytes","internalType":"bytes"},{"name":"chainId","type":"string","internalType":"string"},{"name":"signingKey","type":"string","internalType":"string"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"simulateBundle","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"uint64","internalType":"uint64"}]},{"type":"function","name":"submitBundleJsonRPC","inputs":[{"name":"url","type":"string","internalType":"string"},{"name":"method","type":"string","internalType":"string"},{"name":"params","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"submitEthBlockBidToRelay","inputs":[{"name":"relayUrl","type":"string","internalType":"string"},{"name":"builderBid","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]}] \ No newline at end of file +[{"type":"error","name":"PeekerReverted","inputs":[{"name":"addr","type":"address"},{"name":"err","type":"bytes"}]},{"type":"function","name":"buildEthBlock","inputs":[{"name":"blockArgs","type":"tuple","internalType":"struct Suave.BuildBlockArgs","components":[{"name":"slot","type":"uint64","internalType":"uint64"},{"name":"proposerPubkey","type":"bytes","internalType":"bytes"},{"name":"parent","type":"bytes32","internalType":"bytes32"},{"name":"timestamp","type":"uint64","internalType":"uint64"},{"name":"feeRecipient","type":"address","internalType":"address"},{"name":"gasLimit","type":"uint64","internalType":"uint64"},{"name":"random","type":"bytes32","internalType":"bytes32"},{"name":"withdrawals","type":"tuple[]","internalType":"struct Suave.Withdrawal[]","components":[{"name":"index","type":"uint64","internalType":"uint64"},{"name":"validator","type":"uint64","internalType":"uint64"},{"name":"Address","type":"address","internalType":"address"},{"name":"amount","type":"uint64","internalType":"uint64"}]},{"name":"extra","type":"bytes","internalType":"bytes"}]},{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"},{"name":"output2","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialInputs","outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialRetrieve","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialStore","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"},{"name":"data1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"doHTTPRequest","inputs":[{"name":"request","type":"tuple","internalType":"struct Suave.HttpRequest","components":[{"name":"url","type":"string","internalType":"string"},{"name":"method","type":"string","internalType":"string"},{"name":"headers","type":"string[]","internalType":"string[]"},{"name":"body","type":"bytes","internalType":"bytes"}]}],"outputs":[{"name":"response","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"ensureTxnValid","inputs":[{"name":"txn","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"ethcall","inputs":[{"name":"contractAddr","type":"address","internalType":"address"},{"name":"input1","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"extractHint","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"fetchDataRecords","inputs":[{"name":"cond","type":"uint64","internalType":"uint64"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"dataRecords","type":"tuple[]","internalType":"struct Suave.DataRecord[]","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"version","type":"string","internalType":"string"}]}]},{"type":"function","name":"fillMevShareBundle","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"}],"outputs":[{"name":"encodedBundle","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"getCallData","inputs":[{"name":"txn","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"calldata","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"newDataRecord","inputs":[{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"dataType","type":"string","internalType":"string"}],"outputs":[{"name":"dataRecord","type":"tuple","internalType":"struct Suave.DataRecord","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"version","type":"string","internalType":"string"}]}]},{"type":"function","name":"signEthTransaction","inputs":[{"name":"txn","type":"bytes","internalType":"bytes"},{"name":"chainId","type":"string","internalType":"string"},{"name":"signingKey","type":"string","internalType":"string"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"simulateBundle","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"uint64","internalType":"uint64"}]},{"type":"function","name":"submitBundleJsonRPC","inputs":[{"name":"url","type":"string","internalType":"string"},{"name":"method","type":"string","internalType":"string"},{"name":"params","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"submitEthBlockBidToRelay","inputs":[{"name":"relayUrl","type":"string","internalType":"string"},{"name":"builderBid","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]}] \ No newline at end of file diff --git a/suave/artifacts/addresses.go b/suave/artifacts/addresses.go index 64fb67580..70a7e388b 100644 --- a/suave/artifacts/addresses.go +++ b/suave/artifacts/addresses.go @@ -1,5 +1,5 @@ // Code generated by suave/gen. DO NOT EDIT. -// Hash: 80e00d3e46ad61ee6925143b317f91c0ad551d66908d0ab20e244db63b40ff40 +// Hash: 2a5b71b16af5f16c11664cd066b385df56e26e58a67f1ed420573064ec45740a package artifacts import ( @@ -13,10 +13,12 @@ var ( confidentialRetrieveAddr = common.HexToAddress("0x0000000000000000000000000000000042020001") confidentialStoreAddr = common.HexToAddress("0x0000000000000000000000000000000042020000") doHTTPRequestAddr = common.HexToAddress("0x0000000000000000000000000000000043200002") + ensureTxnValidAddr = common.HexToAddress("0x0000000000000000000000000000000043200004") ethcallAddr = common.HexToAddress("0x0000000000000000000000000000000042100003") extractHintAddr = common.HexToAddress("0x0000000000000000000000000000000042100037") fetchDataRecordsAddr = common.HexToAddress("0x0000000000000000000000000000000042030001") fillMevShareBundleAddr = common.HexToAddress("0x0000000000000000000000000000000043200001") + getCallDataAddr = common.HexToAddress("0x0000000000000000000000000000000043200003") newDataRecordAddr = common.HexToAddress("0x0000000000000000000000000000000042030000") signEthTransactionAddr = common.HexToAddress("0x0000000000000000000000000000000040100001") simulateBundleAddr = common.HexToAddress("0x0000000000000000000000000000000042100000") @@ -30,10 +32,12 @@ var SuaveMethods = map[string]common.Address{ "confidentialRetrieve": confidentialRetrieveAddr, "confidentialStore": confidentialStoreAddr, "doHTTPRequest": doHTTPRequestAddr, + "ensureTxnValid": ensureTxnValidAddr, "ethcall": ethcallAddr, "extractHint": extractHintAddr, "fetchDataRecords": fetchDataRecordsAddr, "fillMevShareBundle": fillMevShareBundleAddr, + "getCallData": getCallDataAddr, "newDataRecord": newDataRecordAddr, "signEthTransaction": signEthTransactionAddr, "simulateBundle": simulateBundleAddr, @@ -53,6 +57,8 @@ func PrecompileAddressToName(addr common.Address) string { return "confidentialStore" case doHTTPRequestAddr: return "doHTTPRequest" + case ensureTxnValidAddr: + return "ensureTxnValid" case ethcallAddr: return "ethcall" case extractHintAddr: @@ -61,6 +67,8 @@ func PrecompileAddressToName(addr common.Address) string { return "fetchDataRecords" case fillMevShareBundleAddr: return "fillMevShareBundle" + case getCallDataAddr: + return "getCallData" case newDataRecordAddr: return "newDataRecord" case signEthTransactionAddr: diff --git a/suave/gen/suave_spec.yaml b/suave/gen/suave_spec.yaml index 0e8adde31..fdab3e3ec 100644 --- a/suave/gen/suave_spec.yaml +++ b/suave/gen/suave_spec.yaml @@ -218,3 +218,23 @@ functions: fields: - name: response type: bytes + - name: getCallData + address: "0x0000000000000000000000000000000043200003" + isConfidential: true + input: + - name: txn + type: bytes + output: + packed: true + fields: + - name: calldata + type: bytes + - name: ensureTxnValid + address: "0x0000000000000000000000000000000043200004" + isConfidential: true + input: + - name: txn + type: bytes + output: + packed: true + fields: diff --git a/suave/sol/libraries/Suave.sol b/suave/sol/libraries/Suave.sol index 884be1626..a6a229e7e 100644 --- a/suave/sol/libraries/Suave.sol +++ b/suave/sol/libraries/Suave.sol @@ -55,6 +55,8 @@ library Suave { address public constant DO_HTTPREQUEST = 0x0000000000000000000000000000000043200002; + address public constant ENSURE_TXN_VALID = 0x0000000000000000000000000000000043200004; + address public constant ETHCALL = 0x0000000000000000000000000000000042100003; address public constant EXTRACT_HINT = 0x0000000000000000000000000000000042100037; @@ -63,6 +65,8 @@ library Suave { address public constant FILL_MEV_SHARE_BUNDLE = 0x0000000000000000000000000000000043200001; + address public constant GET_CALL_DATA = 0x0000000000000000000000000000000043200003; + address public constant NEW_DATA_RECORD = 0x0000000000000000000000000000000042030000; address public constant SIGN_ETH_TRANSACTION = 0x0000000000000000000000000000000040100001; @@ -134,6 +138,14 @@ library Suave { return abi.decode(data, (bytes)); } + function ensureTxnValid(bytes memory txn) internal view { + require(isConfidential()); + (bool success, bytes memory data) = ENSURE_TXN_VALID.staticcall(abi.encode(txn)); + if (!success) { + revert PeekerReverted(ENSURE_TXN_VALID, data); + } + } + function ethcall(address contractAddr, bytes memory input1) internal view returns (bytes memory) { (bool success, bytes memory data) = ETHCALL.staticcall(abi.encode(contractAddr, input1)); if (!success) { @@ -172,6 +184,16 @@ library Suave { return data; } + function getCallData(bytes memory txn) internal view returns (bytes memory) { + require(isConfidential()); + (bool success, bytes memory data) = GET_CALL_DATA.staticcall(abi.encode(txn)); + if (!success) { + revert PeekerReverted(GET_CALL_DATA, data); + } + + return data; + } + function newDataRecord( uint64 decryptionCondition, address[] memory allowedPeekers, diff --git a/suave/sol/libraries/SuaveForge.sol b/suave/sol/libraries/SuaveForge.sol index 5e0d14851..396de6364 100644 --- a/suave/sol/libraries/SuaveForge.sol +++ b/suave/sol/libraries/SuaveForge.sol @@ -69,6 +69,10 @@ library SuaveForge { return abi.decode(data, (bytes)); } + function ensureTxnValid(bytes memory txn) internal view { + bytes memory data = forgeIt("0x0000000000000000000000000000000043200004", abi.encode(txn)); + } + function ethcall(address contractAddr, bytes memory input1) internal view returns (bytes memory) { bytes memory data = forgeIt("0x0000000000000000000000000000000042100003", abi.encode(contractAddr, input1)); @@ -93,6 +97,12 @@ library SuaveForge { return data; } + function getCallData(bytes memory txn) internal view returns (bytes memory) { + bytes memory data = forgeIt("0x0000000000000000000000000000000043200003", abi.encode(txn)); + + return data; + } + function newDataRecord( uint64 decryptionCondition, address[] memory allowedPeekers,