From 91e8ee602cab90ff2401949ea0a05459af816211 Mon Sep 17 00:00:00 2001 From: Mateusz Morusiewicz <11313015+Ruteri@users.noreply.github.com> Date: Tue, 31 Oct 2023 18:30:03 +0100 Subject: [PATCH] Adds a prng precompile --- core/types/suave_structs.go | 2 +- core/vm/contracts_suave.go | 28 ++++++++++++++ core/vm/contracts_suave_runtime_adapter.go | 43 +++++++++++++++++++++- core/vm/contracts_suave_test.go | 10 ++++- suave/artifacts/Suave.sol/Suave.json | 17 ++++++++- suave/artifacts/SuaveLib.json | 2 +- suave/artifacts/addresses.go | 6 ++- suave/gen/suave_spec.yaml | 12 ++++++ suave/sol/libraries/Suave.sol | 16 ++++++++ suave/sol/libraries/SuaveForge.sol | 10 +++++ 10 files changed, 139 insertions(+), 7 deletions(-) diff --git a/core/types/suave_structs.go b/core/types/suave_structs.go index 250af51a2..e1606863c 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: 23a6dd8b9b224b11b8baea19a80c55c7787c50c0eb2fc69727e66d615c913483 +// Hash: 50dd3546404cc99388eeb67cd6dcf4428470f00edbd2e7341362d5c2fc89966b package types import "github.com/ethereum/go-ethereum/common" diff --git a/core/vm/contracts_suave.go b/core/vm/contracts_suave.go index 8cebbd1e3..f5eaabae7 100644 --- a/core/vm/contracts_suave.go +++ b/core/vm/contracts_suave.go @@ -1,6 +1,8 @@ package vm import ( + "crypto" + "crypto/rand" "errors" "fmt" "strings" @@ -332,6 +334,32 @@ func (b *suaveRuntime) buildEthBlock(blockArgs types.BuildBlockArgs, bid types.B return (&buildEthBlock{}).runImpl(b.suaveContext, blockArgs, bid, namespace) } +func (b *suaveRuntime) generatePseudoRandomBytes(numBytes uint64, domainSeparator []byte) ([]byte, error) { + if numBytes > (2 << 16) { // refuse to generate more than 65kB + return nil, errors.New("refusing to generate more than 65kB random bytes") + } + + nChunks := (numBytes + 31) / 32 // align with 32-byte blocks + buf := make([]byte, nChunks*32) + nRead, err := rand.Read(buf) + if err != nil { + return nil, err + } + + if uint64(nRead) != nChunks*32 { + return nil, errors.New("too many bytes") + } + + for chunk := 0; uint64(chunk) < nChunks; chunk++ { + // buf[0:31] = sha256(initial random buf, domainSeparator) + // buf[32:64] = sha256(sha256(initial random buf, domainSeparator), domainSeparator) + // ... + copy(buf[chunk*32:], crypto.SHA256.New().Sum(append(buf, domainSeparator...))) + } + + return buf[:numBytes], nil +} + func (b *suaveRuntime) confidentialInputs() ([]byte, error) { return (&confidentialInputsPrecompile{}).RunConfidential(b.suaveContext, nil) } diff --git a/core/vm/contracts_suave_runtime_adapter.go b/core/vm/contracts_suave_runtime_adapter.go index 359216a04..50ab09df7 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: 23a6dd8b9b224b11b8baea19a80c55c7787c50c0eb2fc69727e66d615c913483 +// Hash: 50dd3546404cc99388eeb67cd6dcf4428470f00edbd2e7341362d5c2fc89966b package vm import ( @@ -25,6 +25,7 @@ type SuaveRuntime interface { extractHint(bundleData []byte) ([]byte, error) fetchBids(cond uint64, namespace string) ([]types.Bid, error) fillMevShareBundle(bidId types.BidId) ([]byte, error) + generatePseudoRandomBytes(numBytes uint64, domainSeparator []byte) ([]byte, error) newBid(decryptionCondition uint64, allowedPeekers []common.Address, allowedStores []common.Address, bidType string) (types.Bid, error) signEthTransaction(txn []byte, chainId string, signingKey string) ([]byte, error) simulateBundle(bundleData []byte) (uint64, error) @@ -41,6 +42,7 @@ var ( extractHintAddr = common.HexToAddress("0x0000000000000000000000000000000042100037") fetchBidsAddr = common.HexToAddress("0x0000000000000000000000000000000042030001") fillMevShareBundleAddr = common.HexToAddress("0x0000000000000000000000000000000043200001") + generatePseudoRandomBytesAddr = common.HexToAddress("0x0000000000000000000000000000000040100000") newBidAddr = common.HexToAddress("0x0000000000000000000000000000000042030000") signEthTransactionAddr = common.HexToAddress("0x0000000000000000000000000000000040100001") simulateBundleAddr = common.HexToAddress("0x0000000000000000000000000000000042100000") @@ -78,6 +80,9 @@ func (b *SuaveRuntimeAdapter) run(addr common.Address, input []byte) ([]byte, er case fillMevShareBundleAddr: return b.fillMevShareBundle(input) + case generatePseudoRandomBytesAddr: + return b.generatePseudoRandomBytes(input) + case newBidAddr: return b.newBid(input) @@ -409,6 +414,42 @@ func (b *SuaveRuntimeAdapter) fillMevShareBundle(input []byte) (res []byte, err } +func (b *SuaveRuntimeAdapter) generatePseudoRandomBytes(input []byte) (res []byte, err error) { + var ( + unpacked []interface{} + result []byte + ) + + _ = unpacked + _ = result + + unpacked, err = artifacts.SuaveAbi.Methods["generatePseudoRandomBytes"].Inputs.Unpack(input) + if err != nil { + err = errFailedToUnpackInput + return + } + + var ( + numBytes uint64 + domainSeparator []byte + ) + + numBytes = unpacked[0].(uint64) + domainSeparator = unpacked[1].([]byte) + + var ( + output1 []byte + ) + + if output1, err = b.impl.generatePseudoRandomBytes(numBytes, domainSeparator); err != nil { + return + } + + result = output1 + return result, nil + +} + func (b *SuaveRuntimeAdapter) newBid(input []byte) (res []byte, err error) { var ( unpacked []interface{} diff --git a/core/vm/contracts_suave_test.go b/core/vm/contracts_suave_test.go index fa817c6ad..e9db44960 100644 --- a/core/vm/contracts_suave_test.go +++ b/core/vm/contracts_suave_test.go @@ -118,6 +118,7 @@ func TestSuavePrecompileStub(t *testing.T) { // error in 'buildEthBlock' when it expects to retrieve bids in abi format from the // confidential store. "could not unpack merged bid ids", + "key not formatted properly: invalid length, need 256 bits", "no caller of confidentialStoreRetrieve (0000000000000000000000000000000042020001) is allowed on 00000000000000000000000000000000", "precompile fillMevShareBundle (0000000000000000000000000000000043200001) not allowed on 00000000000000000000000000000000", "no caller of confidentialStoreStore (0000000000000000000000000000000042020000) is allowed on 00000000000000000000000000000000", @@ -125,7 +126,7 @@ func TestSuavePrecompileStub(t *testing.T) { } expectedVariableErrors := []*regexp.Regexp{ - regexp.MustCompile("key not formatted properly: invalid hex character.*in private key"), + regexp.MustCompile("key not formatted properly: invalid hex .* private key"), } for name, addr := range artifacts.SuaveMethods { @@ -253,3 +254,10 @@ func TestSuave_ConfStoreWorkflow(t *testing.T) { _, err = b.confidentialStoreRetrieve(bid.Id, "key") require.Error(t, err) } + +func TestSuave_PRNG(t *testing.T) { + b := newTestBackend(t) + randomBytes, err := b.generatePseudoRandomBytes(100, []byte("xxx")) + require.NoError(t, err) + require.Equal(t, 100, len(randomBytes)) +} diff --git a/suave/artifacts/Suave.sol/Suave.json b/suave/artifacts/Suave.sol/Suave.json index 1bb8dd8f0..2bf188e08 100644 --- a/suave/artifacts/Suave.sol/Suave.json +++ b/suave/artifacts/Suave.sol/Suave.json @@ -120,6 +120,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "GENERATE_PSEUDO_RANDOM_BYTES", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "IS_CONFIDENTIAL_ADDR", @@ -200,9 +213,9 @@ } ], "deployedBytecode": { - "object": "0x73000000000000000000000000000000000000000030146080604052600436106100f45760003560e01c8063b61b127d11610096578063c91e11df11610070578063c91e11df14610183578063d91525db1461018e578063f0608b1c14610199578063f6ab3de5146101a457600080fd5b8063b61b127d14610162578063b7817da01461016d578063bc50c0051461017857600080fd5b80637320cb17116100d25780637320cb1714610136578063744795b914610141578063751afe2c1461014c57806394804c691461015757600080fd5b806301c19530146100f9578063040e51831461012057806369094cbc1461012b575b600080fd5b610104634320000181565b6040516001600160a01b03909116815260200160405180910390f35b610104634210000381565b610104634201000181565b610104634203000081565b610104634010000181565b610104634210003781565b610104634210000181565b610104634210000081565b610104634202000081565b610104634210000281565b610104634203000181565b610104634201000081565b610104634300000181565b61010463420200018156fea164736f6c6343000813000a" + "object": "0x73000000000000000000000000000000000000000030146080604052600436106100ff5760003560e01c806394804c69116100a1578063c91e11df11610070578063c91e11df1461018e578063d91525db14610199578063f0608b1c146101a4578063f6ab3de5146101af57600080fd5b806394804c6914610162578063b61b127d1461016d578063b7817da014610178578063bc50c0051461018357600080fd5b806369094cbc116100dd57806369094cbc146101415780637320cb171461014c578063744795b914610136578063751afe2c1461015757600080fd5b806301c1953014610104578063040e51831461012b5780634d1f1ab114610136575b600080fd5b61010f634320000181565b6040516001600160a01b03909116815260200160405180910390f35b61010f634210000381565b61010f634010000181565b61010f634201000181565b61010f634203000081565b61010f634210003781565b61010f634210000181565b61010f634210000081565b61010f634202000081565b61010f634210000281565b61010f634203000181565b61010f634201000081565b61010f634300000181565b61010f63420200018156fea164736f6c6343000813000a" }, "bytecode": { - "object": "0x6101bc61003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100f45760003560e01c8063b61b127d11610096578063c91e11df11610070578063c91e11df14610183578063d91525db1461018e578063f0608b1c14610199578063f6ab3de5146101a457600080fd5b8063b61b127d14610162578063b7817da01461016d578063bc50c0051461017857600080fd5b80637320cb17116100d25780637320cb1714610136578063744795b914610141578063751afe2c1461014c57806394804c691461015757600080fd5b806301c19530146100f9578063040e51831461012057806369094cbc1461012b575b600080fd5b610104634320000181565b6040516001600160a01b03909116815260200160405180910390f35b610104634210000381565b610104634201000181565b610104634203000081565b610104634010000181565b610104634210003781565b610104634210000181565b610104634210000081565b610104634202000081565b610104634210000281565b610104634203000181565b610104634201000081565b610104634300000181565b61010463420200018156fea164736f6c6343000813000a" + "object": "0x6101c761003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100ff5760003560e01c806394804c69116100a1578063c91e11df11610070578063c91e11df1461018e578063d91525db14610199578063f0608b1c146101a4578063f6ab3de5146101af57600080fd5b806394804c6914610162578063b61b127d1461016d578063b7817da014610178578063bc50c0051461018357600080fd5b806369094cbc116100dd57806369094cbc146101415780637320cb171461014c578063744795b914610136578063751afe2c1461015757600080fd5b806301c1953014610104578063040e51831461012b5780634d1f1ab114610136575b600080fd5b61010f634320000181565b6040516001600160a01b03909116815260200160405180910390f35b61010f634210000381565b61010f634010000181565b61010f634201000181565b61010f634203000081565b61010f634210003781565b61010f634210000181565b61010f634210000081565b61010f634202000081565b61010f634210000281565b61010f634203000181565b61010f634201000081565b61010f634300000181565b61010f63420200018156fea164736f6c6343000813000a" } } diff --git a/suave/artifacts/SuaveLib.json b/suave/artifacts/SuaveLib.json index b2dd7839f..c40a6c896 100644 --- a/suave/artifacts/SuaveLib.json +++ b/suave/artifacts/SuaveLib.json @@ -1 +1 @@ -[{"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":"bidId","type":"bytes16","internalType":"struct Suave.BidId"},{"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":"confidentialStoreRetrieve","inputs":[{"name":"bidId","type":"bytes16","internalType":"struct Suave.BidId"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialStoreStore","inputs":[{"name":"bidId","type":"bytes16","internalType":"struct Suave.BidId"},{"name":"key","type":"string","internalType":"string"},{"name":"data1","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":"fetchBids","inputs":[{"name":"cond","type":"uint64","internalType":"uint64"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"bid","type":"tuple[]","internalType":"struct Suave.Bid[]","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.BidId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.BidId"},{"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":"bidId","type":"bytes16","internalType":"struct Suave.BidId"}],"outputs":[{"name":"encodedBundle","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"newBid","inputs":[{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"bidType","type":"string","internalType":"string"}],"outputs":[{"name":"bid","type":"tuple","internalType":"struct Suave.Bid","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.BidId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.BidId"},{"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":"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":"bidId","type":"bytes16","internalType":"struct Suave.BidId"},{"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":"confidentialStoreRetrieve","inputs":[{"name":"bidId","type":"bytes16","internalType":"struct Suave.BidId"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialStoreStore","inputs":[{"name":"bidId","type":"bytes16","internalType":"struct Suave.BidId"},{"name":"key","type":"string","internalType":"string"},{"name":"data1","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":"fetchBids","inputs":[{"name":"cond","type":"uint64","internalType":"uint64"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"bid","type":"tuple[]","internalType":"struct Suave.Bid[]","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.BidId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.BidId"},{"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":"bidId","type":"bytes16","internalType":"struct Suave.BidId"}],"outputs":[{"name":"encodedBundle","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"generatePseudoRandomBytes","inputs":[{"name":"numBytes","type":"uint64","internalType":"uint64"},{"name":"domainSeparator","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"output1","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"newBid","inputs":[{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"bidType","type":"string","internalType":"string"}],"outputs":[{"name":"bid","type":"tuple","internalType":"struct Suave.Bid","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.BidId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.BidId"},{"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 3abe51d48..d49f41182 100644 --- a/suave/artifacts/addresses.go +++ b/suave/artifacts/addresses.go @@ -1,5 +1,5 @@ // Code generated by suave/gen. DO NOT EDIT. -// Hash: 23a6dd8b9b224b11b8baea19a80c55c7787c50c0eb2fc69727e66d615c913483 +// Hash: 50dd3546404cc99388eeb67cd6dcf4428470f00edbd2e7341362d5c2fc89966b package artifacts import ( @@ -16,6 +16,7 @@ var ( extractHintAddr = common.HexToAddress("0x0000000000000000000000000000000042100037") fetchBidsAddr = common.HexToAddress("0x0000000000000000000000000000000042030001") fillMevShareBundleAddr = common.HexToAddress("0x0000000000000000000000000000000043200001") + generatePseudoRandomBytesAddr = common.HexToAddress("0x0000000000000000000000000000000040100000") newBidAddr = common.HexToAddress("0x0000000000000000000000000000000042030000") signEthTransactionAddr = common.HexToAddress("0x0000000000000000000000000000000040100001") simulateBundleAddr = common.HexToAddress("0x0000000000000000000000000000000042100000") @@ -32,6 +33,7 @@ var SuaveMethods = map[string]common.Address{ "extractHint": extractHintAddr, "fetchBids": fetchBidsAddr, "fillMevShareBundle": fillMevShareBundleAddr, + "generatePseudoRandomBytes": generatePseudoRandomBytesAddr, "newBid": newBidAddr, "signEthTransaction": signEthTransactionAddr, "simulateBundle": simulateBundleAddr, @@ -57,6 +59,8 @@ func PrecompileAddressToName(addr common.Address) string { return "fetchBids" case fillMevShareBundleAddr: return "fillMevShareBundle" + case generatePseudoRandomBytesAddr: + return "generatePseudoRandomBytes" case newBidAddr: return "newBid" case signEthTransactionAddr: diff --git a/suave/gen/suave_spec.yaml b/suave/gen/suave_spec.yaml index e60fc7443..996e93479 100644 --- a/suave/gen/suave_spec.yaml +++ b/suave/gen/suave_spec.yaml @@ -52,6 +52,18 @@ functions: fields: - name: output1 type: bytes + - name: generatePseudoRandomBytes + address: "0x0000000000000000000000000000000040100000" + input: + - name: numBytes + type: uint64 + - name: domainSeparator + type: bytes + output: + packed: true + fields: + - name: output1 + type: bytes - name: newBid address: "0x0000000000000000000000000000000042030000" input: diff --git a/suave/sol/libraries/Suave.sol b/suave/sol/libraries/Suave.sol index 3923371d5..b5520342c 100644 --- a/suave/sol/libraries/Suave.sol +++ b/suave/sol/libraries/Suave.sol @@ -51,6 +51,8 @@ library Suave { address public constant FILL_MEV_SHARE_BUNDLE = 0x0000000000000000000000000000000043200001; + address public constant GENERATE_PSEUDO_RANDOM_BYTES = 0x0000000000000000000000000000000040100000; + address public constant NEW_BID = 0x0000000000000000000000000000000042030000; address public constant SIGN_ETH_TRANSACTION = 0x0000000000000000000000000000000040100001; @@ -151,6 +153,20 @@ library Suave { return data; } + function generatePseudoRandomBytes(uint64 numBytes, bytes memory domainSeparator) + internal + view + returns (bytes memory) + { + (bool success, bytes memory data) = + GENERATE_PSEUDO_RANDOM_BYTES.staticcall(abi.encode(numBytes, domainSeparator)); + if (!success) { + revert PeekerReverted(GENERATE_PSEUDO_RANDOM_BYTES, data); + } + + return data; + } + function newBid( uint64 decryptionCondition, address[] memory allowedPeekers, diff --git a/suave/sol/libraries/SuaveForge.sol b/suave/sol/libraries/SuaveForge.sol index 490a94a68..b96090ba3 100644 --- a/suave/sol/libraries/SuaveForge.sol +++ b/suave/sol/libraries/SuaveForge.sol @@ -87,6 +87,16 @@ library SuaveForge { return data; } + function generatePseudoRandomBytes(uint64 numBytes, bytes memory domainSeparator) + internal + view + returns (bytes memory) + { + bytes memory data = forgeIt("0x0000000000000000000000000000000040100000", abi.encode(numBytes, domainSeparator)); + + return data; + } + function newBid( uint64 decryptionCondition, address[] memory allowedPeekers,