diff --git a/suave/backends/local_store_backend.go b/suave/backends/local_store_backend.go new file mode 100644 index 0000000000..6ed97cd7b7 --- /dev/null +++ b/suave/backends/local_store_backend.go @@ -0,0 +1,112 @@ +package backends + +import ( + "errors" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + suave "github.com/ethereum/go-ethereum/suave/core" +) + +var _ suave.ConfidentialStoreBackend = &LocalConfidentialStore{} + +type LocalConfidentialStore struct { + lock sync.Mutex + bids map[suave.BidId]suave.Bid + dataMap map[string][]byte + index map[string][]suave.BidId +} + +func NewLocalConfidentialStore() *LocalConfidentialStore { + return &LocalConfidentialStore{ + bids: make(map[suave.BidId]suave.Bid), + dataMap: make(map[string][]byte), + index: make(map[string][]suave.BidId), + } +} + +func (l *LocalConfidentialStore) Start() error { + return nil +} + +func (l *LocalConfidentialStore) Stop() error { + return nil +} + +func (l *LocalConfidentialStore) InitializeBid(bid suave.Bid) error { + l.lock.Lock() + defer l.lock.Unlock() + + _, found := l.bids[bid.Id] + if found { + return suave.ErrBidAlreadyPresent + } + + l.bids[bid.Id] = bid + + // index the bid by (protocol, block number) + indexKey := fmt.Sprintf("protocol-%s-bn-%d", bid.Version, bid.DecryptionCondition) + bidIds := l.index[indexKey] + bidIds = append(bidIds, bid.Id) + l.index[indexKey] = bidIds + + return nil +} + +func (l *LocalConfidentialStore) Store(bid suave.Bid, caller common.Address, key string, value []byte) (suave.Bid, error) { + l.lock.Lock() + defer l.lock.Unlock() + + l.dataMap[fmt.Sprintf("%x-%s", bid.Id, key)] = append(make([]byte, 0, len(value)), value...) + + defer log.Trace("CSSW", "caller", caller, "key", key, "value", value, "stored", l.dataMap[fmt.Sprintf("%x-%s", bid.Id, key)]) + return bid, nil +} + +func (l *LocalConfidentialStore) Retrieve(bid suave.Bid, caller common.Address, key string) ([]byte, error) { + l.lock.Lock() + defer l.lock.Unlock() + + data, found := l.dataMap[fmt.Sprintf("%x-%s", bid.Id, key)] + if !found { + return []byte{}, fmt.Errorf("data for key %s not found", key) + } + + log.Trace("CSRW", "caller", caller, "key", key, "data", data) + return append(make([]byte, 0, len(data)), data...), nil +} + +func (l *LocalConfidentialStore) FetchBidById(bidId suave.BidId) (suave.Bid, error) { + l.lock.Lock() + defer l.lock.Unlock() + + bid, found := l.bids[bidId] + if !found { + return suave.Bid{}, errors.New("bid not found") + } + + return bid, nil +} + +func (l *LocalConfidentialStore) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []suave.Bid { + l.lock.Lock() + defer l.lock.Unlock() + + indexKey := fmt.Sprintf("protocol-%s-bn-%d", namespace, blockNumber) + bidIDs, ok := l.index[indexKey] + if !ok { + return nil + } + + res := []suave.Bid{} + for _, id := range bidIDs { + bid, found := l.bids[id] + if found { + res = append(res, bid) + } + } + + return res +} diff --git a/suave/backends/local_store_backend_test.go b/suave/backends/local_store_backend_test.go new file mode 100644 index 0000000000..9da3bb1e35 --- /dev/null +++ b/suave/backends/local_store_backend_test.go @@ -0,0 +1,10 @@ +package backends + +import ( + "testing" +) + +func TestLocal_StoreSuite(t *testing.T) { + store := NewLocalConfidentialStore() + testBackendStore(t, store) +} diff --git a/suave/backends/redis_store_backend.go b/suave/backends/redis_store_backend.go index a005e424fa..d108ca7909 100644 --- a/suave/backends/redis_store_backend.go +++ b/suave/backends/redis_store_backend.go @@ -15,6 +15,8 @@ import ( "github.com/go-redis/redis/v8" ) +var _ suave.ConfidentialStoreBackend = &RedisStoreBackend{} + var ( formatRedisBidKey = func(bidId suave.BidId) string { return fmt.Sprintf("bid-%x", bidId) @@ -35,10 +37,6 @@ type RedisStoreBackend struct { local *miniredis.Miniredis } -func NewLocalConfidentialStore() *RedisStoreBackend { - return NewRedisStoreBackend("") -} - func NewRedisStoreBackend(redisUri string) *RedisStoreBackend { r := &RedisStoreBackend{ cancel: nil,