From 0ca15b79dbb95fafeead25b11a06c15dea91e111 Mon Sep 17 00:00:00 2001 From: pistomat Date: Thu, 5 Sep 2024 19:08:00 +0200 Subject: [PATCH] feat: implement getInsecureTime precompile (#278) * feat: implement getInsecureTime precompile * update description * Return milliseconds in getInsecureTime --- core/types/suave_structs.go | 2 +- core/vm/contracts_suave.go | 5 +++ core/vm/contracts_suave_runtime_adapter.go | 44 ++++++++++++++++++- .../contracts_suave_runtime_adapter_test.go | 5 +++ suave/artifacts/SuaveLib.json | 2 +- suave/artifacts/addresses.go | 6 ++- .../df29ee92c6cbdf8433c246433ac49ec6.json | 1 + suave/e2e/workflow_test.go | 13 ++++++ suave/gen/suave_spec.yaml | 8 ++++ suave/sol/libraries/Suave.sol | 13 ++++++ 10 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 suave/artifacts/build-info/df29ee92c6cbdf8433c246433ac49ec6.json diff --git a/core/types/suave_structs.go b/core/types/suave_structs.go index d3d8aefcb..3ff89c3d3 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: 0433c95fed95ac0160125de152961adbf87bb072eb288b07cc35512c45cbd9ad +// Hash: 0c3427c1ad6242fe36606599fbb5d69d17fab52cab79a5350be8055daae46338 package types import "github.com/ethereum/go-ethereum/common" diff --git a/core/vm/contracts_suave.go b/core/vm/contracts_suave.go index 7ee92a80c..087980e47 100644 --- a/core/vm/contracts_suave.go +++ b/core/vm/contracts_suave.go @@ -8,6 +8,7 @@ import ( "crypto/rand" "fmt" "io" + "math/big" "net/http" "net/url" "strings" @@ -50,6 +51,10 @@ func (b *suaveRuntime) randomBytes(numBytes uint8) ([]byte, error) { return buf, nil } +func (b *suaveRuntime) getInsecureTime() (*big.Int, error) { + return big.NewInt(time.Now().UnixMilli()), nil +} + /* Confidential store precompiles */ func (b *suaveRuntime) confidentialStore(dataId types.DataId, key string, data []byte) error { diff --git a/core/vm/contracts_suave_runtime_adapter.go b/core/vm/contracts_suave_runtime_adapter.go index 0de431366..87a2b75a8 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: 0433c95fed95ac0160125de152961adbf87bb072eb288b07cc35512c45cbd9ad +// Hash: 0c3427c1ad6242fe36606599fbb5d69d17fab52cab79a5350be8055daae46338 package vm import ( @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/suave/artifacts" "github.com/mitchellh/mapstructure" + "math/big" ) var ( @@ -30,6 +31,7 @@ type SuaveRuntime interface { extractHint(bundleData []byte) ([]byte, error) fetchDataRecords(cond uint64, namespace string) ([]types.DataRecord, error) fillMevShareBundle(dataId types.DataId) ([]byte, error) + getInsecureTime() (*big.Int, error) newBuilder() (string, error) newDataRecord(decryptionCondition uint64, allowedPeekers []common.Address, allowedStores []common.Address, dataType string) (types.DataRecord, error) privateKeyGen(crypto types.CryptoSignature) (string, error) @@ -56,6 +58,7 @@ var ( extractHintAddr = common.HexToAddress("0x0000000000000000000000000000000042100037") fetchDataRecordsAddr = common.HexToAddress("0x0000000000000000000000000000000042030001") fillMevShareBundleAddr = common.HexToAddress("0x0000000000000000000000000000000043200001") + getInsecureTimeAddr = common.HexToAddress("0x000000000000000000000000000000007770000c") newBuilderAddr = common.HexToAddress("0x0000000000000000000000000000000053200001") newDataRecordAddr = common.HexToAddress("0x0000000000000000000000000000000042030000") privateKeyGenAddr = common.HexToAddress("0x0000000000000000000000000000000053200003") @@ -69,7 +72,7 @@ var ( ) var addrList = []common.Address{ - aesDecryptAddr, aesEncryptAddr, buildEthBlockAddr, buildEthBlockToAddr, confidentialInputsAddr, confidentialRetrieveAddr, confidentialStoreAddr, contextGetAddr, doHTTPRequestAddr, ethcallAddr, extractHintAddr, fetchDataRecordsAddr, fillMevShareBundleAddr, newBuilderAddr, newDataRecordAddr, privateKeyGenAddr, randomBytesAddr, signEthTransactionAddr, signMessageAddr, simulateBundleAddr, simulateTransactionAddr, submitBundleJsonRPCAddr, submitEthBlockToRelayAddr, + aesDecryptAddr, aesEncryptAddr, buildEthBlockAddr, buildEthBlockToAddr, confidentialInputsAddr, confidentialRetrieveAddr, confidentialStoreAddr, contextGetAddr, doHTTPRequestAddr, ethcallAddr, extractHintAddr, fetchDataRecordsAddr, fillMevShareBundleAddr, getInsecureTimeAddr, newBuilderAddr, newDataRecordAddr, privateKeyGenAddr, randomBytesAddr, signEthTransactionAddr, signMessageAddr, simulateBundleAddr, simulateTransactionAddr, submitBundleJsonRPCAddr, submitEthBlockToRelayAddr, } type SuaveRuntimeAdapter struct { @@ -117,6 +120,9 @@ func (b *SuaveRuntimeAdapter) run(addr common.Address, input []byte) ([]byte, er case fillMevShareBundleAddr: return b.fillMevShareBundle(input) + case getInsecureTimeAddr: + return b.getInsecureTime(input) + case newBuilderAddr: return b.newBuilder(input) @@ -676,6 +682,40 @@ func (b *SuaveRuntimeAdapter) fillMevShareBundle(input []byte) (res []byte, err } +func (b *SuaveRuntimeAdapter) getInsecureTime(input []byte) (res []byte, err error) { + var ( + unpacked []interface{} + result []byte + ) + + _ = unpacked + _ = result + + unpacked, err = artifacts.SuaveAbi.Methods["getInsecureTime"].Inputs.Unpack(input) + if err != nil { + err = errFailedToUnpackInput + return + } + + var () + + var ( + time *big.Int + ) + + if time, err = b.impl.getInsecureTime(); err != nil { + return + } + + result, err = artifacts.SuaveAbi.Methods["getInsecureTime"].Outputs.Pack(time) + if err != nil { + err = errFailedToPackOutput + return + } + return result, nil + +} + func (b *SuaveRuntimeAdapter) newBuilder(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 4133a3b53..c84138915 100644 --- a/core/vm/contracts_suave_runtime_adapter_test.go +++ b/core/vm/contracts_suave_runtime_adapter_test.go @@ -1,6 +1,7 @@ package vm import ( + "math/big" "testing" "github.com/ethereum/go-ethereum/accounts/abi" @@ -103,6 +104,10 @@ func (m *mockRuntime) randomBytes(length uint8) ([]byte, error) { return bytes, nil } +func (m *mockRuntime) getInsecureTime() (*big.Int, error) { + return big.NewInt(1), nil +} + func (m *mockRuntime) aesEncrypt(key []byte, message []byte) ([]byte, error) { return []byte{0x1}, nil } diff --git a/suave/artifacts/SuaveLib.json b/suave/artifacts/SuaveLib.json index 8f1893949..75715d483 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":"aesDecrypt","inputs":[{"name":"key","type":"bytes","internalType":"bytes"},{"name":"ciphertext","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"message","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"aesEncrypt","inputs":[{"name":"key","type":"bytes","internalType":"bytes"},{"name":"message","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"ciphertext","type":"bytes","internalType":"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":"beaconRoot","type":"bytes32","internalType":"bytes32"},{"name":"fillPending","type":"bool","internalType":"bool"}]},{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"relayUrl","type":"string","internalType":"string"}],"outputs":[{"name":"blockBid","type":"bytes","internalType":"bytes"},{"name":"executionPayload","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"buildEthBlockTo","inputs":[{"name":"executionNodeURL","type":"string","internalType":"string"},{"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":"beaconRoot","type":"bytes32","internalType":"bytes32"},{"name":"fillPending","type":"bool","internalType":"bool"}]},{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"relayUrl","type":"string","internalType":"string"}],"outputs":[{"name":"blockBid","type":"bytes","internalType":"bytes"},{"name":"executionPayload","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialInputs","outputs":[{"name":"confindentialData","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":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialStore","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"},{"name":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"contextGet","inputs":[{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"value","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"},{"name":"withFlashbotsSignature","type":"bool","internalType":"bool"},{"name":"timeout","type":"uint64","internalType":"uint64"}]}],"outputs":[{"name":"httpResponse","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"ethcall","inputs":[{"name":"contractAddr","type":"address","internalType":"address"},{"name":"input1","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"callOutput","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"extractHint","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"hints","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":"newBuilder","outputs":[{"name":"sessionid","type":"string","internalType":"string"}]},{"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":"privateKeyGen","inputs":[{"name":"crypto","type":"uint8","internalType":"struct Suave.CryptoSignature"}],"outputs":[{"name":"privateKey","type":"string","internalType":"string"}]},{"type":"function","name":"randomBytes","inputs":[{"name":"numBytes","type":"uint8","internalType":"uint8"}],"outputs":[{"name":"value","type":"bytes","internalType":"bytes"}]},{"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":"signedTxn","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"signMessage","inputs":[{"name":"digest","type":"bytes","internalType":"bytes"},{"name":"crypto","type":"uint8","internalType":"struct Suave.CryptoSignature"},{"name":"signingKey","type":"string","internalType":"string"}],"outputs":[{"name":"signature","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"simulateBundle","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"effectiveGasPrice","type":"uint64","internalType":"uint64"}]},{"type":"function","name":"simulateTransaction","inputs":[{"name":"sessionid","type":"string","internalType":"string"},{"name":"txn","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"simulationResult","type":"tuple","internalType":"struct Suave.SimulateTransactionResult","components":[{"name":"egp","type":"uint64","internalType":"uint64"},{"name":"logs","type":"tuple[]","internalType":"struct Suave.SimulatedLog[]","components":[{"name":"data","type":"bytes","internalType":"bytes"},{"name":"addr","type":"address","internalType":"address"},{"name":"topics","type":"bytes32[]","internalType":"bytes32[]"}]},{"name":"success","type":"bool","internalType":"bool"},{"name":"error","type":"string","internalType":"string"}]}]},{"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":"errorMessage","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"submitEthBlockToRelay","inputs":[{"name":"relayUrl","type":"string","internalType":"string"},{"name":"builderBid","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"blockBid","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":"aesDecrypt","inputs":[{"name":"key","type":"bytes","internalType":"bytes"},{"name":"ciphertext","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"message","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"aesEncrypt","inputs":[{"name":"key","type":"bytes","internalType":"bytes"},{"name":"message","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"ciphertext","type":"bytes","internalType":"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":"beaconRoot","type":"bytes32","internalType":"bytes32"},{"name":"fillPending","type":"bool","internalType":"bool"}]},{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"relayUrl","type":"string","internalType":"string"}],"outputs":[{"name":"blockBid","type":"bytes","internalType":"bytes"},{"name":"executionPayload","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"buildEthBlockTo","inputs":[{"name":"executionNodeURL","type":"string","internalType":"string"},{"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":"beaconRoot","type":"bytes32","internalType":"bytes32"},{"name":"fillPending","type":"bool","internalType":"bool"}]},{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"relayUrl","type":"string","internalType":"string"}],"outputs":[{"name":"blockBid","type":"bytes","internalType":"bytes"},{"name":"executionPayload","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialInputs","outputs":[{"name":"confindentialData","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":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialStore","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"},{"name":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"contextGet","inputs":[{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"value","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"},{"name":"withFlashbotsSignature","type":"bool","internalType":"bool"},{"name":"timeout","type":"uint64","internalType":"uint64"}]}],"outputs":[{"name":"httpResponse","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"ethcall","inputs":[{"name":"contractAddr","type":"address","internalType":"address"},{"name":"input1","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"callOutput","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"extractHint","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"hints","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":"getInsecureTime","outputs":[{"name":"time","type":"uint256","internalType":"uint256"}]},{"type":"function","name":"newBuilder","outputs":[{"name":"sessionid","type":"string","internalType":"string"}]},{"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":"privateKeyGen","inputs":[{"name":"crypto","type":"uint8","internalType":"struct Suave.CryptoSignature"}],"outputs":[{"name":"privateKey","type":"string","internalType":"string"}]},{"type":"function","name":"randomBytes","inputs":[{"name":"numBytes","type":"uint8","internalType":"uint8"}],"outputs":[{"name":"value","type":"bytes","internalType":"bytes"}]},{"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":"signedTxn","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"signMessage","inputs":[{"name":"digest","type":"bytes","internalType":"bytes"},{"name":"crypto","type":"uint8","internalType":"struct Suave.CryptoSignature"},{"name":"signingKey","type":"string","internalType":"string"}],"outputs":[{"name":"signature","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"simulateBundle","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"effectiveGasPrice","type":"uint64","internalType":"uint64"}]},{"type":"function","name":"simulateTransaction","inputs":[{"name":"sessionid","type":"string","internalType":"string"},{"name":"txn","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"simulationResult","type":"tuple","internalType":"struct Suave.SimulateTransactionResult","components":[{"name":"egp","type":"uint64","internalType":"uint64"},{"name":"logs","type":"tuple[]","internalType":"struct Suave.SimulatedLog[]","components":[{"name":"data","type":"bytes","internalType":"bytes"},{"name":"addr","type":"address","internalType":"address"},{"name":"topics","type":"bytes32[]","internalType":"bytes32[]"}]},{"name":"success","type":"bool","internalType":"bool"},{"name":"error","type":"string","internalType":"string"}]}]},{"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":"errorMessage","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"submitEthBlockToRelay","inputs":[{"name":"relayUrl","type":"string","internalType":"string"},{"name":"builderBid","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"blockBid","type":"bytes","internalType":"bytes"}]}] \ No newline at end of file diff --git a/suave/artifacts/addresses.go b/suave/artifacts/addresses.go index 3eed122d5..526f15144 100644 --- a/suave/artifacts/addresses.go +++ b/suave/artifacts/addresses.go @@ -1,5 +1,5 @@ // Code generated by suave/gen. DO NOT EDIT. -// Hash: 0433c95fed95ac0160125de152961adbf87bb072eb288b07cc35512c45cbd9ad +// Hash: 0c3427c1ad6242fe36606599fbb5d69d17fab52cab79a5350be8055daae46338 package artifacts import ( @@ -21,6 +21,7 @@ var ( extractHintAddr = common.HexToAddress("0x0000000000000000000000000000000042100037") fetchDataRecordsAddr = common.HexToAddress("0x0000000000000000000000000000000042030001") fillMevShareBundleAddr = common.HexToAddress("0x0000000000000000000000000000000043200001") + getInsecureTimeAddr = common.HexToAddress("0x000000000000000000000000000000007770000c") newBuilderAddr = common.HexToAddress("0x0000000000000000000000000000000053200001") newDataRecordAddr = common.HexToAddress("0x0000000000000000000000000000000042030000") privateKeyGenAddr = common.HexToAddress("0x0000000000000000000000000000000053200003") @@ -47,6 +48,7 @@ var SuaveMethods = map[string]common.Address{ "extractHint": extractHintAddr, "fetchDataRecords": fetchDataRecordsAddr, "fillMevShareBundle": fillMevShareBundleAddr, + "getInsecureTime": getInsecureTimeAddr, "newBuilder": newBuilderAddr, "newDataRecord": newDataRecordAddr, "privateKeyGen": privateKeyGenAddr, @@ -87,6 +89,8 @@ func PrecompileAddressToName(addr common.Address) string { return "fetchDataRecords" case fillMevShareBundleAddr: return "fillMevShareBundle" + case getInsecureTimeAddr: + return "getInsecureTime" case newBuilderAddr: return "newBuilder" case newDataRecordAddr: diff --git a/suave/artifacts/build-info/df29ee92c6cbdf8433c246433ac49ec6.json b/suave/artifacts/build-info/df29ee92c6cbdf8433c246433ac49ec6.json new file mode 100644 index 000000000..9afc48cdd --- /dev/null +++ b/suave/artifacts/build-info/df29ee92c6cbdf8433c246433ac49ec6.json @@ -0,0 +1 @@ +{"id":"df29ee92c6cbdf8433c246433ac49ec6","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"} \ No newline at end of file diff --git a/suave/e2e/workflow_test.go b/suave/e2e/workflow_test.go index 94179b2ad..6e0f27ffb 100644 --- a/suave/e2e/workflow_test.go +++ b/suave/e2e/workflow_test.go @@ -1371,6 +1371,19 @@ func TestE2E_Precompile_RandomBytes(t *testing.T) { require.Len(t, res[0], 64) } +func TestE2E_Precompile_GetInsecureTime(t *testing.T) { + fr := newFramework(t) + defer fr.Close() + + // get the current time from Unix + current := big.NewInt(time.Now().Unix()) + + // get the time from the precompile + res := fr.callPrecompile("getInsecureTime", []interface{}{}) + require.NotZero(t, res[0]) + require.GreaterOrEqual(t, res[0].(*big.Int).Int64(), current.Int64()) +} + func TestE2E_EmptyAddress(t *testing.T) { // it should not be possible to make a CCR to an empty address fr := newFramework(t) diff --git a/suave/gen/suave_spec.yaml b/suave/gen/suave_spec.yaml index 20fe2fd59..bbb251b41 100644 --- a/suave/gen/suave_spec.yaml +++ b/suave/gen/suave_spec.yaml @@ -475,3 +475,11 @@ functions: - name: message type: bytes description: "Decrypted message" + - name: getInsecureTime + address: "0x000000000000000000000000000000007770000c" + description: "Returns the current Kettle Unix time in milliseconds. Insecure because it assumes trust in Kettle's clock." + output: + fields: + - name: time + type: uint256 + description: "Current Unix time in milliseconds" diff --git a/suave/sol/libraries/Suave.sol b/suave/sol/libraries/Suave.sol index 3c85c3d1c..15fe9a2e8 100644 --- a/suave/sol/libraries/Suave.sol +++ b/suave/sol/libraries/Suave.sol @@ -134,6 +134,8 @@ library Suave { address public constant FILL_MEV_SHARE_BUNDLE = 0x0000000000000000000000000000000043200001; + address public constant GET_INSECURE_TIME = 0x000000000000000000000000000000007770000c; + address public constant NEW_BUILDER = 0x0000000000000000000000000000000053200001; address public constant NEW_DATA_RECORD = 0x0000000000000000000000000000000042030000; @@ -346,6 +348,17 @@ library Suave { return data; } + /// @notice Returns the current Kettle Unix time in seconds. + /// @return time Current Unix time in seconds + function getInsecureTime() internal returns (uint256) { + (bool success, bytes memory data) = GET_INSECURE_TIME.call(abi.encode()); + if (!success) { + revert PeekerReverted(GET_INSECURE_TIME, data); + } + + return abi.decode(data, (uint256)); + } + /// @notice Initializes a new remote builder session /// @return sessionid ID of the remote builder session function newBuilder() internal returns (string memory) {