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

Engine store api #53

Merged
merged 3 commits into from
Oct 2, 2023
Merged
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
8 changes: 7 additions & 1 deletion core/vm/contracts_suave.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,13 @@ func (c *fetchBids) RunConfidential(suaveContext *SuaveContext, input []byte) ([
}

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

bids := make([]types.Bid, 0, len(bids1))
for _, bid := range bids1 {
bids = append(bids, bid.ToInnerBid())
}

return bids, nil
}

Expand Down
3 changes: 2 additions & 1 deletion core/vm/contracts_suave_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,11 @@ func (c *buildEthBlock) runImpl(suaveContext *SuaveContext, blockArgs types.Buil
for i, bidId := range bidIds {
var err error

bidsToMerge[i], err = suaveContext.Backend.ConfidentialStoreEngine.FetchBidById(bidId)
bid, err := suaveContext.Backend.ConfidentialStoreEngine.FetchBidById(bidId)
if err != nil {
return nil, nil, fmt.Errorf("could not fetch bid id %v: %w", bidId, err)
}
bidsToMerge[i] = bid.ToInnerBid()
}

var mergedBundles []types.SBundle
Expand Down
10 changes: 5 additions & 5 deletions core/vm/contracts_suave_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ func (m *mockSuaveBackend) FetchEngineBidById(suave.BidId) (suave.Bid, error) {
return suave.Bid{}, nil
}

func (m *mockSuaveBackend) FetchBidById(suave.BidId) (types.Bid, error) {
return types.Bid{}, nil
func (m *mockSuaveBackend) FetchBidById(suave.BidId) (suave.Bid, error) {
return suave.Bid{}, nil
}

func (m *mockSuaveBackend) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []types.Bid {
func (m *mockSuaveBackend) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []suave.Bid {
return nil
}

Expand Down Expand Up @@ -179,10 +179,10 @@ func TestSuave_BidWorkflow(t *testing.T) {
namespace string
bids []types.Bid
}{
{0, "a", nil},
{0, "a", []types.Bid{}},
{5, "a", []types.Bid{bid5}},
{10, "a", []types.Bid{bid10, bid10b}},
{11, "a", nil},
{11, "a", []types.Bid{}},
}

for _, c := range cases {
Expand Down
4 changes: 2 additions & 2 deletions core/vm/suave.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ type ConfidentialStore interface {
InitializeBid(bid types.Bid, creationTx *types.Transaction) (types.Bid, error)
Store(bidId suave.BidId, sourceTx *types.Transaction, caller common.Address, key string, value []byte) (suave.Bid, error)
Retrieve(bid types.BidId, caller common.Address, key string) ([]byte, error)
FetchBidById(suave.BidId) (types.Bid, error)
FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []types.Bid
FetchBidById(suave.BidId) (suave.Bid, error)
FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []suave.Bid
}

type SuaveContext struct {
Expand Down
36 changes: 36 additions & 0 deletions suave/backends/backend_testing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package backends

import (
"testing"

"github.com/ethereum/go-ethereum/common"
suave "github.com/ethereum/go-ethereum/suave/core"
"github.com/stretchr/testify/require"
)

func testBackendStore(t *testing.T, store suave.ConfidentialStoreBackend) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A generic testing suite for any type of backend store.

bid := suave.Bid{
Id: suave.RandomBidId(),
DecryptionCondition: 10,
AllowedPeekers: []common.Address{common.HexToAddress("0x424344")},
Version: "default:v0:ethBundles",
}

err := store.InitializeBid(bid)
require.NoError(t, err)

bidRes, err := store.FetchBidById(bid.Id)
require.NoError(t, err)
require.Equal(t, bid, bidRes)

_, err = store.Store(bid, bid.AllowedPeekers[0], "xx", []byte{0x43, 0x14})
require.NoError(t, err)

retrievedData, err := store.Retrieve(bid, bid.AllowedPeekers[0], "xx")
require.NoError(t, err)
require.Equal(t, []byte{0x43, 0x14}, retrievedData)

bids := store.FetchBidsByProtocolAndBlock(10, "default:v0:ethBundles")
require.Len(t, bids, 1)
require.Equal(t, bid, bids[0])
}
31 changes: 1 addition & 30 deletions suave/backends/redis_backends_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,35 +60,6 @@ func TestRedisTransport(t *testing.T) {
}
}

func TestRedisStore(t *testing.T) {
mr := miniredis.RunT(t)

redisStoreBackend := NewRedisStoreBackend(mr.Addr())
redisStoreBackend.Start()
t.Cleanup(func() { redisStoreBackend.Stop() })

bid := suave.Bid{
Id: suave.BidId{0x42},
DecryptionCondition: uint64(13),
AllowedPeekers: []common.Address{{0x41, 0x39}},
Version: string("vv"),
}

err := redisStoreBackend.InitializeBid(bid)
require.NoError(t, err)

fetchedBid, err := redisStoreBackend.FetchEngineBidById(bid.Id)
require.NoError(t, err)
require.Equal(t, bid, fetchedBid)

_, err = redisStoreBackend.Store(bid, bid.AllowedPeekers[0], "xx", []byte{0x43, 0x14})
require.NoError(t, err)

retrievedData, err := redisStoreBackend.Retrieve(bid, bid.AllowedPeekers[0], "xx")
require.NoError(t, err)
require.Equal(t, []byte{0x43, 0x14}, retrievedData)
}

func TestEngineOnRedis(t *testing.T) {
mrStore1 := miniredis.RunT(t)
mrStore2 := miniredis.RunT(t)
Expand Down Expand Up @@ -174,7 +145,7 @@ func TestEngineOnRedis(t *testing.T) {
require.NoError(t, err)
require.Equal(t, []byte{0x43, 0x14}, retrievedData)

fetchedBid, err := redisStoreBackend2.FetchEngineBidById(bid.Id)
fetchedBid, err := redisStoreBackend2.FetchBidById(bid.Id)
require.NoError(t, err)

fetchedBidJson, err := json.Marshal(fetchedBid)
Expand Down
50 changes: 25 additions & 25 deletions suave/backends/redis_store_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,15 @@ func (r *RedisStoreBackend) InitializeBid(bid suave.Bid) error {
return err
}

err = r.indexBid(bid)
if err != nil {
return err
}

return nil
}

func (r *RedisStoreBackend) FetchEngineBidById(bidId suave.BidId) (suave.Bid, error) {
func (r *RedisStoreBackend) FetchBidById(bidId suave.BidId) (suave.Bid, error) {
key := formatRedisBidKey(bidId)

data, err := r.client.Get(r.ctx, key).Bytes()
Expand Down Expand Up @@ -158,44 +163,39 @@ var (
mempoolConfidentialStoreBid = suave.Bid{Id: mempoolConfStoreId, AllowedPeekers: []common.Address{mempoolConfStoreAddr}}
)

func (r *RedisStoreBackend) SubmitBid(bid types.Bid) error {
func (r *RedisStoreBackend) indexBid(bid suave.Bid) error {
defer log.Info("bid submitted", "bid", bid, "store", r.Store)

var bidsByBlockAndProtocol []types.Bid
var bidsByBlockAndProtocol []suave.BidId
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indexing was changed to include only the bid id and no add extra space storing the bids again.

bidsByBlockAndProtocolBytes, err := r.Retrieve(mempoolConfidentialStoreBid, mempoolConfStoreAddr, fmt.Sprintf("protocol-%s-bn-%d", bid.Version, bid.DecryptionCondition))
if err == nil {
bidsByBlockAndProtocol = suave.MustDecode[[]types.Bid](bidsByBlockAndProtocolBytes)
bidsByBlockAndProtocol = suave.MustDecode[[]suave.BidId](bidsByBlockAndProtocolBytes)
}
// store bid by block number and by protocol + block number
bidsByBlockAndProtocol = append(bidsByBlockAndProtocol, bid)
bidsByBlockAndProtocol = append(bidsByBlockAndProtocol, bid.Id)

r.Store(mempoolConfidentialStoreBid, mempoolConfStoreAddr, fmt.Sprintf("protocol-%s-bn-%d", bid.Version, bid.DecryptionCondition), suave.MustEncode(bidsByBlockAndProtocol))

return nil
}

func (r *RedisStoreBackend) FetchBidById(bidId suave.BidId) (types.Bid, error) {
engineBid, err := r.FetchEngineBidById(bidId)
if err != nil {
log.Error("bid missing!", "id", bidId, "err", err)
return types.Bid{}, errors.New("not found")
}

return types.Bid{
Id: engineBid.Id,
Salt: engineBid.Salt,
DecryptionCondition: engineBid.DecryptionCondition,
AllowedPeekers: engineBid.AllowedPeekers,
AllowedStores: engineBid.AllowedStores,
Version: engineBid.Version,
}, nil
}

func (r *RedisStoreBackend) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []types.Bid {
func (r *RedisStoreBackend) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []suave.Bid {
bidsByProtocolBytes, err := r.Retrieve(mempoolConfidentialStoreBid, mempoolConfStoreAddr, fmt.Sprintf("protocol-%s-bn-%d", namespace, blockNumber))
if err != nil {
return nil
}
defer log.Info("bids fetched", "bids", string(bidsByProtocolBytes))
return suave.MustDecode[[]types.Bid](bidsByProtocolBytes)

res := []suave.Bid{}

bidIDs := suave.MustDecode[[]suave.BidId](bidsByProtocolBytes)
for _, id := range bidIDs {
bid, err := r.FetchBidById(id)
if err != nil {
continue
}
res = append(res, bid)
}

// defer log.Info("bids fetched", "bids", string(bidsByProtocolBytes))
return res
}
14 changes: 14 additions & 0 deletions suave/backends/redis_store_backend_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package backends

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestRedis_StoreSuite(t *testing.T) {
store := NewRedisStoreBackend("")
require.NoError(t, store.Start())

testBackendStore(t, store)
}
19 changes: 6 additions & 13 deletions suave/core/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,28 +170,23 @@ func (e *ConfidentialStoreEngine) InitializeBid(bid types.Bid, creationTx *types
return types.Bid{}, fmt.Errorf("confidential engine: store backend failed to initialize bid: %w", err)
}

// send the bid to the internal mempool
if err := e.backend.SubmitBid(bid); err != nil {
return types.Bid{}, fmt.Errorf("failed to submit to mempool: %w", err)
}

return bid, nil
}

func (e *ConfidentialStoreEngine) SubmitBid(bid types.Bid) error {
return e.backend.SubmitBid(bid)
func (e *ConfidentialStoreEngine) StoreBid(bid Bid) error {
return e.backend.InitializeBid(bid)
}

func (e *ConfidentialStoreEngine) FetchBidById(bidId BidId) (types.Bid, error) {
func (e *ConfidentialStoreEngine) FetchBidById(bidId BidId) (Bid, error) {
return e.backend.FetchBidById(bidId)
}

func (e *ConfidentialStoreEngine) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []types.Bid {
func (e *ConfidentialStoreEngine) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []Bid {
return e.backend.FetchBidsByProtocolAndBlock(blockNumber, namespace)
}

func (e *ConfidentialStoreEngine) Store(bidId BidId, sourceTx *types.Transaction, caller common.Address, key string, value []byte) (Bid, error) {
bid, err := e.backend.FetchEngineBidById(bidId)
bid, err := e.backend.FetchBidById(bidId)
if err != nil {
return Bid{}, fmt.Errorf("confidential engine: could not fetch bid %x while storing: %w", bidId, err)
}
Expand Down Expand Up @@ -231,7 +226,7 @@ func (e *ConfidentialStoreEngine) Store(bidId BidId, sourceTx *types.Transaction
}

func (e *ConfidentialStoreEngine) Retrieve(bidId BidId, caller common.Address, key string) ([]byte, error) {
bid, err := e.backend.FetchEngineBidById(bidId)
bid, err := e.backend.FetchBidById(bidId)
if err != nil {
return []byte{}, fmt.Errorf("confidential engine: could not fetch bid %x while retrieving: %w", bidId, err)
}
Expand Down Expand Up @@ -329,8 +324,6 @@ func (e *ConfidentialStoreEngine) NewMessage(message DAMessage) error {
if !errors.Is(err, ErrBidAlreadyPresent) {
return fmt.Errorf("unexpected error while initializing bid from transport: %w", err)
}
} else {
e.backend.SubmitBid(innerBid)
}

_, err = e.backend.Store(message.Bid, message.Caller, message.Key, message.Value)
Expand Down
6 changes: 3 additions & 3 deletions suave/core/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ func (*FakeStoreBackend) Retrieve(bid Bid, caller common.Address, key string) ([
return nil, errors.New("not implemented")
}

func (*FakeStoreBackend) FetchBidById(BidId) (types.Bid, error) {
return types.Bid{}, nil
func (*FakeStoreBackend) FetchBidById(BidId) (Bid, error) {
return Bid{}, nil
}

func (*FakeStoreBackend) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []types.Bid {
func (*FakeStoreBackend) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []Bid {
return nil
}

Expand Down
19 changes: 13 additions & 6 deletions suave/core/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ type Bid struct {
Signature []byte
}

func (b *Bid) ToInnerBid() types.Bid {
return types.Bid{
Id: b.Id,
Salt: b.Salt,
DecryptionCondition: b.DecryptionCondition,
AllowedPeekers: b.AllowedPeekers,
AllowedStores: b.AllowedStores,
Version: b.Version,
}
}

type MEVMBid = types.Bid

type BuildBlockArgs = types.BuildBlockArgs
Expand All @@ -38,14 +49,10 @@ type ConfidentialStoreBackend interface {
node.Lifecycle

InitializeBid(bid Bid) error
FetchEngineBidById(bidId BidId) (Bid, error)
Store(bid Bid, caller common.Address, key string, value []byte) (Bid, error)
Retrieve(bid Bid, caller common.Address, key string) ([]byte, error)
FetchBidById(BidId) (types.Bid, error)
FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []types.Bid

// TODO: remove this
SubmitBid(types.Bid) error
FetchBidById(BidId) (Bid, error)
FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []Bid
}

type ConfidentialEthBackend interface {
Expand Down
12 changes: 6 additions & 6 deletions suave/e2e/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,22 +137,22 @@ func TestMempool(t *testing.T) {
{
targetBlock := uint64(16103213)

bid1 := types.Bid{
bid1 := suave.Bid{
Id: suave.RandomBidId(),
DecryptionCondition: targetBlock,
AllowedPeekers: []common.Address{common.HexToAddress("0x424344")},
Version: "default:v0:ethBundles",
}

bid2 := types.Bid{
bid2 := suave.Bid{
Id: suave.RandomBidId(),
DecryptionCondition: targetBlock,
AllowedPeekers: []common.Address{common.HexToAddress("0x424344")},
Version: "default:v0:ethBundles",
}

require.NoError(t, fr.ConfidentialStore().SubmitBid(bid1))
require.NoError(t, fr.ConfidentialStore().SubmitBid(bid2))
require.NoError(t, fr.ConfidentialStore().StoreBid(bid1))
require.NoError(t, fr.ConfidentialStore().StoreBid(bid2))

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")

Expand All @@ -174,13 +174,13 @@ func TestMempool(t *testing.T) {
var bids []suave.Bid
require.NoError(t, mapstructure.Decode(unpacked[0], &bids))

require.Equal(t, bid1, types.Bid{
require.Equal(t, bid1, suave.Bid{
Id: bids[0].Id,
DecryptionCondition: bids[0].DecryptionCondition,
AllowedPeekers: bids[0].AllowedPeekers,
Version: bids[0].Version,
})
require.Equal(t, bid2, types.Bid{
require.Equal(t, bid2, suave.Bid{
Id: bids[1].Id,
DecryptionCondition: bids[1].DecryptionCondition,
AllowedPeekers: bids[1].AllowedPeekers,
Expand Down