From b157a4a67f8de4db36a1e23afd153ed59bca99a8 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Fri, 20 Oct 2023 13:32:35 +0200 Subject: [PATCH] Da store as a single package (#71) * Move things to custom package * Move core types to cstore * Finish * Pass lint --- core/vm/contracts_suave_test.go | 12 +- eth/api_backend.go | 5 +- eth/backend.go | 20 +-- suave/backends/redis_store_backend_test.go | 14 -- suave/core/types.go | 31 ---- suave/core/utils.go | 18 --- suave/{backends => cstore}/am_signer.go | 2 +- suave/{backends => cstore}/backend_testing.go | 4 +- suave/{core => cstore}/engine.go | 133 +++++++++++++----- suave/{core => cstore}/engine_test.go | 25 ++-- .../local_store_backend.go | 8 +- .../local_store_backend_test.go | 2 +- .../redis_backends_test.go | 18 +-- .../redis_store_backend.go | 14 +- suave/cstore/redis_store_backend_test.go | 10 ++ suave/{backends => cstore}/redis_transport.go | 11 +- suave/{core => cstore}/transactional_store.go | 17 +-- .../transactional_store_test.go | 6 +- suave/e2e/workflow_test.go | 7 +- 19 files changed, 187 insertions(+), 170 deletions(-) delete mode 100644 suave/backends/redis_store_backend_test.go rename suave/{backends => cstore}/am_signer.go (98%) rename suave/{backends => cstore}/backend_testing.go (90%) rename suave/{core => cstore}/engine.go (72%) rename suave/{core => cstore}/engine_test.go (77%) rename suave/{backends => cstore}/local_store_backend.go (94%) rename suave/{backends => cstore}/local_store_backend_test.go (88%) rename suave/{backends => cstore}/redis_backends_test.go (88%) rename suave/{backends => cstore}/redis_store_backend.go (94%) create mode 100644 suave/cstore/redis_store_backend_test.go rename suave/{backends => cstore}/redis_transport.go (94%) rename suave/{core => cstore}/transactional_store.go (78%) rename suave/{backends => cstore}/transactional_store_test.go (93%) diff --git a/core/vm/contracts_suave_test.go b/core/vm/contracts_suave_test.go index f232564f6..f86bb8493 100644 --- a/core/vm/contracts_suave_test.go +++ b/core/vm/contracts_suave_test.go @@ -14,8 +14,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/suave/artifacts" - "github.com/ethereum/go-ethereum/suave/backends" suave "github.com/ethereum/go-ethereum/suave/core" + "github.com/ethereum/go-ethereum/suave/cstore" "github.com/stretchr/testify/require" ) @@ -61,11 +61,11 @@ func (m *mockSuaveBackend) BuildEthBlockFromBundles(ctx context.Context, args *s return nil, nil } -func (m *mockSuaveBackend) Subscribe() (<-chan suave.DAMessage, context.CancelFunc) { +func (m *mockSuaveBackend) Subscribe() (<-chan cstore.DAMessage, context.CancelFunc) { return nil, func() {} } -func (m *mockSuaveBackend) Publish(suave.DAMessage) {} +func (m *mockSuaveBackend) Publish(cstore.DAMessage) {} var dummyBlockContext = BlockContext{ CanTransfer: func(StateDB, common.Address, *big.Int) bool { return true }, @@ -77,7 +77,7 @@ func TestSuavePrecompileStub(t *testing.T) { // This test ensures that the Suave precompile stubs work as expected // for encoding/decoding. mockSuaveBackend := &mockSuaveBackend{} - stubEngine := suave.NewConfidentialStoreEngine(mockSuaveBackend, mockSuaveBackend, suave.MockSigner{}, suave.MockChainSigner{}) + stubEngine := cstore.NewConfidentialStoreEngine(mockSuaveBackend, mockSuaveBackend, cstore.MockSigner{}, cstore.MockChainSigner{}) reqTx := types.NewTx(&types.ConfidentialComputeRequest{ ConfidentialComputeRecord: types.ConfidentialComputeRecord{ @@ -142,8 +142,8 @@ func TestSuavePrecompileStub(t *testing.T) { } func newTestBackend(t *testing.T) *suaveRuntime { - confStore := backends.NewLocalConfidentialStore() - confEngine := suave.NewConfidentialStoreEngine(confStore, &suave.MockTransport{}, suave.MockSigner{}, suave.MockChainSigner{}) + confStore := cstore.NewLocalConfidentialStore() + confEngine := cstore.NewConfidentialStoreEngine(confStore, &cstore.MockTransport{}, cstore.MockSigner{}, cstore.MockChainSigner{}) require.NoError(t, confEngine.Start()) t.Cleanup(func() { confEngine.Stop() }) diff --git a/eth/api_backend.go b/eth/api_backend.go index 3e5cade3e..dd9cf068f 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -41,6 +41,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" suave "github.com/ethereum/go-ethereum/suave/core" + "github.com/ethereum/go-ethereum/suave/cstore" ) // EthAPIBackend implements ethapi.Backend for full nodes @@ -49,12 +50,12 @@ type EthAPIBackend struct { allowUnprotectedTxs bool eth *Ethereum gpo *gasprice.Oracle - suaveEngine *suave.ConfidentialStoreEngine + suaveEngine *cstore.ConfidentialStoreEngine suaveEthBackend suave.ConfidentialEthBackend } // For testing purposes -func (b *EthAPIBackend) SuaveEngine() *suave.ConfidentialStoreEngine { +func (b *EthAPIBackend) SuaveEngine() *cstore.ConfidentialStoreEngine { return b.suaveEngine } diff --git a/eth/backend.go b/eth/backend.go index d0cf690ca..db249455b 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -58,6 +58,7 @@ import ( "github.com/ethereum/go-ethereum/suave/backends" suave_backends "github.com/ethereum/go-ethereum/suave/backends" suave "github.com/ethereum/go-ethereum/suave/core" + "github.com/ethereum/go-ethereum/suave/cstore" ) // Config contains the configuration options of the ETH protocol. @@ -230,18 +231,21 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { eth.miner = miner.New(eth, &config.Miner, eth.blockchain.Config(), eth.EventMux(), eth.engine, eth.isLocalBlock) eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) - var confidentialStoreBackend suave.ConfidentialStoreBackend + var confidentialStoreBackend cstore.ConfidentialStorageBackend if config.Suave.RedisStoreUri != "" { - confidentialStoreBackend = suave_backends.NewRedisStoreBackend(config.Suave.RedisStoreUri) + confidentialStoreBackend, err = cstore.NewRedisStoreBackend(config.Suave.RedisStoreUri) + if err != nil { + return nil, err + } } else { - confidentialStoreBackend = suave_backends.NewLocalConfidentialStore() + confidentialStoreBackend = cstore.NewLocalConfidentialStore() } - var confidentialStoreTransport suave.StoreTransportTopic + var confidentialStoreTransport cstore.StoreTransportTopic if config.Suave.RedisStorePubsubUri != "" { - confidentialStoreTransport = suave_backends.NewRedisPubSubTransport(config.Suave.RedisStorePubsubUri) + confidentialStoreTransport = cstore.NewRedisPubSubTransport(config.Suave.RedisStorePubsubUri) } else { - confidentialStoreTransport = suave.MockTransport{} + confidentialStoreTransport = cstore.MockTransport{} } var suaveEthBackend suave.ConfidentialEthBackend @@ -251,9 +255,9 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { suaveEthBackend = &suave_backends.EthMock{} } - suaveDaSigner := &suave_backends.AccountManagerDASigner{Manager: eth.AccountManager()} + suaveDaSigner := &cstore.AccountManagerDASigner{Manager: eth.AccountManager()} - confidentialStoreEngine := suave.NewConfidentialStoreEngine(confidentialStoreBackend, confidentialStoreTransport, suaveDaSigner, types.LatestSigner(chainConfig)) + confidentialStoreEngine := cstore.NewConfidentialStoreEngine(confidentialStoreBackend, confidentialStoreTransport, suaveDaSigner, types.LatestSigner(chainConfig)) eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil, confidentialStoreEngine, suaveEthBackend} if eth.APIBackend.allowUnprotectedTxs { diff --git a/suave/backends/redis_store_backend_test.go b/suave/backends/redis_store_backend_test.go deleted file mode 100644 index 07db156de..000000000 --- a/suave/backends/redis_store_backend_test.go +++ /dev/null @@ -1,14 +0,0 @@ -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) -} diff --git a/suave/core/types.go b/suave/core/types.go index 89c5d9e23..e1694b81c 100644 --- a/suave/core/types.go +++ b/suave/core/types.go @@ -9,7 +9,6 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/node" - "github.com/google/uuid" ) type Bytes = hexutil.Bytes @@ -48,16 +47,6 @@ var ( ErrUnsignedFinalize = errors.New("finalize called with unsigned transaction, refusing to propagate") ) -type DASigner interface { - Sign(account common.Address, data []byte) ([]byte, error) - Sender(data []byte, signature []byte) (common.Address, error) - LocalAddresses() []common.Address -} - -type ChainSigner interface { - Sender(tx *types.Transaction) (common.Address, error) -} - type ConfidentialStoreBackend interface { node.Lifecycle @@ -72,23 +61,3 @@ type ConfidentialEthBackend interface { BuildEthBlock(ctx context.Context, args *BuildBlockArgs, txs types.Transactions) (*engine.ExecutionPayloadEnvelope, error) BuildEthBlockFromBundles(ctx context.Context, args *BuildBlockArgs, bundles []types.SBundle) (*engine.ExecutionPayloadEnvelope, error) } - -type StoreTransportTopic interface { - node.Lifecycle - Subscribe() (<-chan DAMessage, context.CancelFunc) - Publish(DAMessage) -} - -type DAMessage struct { - SourceTx *types.Transaction `json:"sourceTx"` - StoreWrites []StoreWrite `json:"storeWrites"` - StoreUUID uuid.UUID `json:"storeUUID"` - Signature Bytes `json:"signature"` -} - -type StoreWrite struct { - Bid Bid `json:"bid"` - Caller common.Address `json:"caller"` - Key string `json:"key"` - Value Bytes `json:"value"` -} diff --git a/suave/core/utils.go b/suave/core/utils.go index 18f1937bc..ba4b59b99 100644 --- a/suave/core/utils.go +++ b/suave/core/utils.go @@ -2,29 +2,11 @@ package suave import ( "encoding/json" - "fmt" "github.com/ethereum/go-ethereum/core/types" "github.com/google/uuid" ) -var bidUuidSpace = uuid.UUID{0x42} -var emptyId [16]byte - -func calculateBidId(bid types.Bid) (types.BidId, error) { - copy(bid.Id[:], emptyId[:]) - - body, err := json.Marshal(bid) - if err != nil { - return types.BidId{}, fmt.Errorf("could not marshal bid to calculate its id: %w", err) - } - - uuidv5 := uuid.NewSHA1(bidUuidSpace, body) - copy(bid.Id[:], uuidv5[:]) - - return bid.Id, nil -} - func RandomBidId() types.BidId { return types.BidId(uuid.New()) } diff --git a/suave/backends/am_signer.go b/suave/cstore/am_signer.go similarity index 98% rename from suave/backends/am_signer.go rename to suave/cstore/am_signer.go index 07d513e8a..046a29688 100644 --- a/suave/backends/am_signer.go +++ b/suave/cstore/am_signer.go @@ -1,4 +1,4 @@ -package backends +package cstore import ( "github.com/ethereum/go-ethereum/accounts" diff --git a/suave/backends/backend_testing.go b/suave/cstore/backend_testing.go similarity index 90% rename from suave/backends/backend_testing.go rename to suave/cstore/backend_testing.go index 49232b2db..2adebffd4 100644 --- a/suave/backends/backend_testing.go +++ b/suave/cstore/backend_testing.go @@ -1,4 +1,4 @@ -package backends +package cstore import ( "testing" @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" ) -func testBackendStore(t *testing.T, store suave.ConfidentialStoreBackend) { +func testBackendStore(t *testing.T, store ConfidentialStorageBackend) { bid := suave.Bid{ Id: suave.RandomBidId(), DecryptionCondition: 10, diff --git a/suave/core/engine.go b/suave/cstore/engine.go similarity index 72% rename from suave/core/engine.go rename to suave/cstore/engine.go index 49bc91484..6104a5695 100644 --- a/suave/core/engine.go +++ b/suave/cstore/engine.go @@ -1,4 +1,4 @@ -package suave +package cstore import ( "context" @@ -9,15 +9,60 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + suave "github.com/ethereum/go-ethereum/suave/core" "github.com/google/uuid" "golang.org/x/exp/slices" ) +// ConfidentialStorageBackend is the interface that must be implemented by a +// storage backend for the confidential storage engine. +type ConfidentialStorageBackend interface { + InitializeBid(bid suave.Bid) error + Store(bid suave.Bid, caller common.Address, key string, value []byte) (suave.Bid, error) + Retrieve(bid suave.Bid, caller common.Address, key string) ([]byte, error) + FetchBidById(suave.BidId) (suave.Bid, error) + FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []suave.Bid + Stop() error +} + +// StoreTransportTopic is the interface that must be implemented by a +// transport engine for the confidential storage engine. +type StoreTransportTopic interface { + node.Lifecycle + Subscribe() (<-chan DAMessage, context.CancelFunc) + Publish(DAMessage) +} + +type DAMessage struct { + SourceTx *types.Transaction `json:"sourceTx"` + StoreWrites []StoreWrite `json:"storeWrites"` + StoreUUID uuid.UUID `json:"storeUUID"` + Signature suave.Bytes `json:"signature"` +} + +type StoreWrite struct { + Bid suave.Bid `json:"bid"` + Caller common.Address `json:"caller"` + Key string `json:"key"` + Value suave.Bytes `json:"value"` +} + +type DASigner interface { + Sign(account common.Address, data []byte) ([]byte, error) + Sender(data []byte, signature []byte) (common.Address, error) + LocalAddresses() []common.Address +} + +type ChainSigner interface { + Sender(tx *types.Transaction) (common.Address, error) +} + type ConfidentialStoreEngine struct { ctx context.Context cancel context.CancelFunc - backend ConfidentialStoreBackend + storage ConfidentialStorageBackend transportTopic StoreTransportTopic daSigner DASigner @@ -27,14 +72,14 @@ type ConfidentialStoreEngine struct { localAddresses map[common.Address]struct{} } -func NewConfidentialStoreEngine(backend ConfidentialStoreBackend, transportTopic StoreTransportTopic, daSigner DASigner, chainSigner ChainSigner) *ConfidentialStoreEngine { +func NewConfidentialStoreEngine(backend ConfidentialStorageBackend, transportTopic StoreTransportTopic, daSigner DASigner, chainSigner ChainSigner) *ConfidentialStoreEngine { localAddresses := make(map[common.Address]struct{}) for _, addr := range daSigner.LocalAddresses() { localAddresses[addr] = struct{}{} } return &ConfidentialStoreEngine{ - backend: backend, + storage: backend, transportTopic: transportTopic, daSigner: daSigner, chainSigner: chainSigner, @@ -47,15 +92,11 @@ func (e *ConfidentialStoreEngine) NewTransactionalStore(sourceTx *types.Transact return &TransactionalStore{ sourceTx: sourceTx, engine: e, - pendingBids: make(map[BidId]Bid), + pendingBids: make(map[suave.BidId]suave.Bid), } } func (e *ConfidentialStoreEngine) Start() error { - if err := e.backend.Start(); err != nil { - return err - } - if err := e.transportTopic.Start(); err != nil { return err } @@ -83,7 +124,7 @@ func (e *ConfidentialStoreEngine) Stop() error { log.Warn("Confidential engine: error while stopping transport", "err", err) } - if err := e.backend.Stop(); err != nil { + if err := e.storage.Stop(); err != nil { log.Warn("Confidential engine: error while stopping transport", "err", err) } @@ -91,8 +132,8 @@ func (e *ConfidentialStoreEngine) Stop() error { } // For testing purposes! -func (e *ConfidentialStoreEngine) Backend() ConfidentialStoreBackend { - return e.backend +func (e *ConfidentialStoreEngine) Backend() ConfidentialStorageBackend { + return e.storage } func (e *ConfidentialStoreEngine) ProcessMessages() { @@ -114,20 +155,20 @@ func (e *ConfidentialStoreEngine) ProcessMessages() { } } -func (e *ConfidentialStoreEngine) InitializeBid(bid types.Bid, creationTx *types.Transaction) (Bid, error) { +func (e *ConfidentialStoreEngine) InitializeBid(bid types.Bid, creationTx *types.Transaction) (suave.Bid, error) { expectedId, err := calculateBidId(bid) if err != nil { - return Bid{}, fmt.Errorf("confidential engine: could not initialize new bid: %w", err) + return suave.Bid{}, fmt.Errorf("confidential engine: could not initialize new bid: %w", err) } if bid.Id == emptyId { bid.Id = expectedId } else if bid.Id != expectedId { // True in some tests, might be time to rewrite them - return Bid{}, errors.New("confidential engine:incorrect bid id passed") + return suave.Bid{}, errors.New("confidential engine:incorrect bid id passed") } - initializedBid := Bid{ + initializedBid := suave.Bid{ Id: bid.Id, Salt: bid.Salt, DecryptionCondition: bid.DecryptionCondition, @@ -139,32 +180,32 @@ func (e *ConfidentialStoreEngine) InitializeBid(bid types.Bid, creationTx *types bidBytes, err := SerializeBidForSigning(&initializedBid) if err != nil { - return Bid{}, fmt.Errorf("confidential engine: could not hash bid for signing: %w", err) + return suave.Bid{}, fmt.Errorf("confidential engine: could not hash bid for signing: %w", err) } signingAccount, err := ExecutionNodeFromTransaction(creationTx) if err != nil { - return Bid{}, fmt.Errorf("confidential engine: could not recover execution node from creation transaction: %w", err) + return suave.Bid{}, fmt.Errorf("confidential engine: could not recover execution node from creation transaction: %w", err) } initializedBid.Signature, err = e.daSigner.Sign(signingAccount, bidBytes) if err != nil { - return Bid{}, fmt.Errorf("confidential engine: could not sign initialized bid: %w", err) + return suave.Bid{}, fmt.Errorf("confidential engine: could not sign initialized bid: %w", err) } return initializedBid, nil } -func (e *ConfidentialStoreEngine) FetchBidById(bidId BidId) (Bid, error) { - return e.backend.FetchBidById(bidId) +func (e *ConfidentialStoreEngine) FetchBidById(bidId suave.BidId) (suave.Bid, error) { + return e.storage.FetchBidById(bidId) } -func (e *ConfidentialStoreEngine) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []Bid { - return e.backend.FetchBidsByProtocolAndBlock(blockNumber, namespace) +func (e *ConfidentialStoreEngine) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []suave.Bid { + return e.storage.FetchBidsByProtocolAndBlock(blockNumber, namespace) } -func (e *ConfidentialStoreEngine) Retrieve(bidId BidId, caller common.Address, key string) ([]byte, error) { - bid, err := e.backend.FetchBidById(bidId) +func (e *ConfidentialStoreEngine) Retrieve(bidId suave.BidId, caller common.Address, key string) ([]byte, error) { + bid, err := e.storage.FetchBidById(bidId) if err != nil { return []byte{}, fmt.Errorf("confidential engine: could not fetch bid %x while retrieving: %w", bidId, err) } @@ -173,13 +214,13 @@ func (e *ConfidentialStoreEngine) Retrieve(bidId BidId, caller common.Address, k return []byte{}, fmt.Errorf("confidential engine: %x not allowed to retrieve %s on %x", caller, key, bidId) } - return e.backend.Retrieve(bid, caller, key) + return e.storage.Retrieve(bid, caller, key) } -func (e *ConfidentialStoreEngine) Finalize(tx *types.Transaction, newBids map[BidId]Bid, stores []StoreWrite) error { +func (e *ConfidentialStoreEngine) Finalize(tx *types.Transaction, newBids map[suave.BidId]suave.Bid, stores []StoreWrite) error { // for _, bid := range newBids { - err := e.backend.InitializeBid(bid) + err := e.storage.InitializeBid(bid) if err != nil { // TODO: deinitialize! return fmt.Errorf("confidential engine: store backend failed to initialize bid: %w", err) @@ -187,7 +228,7 @@ func (e *ConfidentialStoreEngine) Finalize(tx *types.Transaction, newBids map[Bi } for _, sw := range stores { - if _, err := e.backend.Store(sw.Bid, sw.Caller, sw.Key, sw.Value); err != nil { + if _, err := e.storage.Store(sw.Bid, sw.Caller, sw.Key, sw.Value); err != nil { // TODO: deinitialize and deStore! return fmt.Errorf("failed to store data: %w", err) } @@ -202,7 +243,7 @@ func (e *ConfidentialStoreEngine) Finalize(tx *types.Transaction, newBids map[Bi if _, sigErr := e.chainSigner.Sender(tx); sigErr != nil { log.Info("confidential engine: refusing to send writes based on unsigned transaction", "hash", tx.Hash().Hex(), "err", sigErr) - return ErrUnsignedFinalize + return suave.ErrUnsignedFinalize } msgBytes, err := SerializeMessageForSigning(&pwMsg) @@ -312,15 +353,15 @@ func (e *ConfidentialStoreEngine) NewMessage(message DAMessage) error { } for _, sw := range message.StoreWrites { - err = e.backend.InitializeBid(sw.Bid) + err = e.storage.InitializeBid(sw.Bid) if err != nil { - if !errors.Is(err, ErrBidAlreadyPresent) { + if !errors.Is(err, suave.ErrBidAlreadyPresent) { log.Error("confidential engine: unexpected error while initializing bid from transport: %w", err) continue // Don't abandon! } } - _, err = e.backend.Store(sw.Bid, sw.Caller, sw.Key, sw.Value) + _, err = e.storage.Store(sw.Bid, sw.Caller, sw.Key, sw.Value) if err != nil { log.Error("confidential engine: unexpected error while storing: %w", err) continue // Don't abandon! @@ -330,8 +371,8 @@ func (e *ConfidentialStoreEngine) NewMessage(message DAMessage) error { return nil } -func SerializeBidForSigning(bid *Bid) ([]byte, error) { - bidBytes, err := json.Marshal(Bid{ +func SerializeBidForSigning(bid *suave.Bid) ([]byte, error) { + bidBytes, err := json.Marshal(suave.Bid{ Id: bid.Id, Salt: bid.Salt, DecryptionCondition: bid.DecryptionCondition, @@ -408,3 +449,25 @@ func ExecutionNodeFromTransaction(tx *types.Transaction) (common.Address, error) return common.Address{}, fmt.Errorf("transaction is not of confidential type") } + +var emptyId [16]byte + +var bidUuidSpace = uuid.UUID{0x42} + +func calculateBidId(bid types.Bid) (types.BidId, error) { + copy(bid.Id[:], emptyId[:]) + + body, err := json.Marshal(bid) + if err != nil { + return types.BidId{}, fmt.Errorf("could not marshal bid to calculate its id: %w", err) + } + + uuidv5 := uuid.NewSHA1(bidUuidSpace, body) + copy(bid.Id[:], uuidv5[:]) + + return bid.Id, nil +} + +func RandomBidId() types.BidId { + return types.BidId(uuid.New()) +} diff --git a/suave/core/engine_test.go b/suave/cstore/engine_test.go similarity index 77% rename from suave/core/engine_test.go rename to suave/cstore/engine_test.go index 9466d2e41..5037d872f 100644 --- a/suave/core/engine_test.go +++ b/suave/cstore/engine_test.go @@ -1,4 +1,4 @@ -package suave +package cstore import ( "errors" @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + suave "github.com/ethereum/go-ethereum/suave/core" "github.com/google/uuid" "github.com/stretchr/testify/require" ) @@ -25,29 +26,29 @@ func (FakeDASigner) Sender(data []byte, signature []byte) (common.Address, error func (f FakeDASigner) LocalAddresses() []common.Address { return f.localAddresses } type FakeStoreBackend struct { - OnStore func(bid Bid, caller common.Address, key string, value []byte) (Bid, error) + OnStore func(bid suave.Bid, caller common.Address, key string, value []byte) (suave.Bid, error) } func (*FakeStoreBackend) Start() error { return nil } func (*FakeStoreBackend) Stop() error { return nil } -func (*FakeStoreBackend) InitializeBid(bid Bid) error { return nil } -func (*FakeStoreBackend) FetchEngineBidById(bidId BidId) (Bid, error) { - return Bid{}, errors.New("not implemented") +func (*FakeStoreBackend) InitializeBid(bid suave.Bid) error { return nil } +func (*FakeStoreBackend) FetchEngineBidById(bidId suave.BidId) (suave.Bid, error) { + return suave.Bid{}, errors.New("not implemented") } -func (b *FakeStoreBackend) Store(bid Bid, caller common.Address, key string, value []byte) (Bid, error) { +func (b *FakeStoreBackend) Store(bid suave.Bid, caller common.Address, key string, value []byte) (suave.Bid, error) { return b.OnStore(bid, caller, key, value) } -func (*FakeStoreBackend) Retrieve(bid Bid, caller common.Address, key string) ([]byte, error) { +func (*FakeStoreBackend) Retrieve(bid suave.Bid, caller common.Address, key string) ([]byte, error) { return nil, errors.New("not implemented") } -func (*FakeStoreBackend) FetchBidById(BidId) (Bid, error) { - return Bid{}, nil +func (*FakeStoreBackend) FetchBidById(suave.BidId) (suave.Bid, error) { + return suave.Bid{}, nil } -func (*FakeStoreBackend) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []Bid { +func (*FakeStoreBackend) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []suave.Bid { return nil } @@ -57,7 +58,7 @@ func (*FakeStoreBackend) SubmitBid(types.Bid) error { func TestOwnMessageDropping(t *testing.T) { var wasCalled *bool = new(bool) - fakeStore := FakeStoreBackend{OnStore: func(bid Bid, caller common.Address, key string, value []byte) (Bid, error) { + fakeStore := FakeStoreBackend{OnStore: func(bid suave.Bid, caller common.Address, key string, value []byte) (suave.Bid, error) { *wasCalled = true return bid, nil }} @@ -79,7 +80,7 @@ func TestOwnMessageDropping(t *testing.T) { AllowedPeekers: []common.Address{{}}, }) require.NoError(t, err) - testBid := Bid{ + testBid := suave.Bid{ Id: bidId, CreationTx: dummyCreationTx, AllowedStores: []common.Address{{0x42}}, diff --git a/suave/backends/local_store_backend.go b/suave/cstore/local_store_backend.go similarity index 94% rename from suave/backends/local_store_backend.go rename to suave/cstore/local_store_backend.go index 6ed97cd7b..872a92d38 100644 --- a/suave/backends/local_store_backend.go +++ b/suave/cstore/local_store_backend.go @@ -1,4 +1,4 @@ -package backends +package cstore import ( "errors" @@ -10,7 +10,7 @@ import ( suave "github.com/ethereum/go-ethereum/suave/core" ) -var _ suave.ConfidentialStoreBackend = &LocalConfidentialStore{} +var _ ConfidentialStorageBackend = &LocalConfidentialStore{} type LocalConfidentialStore struct { lock sync.Mutex @@ -27,10 +27,6 @@ func NewLocalConfidentialStore() *LocalConfidentialStore { } } -func (l *LocalConfidentialStore) Start() error { - return nil -} - func (l *LocalConfidentialStore) Stop() error { return nil } diff --git a/suave/backends/local_store_backend_test.go b/suave/cstore/local_store_backend_test.go similarity index 88% rename from suave/backends/local_store_backend_test.go rename to suave/cstore/local_store_backend_test.go index 9da3bb1e3..8d7b6be29 100644 --- a/suave/backends/local_store_backend_test.go +++ b/suave/cstore/local_store_backend_test.go @@ -1,4 +1,4 @@ -package backends +package cstore import ( "testing" diff --git a/suave/backends/redis_backends_test.go b/suave/cstore/redis_backends_test.go similarity index 88% rename from suave/backends/redis_backends_test.go rename to suave/cstore/redis_backends_test.go index 6c9ed81ad..c7186c455 100644 --- a/suave/backends/redis_backends_test.go +++ b/suave/cstore/redis_backends_test.go @@ -1,4 +1,4 @@ -package backends +package cstore import ( "encoding/json" @@ -24,8 +24,8 @@ func TestRedisTransport(t *testing.T) { msgSub, cancel := redisPubSub.Subscribe() t.Cleanup(cancel) - daMsg := suave.DAMessage{ - StoreWrites: []suave.StoreWrite{{ + daMsg := DAMessage{ + StoreWrites: []StoreWrite{{ Bid: suave.Bid{ Id: suave.BidId{0x42}, DecryptionCondition: uint64(13), @@ -69,16 +69,16 @@ func TestEngineOnRedis(t *testing.T) { mrPubSub := mrStore1 redisPubSub1 := NewRedisPubSubTransport(mrPubSub.Addr()) - redisStoreBackend1 := NewRedisStoreBackend(mrStore1.Addr()) + redisStoreBackend1, _ := NewRedisStoreBackend(mrStore1.Addr()) - engine1 := suave.NewConfidentialStoreEngine(redisStoreBackend1, redisPubSub1, suave.MockSigner{}, suave.MockChainSigner{}) + engine1 := NewConfidentialStoreEngine(redisStoreBackend1, redisPubSub1, MockSigner{}, MockChainSigner{}) require.NoError(t, engine1.Start()) t.Cleanup(func() { engine1.Stop() }) redisPubSub2 := NewRedisPubSubTransport(mrPubSub.Addr()) - redisStoreBackend2 := NewRedisStoreBackend(mrStore2.Addr()) + redisStoreBackend2, _ := NewRedisStoreBackend(mrStore2.Addr()) - engine2 := suave.NewConfidentialStoreEngine(redisStoreBackend2, redisPubSub2, suave.MockSigner{}, suave.MockChainSigner{}) + engine2 := NewConfidentialStoreEngine(redisStoreBackend2, redisPubSub2, MockSigner{}, MockChainSigner{}) require.NoError(t, engine2.Start()) t.Cleanup(func() { engine2.Stop() }) @@ -94,7 +94,7 @@ func TestEngineOnRedis(t *testing.T) { bid, err := engine1.InitializeBid(types.Bid{ DecryptionCondition: uint64(13), AllowedPeekers: []common.Address{{0x41, 0x39}}, - AllowedStores: []common.Address{common.Address{}}, + AllowedStores: []common.Address{{}}, Version: string("vv"), }, dummyCreationTx) require.NoError(t, err) @@ -108,7 +108,7 @@ func TestEngineOnRedis(t *testing.T) { t.Cleanup(cancel) // Trigger propagation - err = engine1.Finalize(dummyCreationTx, nil, []suave.StoreWrite{{ + err = engine1.Finalize(dummyCreationTx, nil, []StoreWrite{{ Bid: bid, Caller: bid.AllowedPeekers[0], Key: "xx", diff --git a/suave/backends/redis_store_backend.go b/suave/cstore/redis_store_backend.go similarity index 94% rename from suave/backends/redis_store_backend.go rename to suave/cstore/redis_store_backend.go index d108ca790..55ac60aa8 100644 --- a/suave/backends/redis_store_backend.go +++ b/suave/cstore/redis_store_backend.go @@ -1,4 +1,4 @@ -package backends +package cstore import ( "context" @@ -15,7 +15,7 @@ import ( "github.com/go-redis/redis/v8" ) -var _ suave.ConfidentialStoreBackend = &RedisStoreBackend{} +var _ ConfidentialStorageBackend = &RedisStoreBackend{} var ( formatRedisBidKey = func(bidId suave.BidId) string { @@ -37,15 +37,19 @@ type RedisStoreBackend struct { local *miniredis.Miniredis } -func NewRedisStoreBackend(redisUri string) *RedisStoreBackend { +func NewRedisStoreBackend(redisUri string) (*RedisStoreBackend, error) { r := &RedisStoreBackend{ cancel: nil, redisUri: redisUri, } - return r + + if err := r.start(); err != nil { + return nil, err + } + return r, nil } -func (r *RedisStoreBackend) Start() error { +func (r *RedisStoreBackend) start() error { if r.redisUri == "" { // create a mini-redis instance localRedis, err := miniredis.Run() diff --git a/suave/cstore/redis_store_backend_test.go b/suave/cstore/redis_store_backend_test.go new file mode 100644 index 000000000..2962584c8 --- /dev/null +++ b/suave/cstore/redis_store_backend_test.go @@ -0,0 +1,10 @@ +package cstore + +import ( + "testing" +) + +func TestRedis_StoreSuite(t *testing.T) { + store, _ := NewRedisStoreBackend("") + testBackendStore(t, store) +} diff --git a/suave/backends/redis_transport.go b/suave/cstore/redis_transport.go similarity index 94% rename from suave/backends/redis_transport.go rename to suave/cstore/redis_transport.go index 542fe2335..f63136541 100644 --- a/suave/backends/redis_transport.go +++ b/suave/cstore/redis_transport.go @@ -1,4 +1,4 @@ -package backends +package cstore import ( "context" @@ -12,7 +12,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" - suave "github.com/ethereum/go-ethereum/suave/core" ) var ( @@ -67,8 +66,8 @@ func (r *RedisPubSubTransport) Stop() error { return nil } -func (r *RedisPubSubTransport) Subscribe() (<-chan suave.DAMessage, context.CancelFunc) { - ch := make(chan suave.DAMessage, 16) +func (r *RedisPubSubTransport) Subscribe() (<-chan DAMessage, context.CancelFunc) { + ch := make(chan DAMessage, 16) ctx, cancel := context.WithCancel(r.ctx) // Each subscriber has its own PubSub as it blocks on receive! @@ -92,7 +91,7 @@ func (r *RedisPubSubTransport) Subscribe() (<-chan suave.DAMessage, context.Canc continue } - var msg suave.DAMessage + var msg DAMessage msgBytes := common.Hex2Bytes(rmsg.Payload) if err != nil { log.Trace("Redis pubsub: could not decode message from subscription", "err", err, "msg", rmsg.Payload) @@ -137,7 +136,7 @@ func (r *RedisPubSubTransport) Subscribe() (<-chan suave.DAMessage, context.Canc return ch, cancel } -func (r *RedisPubSubTransport) Publish(message suave.DAMessage) { +func (r *RedisPubSubTransport) Publish(message DAMessage) { log.Trace("Redis pubsub: publishing", "message", message) data, err := json.Marshal(message) if err != nil { diff --git a/suave/core/transactional_store.go b/suave/cstore/transactional_store.go similarity index 78% rename from suave/core/transactional_store.go rename to suave/cstore/transactional_store.go index 1709c77f3..e4c68f40b 100644 --- a/suave/core/transactional_store.go +++ b/suave/cstore/transactional_store.go @@ -1,4 +1,4 @@ -package suave +package cstore import ( "errors" @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + suave "github.com/ethereum/go-ethereum/suave/core" "golang.org/x/exp/slices" ) @@ -15,11 +16,11 @@ type TransactionalStore struct { engine *ConfidentialStoreEngine pendingLock sync.Mutex - pendingBids map[BidId]Bid + pendingBids map[suave.BidId]suave.Bid pendingWrites []StoreWrite } -func (s *TransactionalStore) FetchBidById(bidId BidId) (Bid, error) { +func (s *TransactionalStore) FetchBidById(bidId suave.BidId) (suave.Bid, error) { s.pendingLock.Lock() bid, ok := s.pendingBids[bidId] s.pendingLock.Unlock() @@ -31,7 +32,7 @@ func (s *TransactionalStore) FetchBidById(bidId BidId) (Bid, error) { return s.engine.FetchBidById(bidId) } -func (s *TransactionalStore) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []Bid { +func (s *TransactionalStore) FetchBidsByProtocolAndBlock(blockNumber uint64, namespace string) []suave.Bid { bids := s.engine.FetchBidsByProtocolAndBlock(blockNumber, namespace) s.pendingLock.Lock() @@ -45,14 +46,14 @@ func (s *TransactionalStore) FetchBidsByProtocolAndBlock(blockNumber uint64, nam return bids } -func (s *TransactionalStore) Store(bidId BidId, caller common.Address, key string, value []byte) (Bid, error) { +func (s *TransactionalStore) Store(bidId suave.BidId, caller common.Address, key string, value []byte) (suave.Bid, error) { bid, err := s.FetchBidById(bidId) if err != nil { - return Bid{}, err + return suave.Bid{}, err } if !slices.Contains(bid.AllowedPeekers, caller) { - return Bid{}, fmt.Errorf("confidential store transaction: %x not allowed to store %s on %x", caller, key, bidId) + return suave.Bid{}, fmt.Errorf("confidential store transaction: %x not allowed to store %s on %x", caller, key, bidId) } s.pendingLock.Lock() @@ -67,7 +68,7 @@ func (s *TransactionalStore) Store(bidId BidId, caller common.Address, key strin return bid, nil } -func (s *TransactionalStore) Retrieve(bidId BidId, caller common.Address, key string) ([]byte, error) { +func (s *TransactionalStore) Retrieve(bidId suave.BidId, caller common.Address, key string) ([]byte, error) { bid, err := s.FetchBidById(bidId) if err != nil { return nil, err diff --git a/suave/backends/transactional_store_test.go b/suave/cstore/transactional_store_test.go similarity index 93% rename from suave/backends/transactional_store_test.go rename to suave/cstore/transactional_store_test.go index 251b5d90a..f86b3380b 100644 --- a/suave/backends/transactional_store_test.go +++ b/suave/cstore/transactional_store_test.go @@ -1,4 +1,4 @@ -package backends +package cstore import ( "math/big" @@ -12,7 +12,7 @@ import ( ) func TestTransactionalStore(t *testing.T) { - engine := suave.NewConfidentialStoreEngine(NewLocalConfidentialStore(), suave.MockTransport{}, suave.MockSigner{}, suave.MockChainSigner{}) + engine := NewConfidentialStoreEngine(NewLocalConfidentialStore(), MockTransport{}, MockSigner{}, MockChainSigner{}) testKey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") dummyCreationTx, err := types.SignTx(types.NewTx(&types.ConfidentialComputeRequest{ @@ -25,7 +25,7 @@ func TestTransactionalStore(t *testing.T) { tstore := engine.NewTransactionalStore(dummyCreationTx) testBid, err := tstore.InitializeBid(types.Bid{ - Salt: suave.RandomBidId(), + Salt: RandomBidId(), DecryptionCondition: 46, AllowedStores: []common.Address{{0x42}}, AllowedPeekers: []common.Address{{0x43}}, diff --git a/suave/e2e/workflow_test.go b/suave/e2e/workflow_test.go index bc6c6015a..ed8b32ec9 100644 --- a/suave/e2e/workflow_test.go +++ b/suave/e2e/workflow_test.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" suave "github.com/ethereum/go-ethereum/suave/core" + "github.com/ethereum/go-ethereum/suave/cstore" "github.com/ethereum/go-ethereum/suave/sdk" "github.com/flashbots/go-boost-utils/ssz" "github.com/mitchellh/mapstructure" @@ -522,7 +523,7 @@ func TestBlockBuildingPrecompiles(t *testing.T) { }, dummyCreationTx) require.NoError(t, err) - err = fr.ConfidentialEngine().Finalize(dummyCreationTx, map[suave.BidId]suave.Bid{bid.Id: bid}, []suave.StoreWrite{{ + err = fr.ConfidentialEngine().Finalize(dummyCreationTx, map[suave.BidId]suave.Bid{bid.Id: bid}, []cstore.StoreWrite{{ Bid: bid, Caller: common.Address{0x41, 0x42, 0x43}, @@ -876,11 +877,11 @@ func (f *framework) NewSDKClient() *sdk.Client { return sdk.NewClient(f.suethSrv.RPCNode(), testKey, f.ExecutionNode()) } -func (f *framework) ConfidentialStoreBackend() suave.ConfidentialStoreBackend { +func (f *framework) ConfidentialStoreBackend() cstore.ConfidentialStorageBackend { return f.suethSrv.service.APIBackend.SuaveEngine().Backend() } -func (f *framework) ConfidentialEngine() *suave.ConfidentialStoreEngine { +func (f *framework) ConfidentialEngine() *cstore.ConfidentialStoreEngine { return f.suethSrv.service.APIBackend.SuaveEngine() }