diff --git a/docs/fabric/fabricdev/core/fabricdev/channelprovider.go b/docs/fabric/fabricdev/core/fabricdev/channelprovider.go index 577d12e25..1e89e261f 100644 --- a/docs/fabric/fabricdev/core/fabricdev/channelprovider.go +++ b/docs/fabric/fabricdev/core/fabricdev/channelprovider.go @@ -23,7 +23,6 @@ import ( driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/events" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/metrics" "github.com/hyperledger/fabric-protos-go/common" "github.com/pkg/errors" @@ -31,7 +30,9 @@ import ( ) type provider struct { - kvss *kvs.KVS + envelopeKVS driver.EnvelopeKVS + metadataKVS driver.MetadataKVS + endorseTxKVS driver.EndorseTxKVS publisher events.Publisher hasher hash.Hasher newVault generic.VaultConstructor @@ -45,7 +46,9 @@ type provider struct { } func NewChannelProvider( - kvss *kvs.KVS, + envelopeKVS driver.EnvelopeKVS, + metadataKVS driver.MetadataKVS, + endorseTxKVS driver.EndorseTxKVS, publisher events.Publisher, hasher hash.Hasher, tracerProvider trace.TracerProvider, @@ -58,7 +61,9 @@ func NewChannelProvider( acceptedHeaderTypes []common.HeaderType, ) *provider { return &provider{ - kvss: kvss, + envelopeKVS: envelopeKVS, + metadataKVS: metadataKVS, + endorseTxKVS: endorseTxKVS, publisher: publisher, hasher: hasher, newVault: newVault, @@ -90,9 +95,9 @@ func (p *provider) NewChannel(nw driver.FabricNetworkService, channelName string return nil, err } - envelopeService := transaction.NewEnvelopeService(p.kvss, nw.Name(), channelName) - transactionService := transaction.NewEndorseTransactionService(p.kvss, nw.Name(), channelName) - metadataService := transaction.NewMetadataService(p.kvss, nw.Name(), channelName) + envelopeService := transaction.NewEnvelopeService(p.envelopeKVS, nw.Name(), channelName) + transactionService := transaction.NewEndorseTransactionService(p.endorseTxKVS, nw.Name(), channelName) + metadataService := transaction.NewMetadataService(p.metadataKVS, nw.Name(), channelName) peerService := services.NewClientFactory(nw.ConfigService(), nw.LocalMembership().DefaultSigningIdentity()) // Fabric finality diff --git a/docs/fabric/fabricdev/core/fabricdev/driver/provider.go b/docs/fabric/fabricdev/core/fabricdev/driver/provider.go index 0b29b9a23..09aea1684 100644 --- a/docs/fabric/fabricdev/core/fabricdev/driver/provider.go +++ b/docs/fabric/fabricdev/core/fabricdev/driver/provider.go @@ -50,6 +50,9 @@ type Provider struct { } func NewProvider( + envelopeKVS fdriver.EnvelopeKVS, + metadataKVS fdriver.MetadataKVS, + endorseTxKVS fdriver.EndorseTxKVS, configProvider config.Provider, metricsProvider metrics.Provider, endpointService identity.EndpointService, @@ -65,7 +68,9 @@ func NewProvider( return &Provider{ configProvider: configProvider, channelProvider: fabricdev.NewChannelProvider( - kvss, + envelopeKVS, + metadataKVS, + endorseTxKVS, publisher, hasher, tracerProvider, diff --git a/docs/fabric/fabricdev/sdk/fabricdev/providers.go b/docs/fabric/fabricdev/sdk/fabricdev/providers.go index 6b3b37203..a29707f2d 100644 --- a/docs/fabric/fabricdev/sdk/fabricdev/providers.go +++ b/docs/fabric/fabricdev/sdk/fabricdev/providers.go @@ -12,6 +12,7 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/driver/config" mspdriver "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/msp/driver" + "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/driver" vdriver "github.com/hyperledger-labs/fabric-smart-client/platform/view/driver" dbdriver "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/events" @@ -24,6 +25,10 @@ import ( func NewDriver(in struct { dig.In + + EnvelopeKVS driver.EnvelopeKVS + MetadataKVS driver.MetadataKVS + EndorseTxKVS driver.EndorseTxKVS ConfigProvider config.Provider MetricsProvider metrics.Provider EndpointService vdriver.EndpointService @@ -39,6 +44,9 @@ func NewDriver(in struct { d := core.NamedDriver{ Name: "fabricdev", Driver: fdevdriver.NewProvider( + in.EnvelopeKVS, + in.MetadataKVS, + in.EndorseTxKVS, in.ConfigProvider, in.MetricsProvider, in.EndpointService, diff --git a/platform/common/driver/kvs.go b/platform/common/driver/kvs.go new file mode 100644 index 000000000..0c1c92c2f --- /dev/null +++ b/platform/common/driver/kvs.go @@ -0,0 +1,50 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package driver + +import ( + "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" +) + +type SignerEntry struct { + Signer Signer + DebugStack []byte +} + +type SignerKVS interface { + GetSigner(id view.Identity) (*SignerEntry, error) + FilterExistingSigners(ids ...view.Identity) ([]view.Identity, error) + PutSigner(id view.Identity, entry *SignerEntry) error +} + +type AuditInfoKVS interface { + GetAuditInfo(id view.Identity) ([]byte, error) + PutAuditInfo(id view.Identity, info []byte) error +} + +type BindingKVS interface { + GetBinding(ephemeral view.Identity) (view.Identity, error) + PutBinding(ephemeral, longTerm view.Identity) error +} + +type MetadataKVS[K any, M any] interface { + GetMetadata(key K) (M, error) + ExistMetadata(key K) (bool, error) + PutMetadata(key K, transientMap M) error +} + +type EnvelopeKVS[K any] interface { + GetEnvelope(key K) ([]byte, error) + ExistsEnvelope(key K) (bool, error) + PutEnvelope(key K, env []byte) error +} + +type EndorseTxKVS[K any] interface { + GetEndorseTx(key K) ([]byte, error) + ExistsEndorseTx(key K) (bool, error) + PutEndorseTx(key K, etx []byte) error +} diff --git a/platform/common/services/sig/service.go b/platform/common/services/sig/service.go index d6bce3731..46e35104e 100644 --- a/platform/common/services/sig/service.go +++ b/platform/common/services/sig/service.go @@ -12,10 +12,10 @@ import ( "runtime/debug" "sync" + driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging" "github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/collections" "github.com/hyperledger-labs/fabric-smart-client/platform/view/driver" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" "github.com/pkg/errors" "go.uber.org/zap/zapcore" @@ -23,38 +23,30 @@ import ( var logger = logging.MustGetLogger("common-sdk.sig") -type KVS interface { - Exists(id string) bool - GetExisting(ids ...string) []string - Put(id string, state interface{}) error - Get(id string, state interface{}) error -} - type VerifierEntry struct { Verifier driver.Verifier DebugStack []byte } -type SignerEntry struct { - Signer driver.Signer - DebugStack []byte -} +type SignerEntry = driver2.SignerEntry type Service struct { deserializer Deserializer - kvs KVS + signerKVS driver2.SignerKVS + auditInfoKVS driver2.AuditInfoKVS mutex sync.RWMutex signers map[string]SignerEntry verifiers map[string]VerifierEntry } -func NewService(deserializer Deserializer, kvs KVS) *Service { +func NewService(deserializer Deserializer, auditInfoKVS driver2.AuditInfoKVS, signerKVS driver2.SignerKVS) *Service { return &Service{ + signerKVS: signerKVS, + auditInfoKVS: auditInfoKVS, signers: map[string]SignerEntry{}, verifiers: map[string]VerifierEntry{}, deserializer: deserializer, - kvs: kvs, } } @@ -91,8 +83,8 @@ func (o *Service) RegisterSigner(identity view.Identity, signer driver.Signer, v o.signers[idHash] = entry o.mutex.Unlock() - if o.kvs != nil { - if err := o.registerSigner(idHash, &entry); err != nil { + if o.signerKVS != nil { + if err := o.signerKVS.PutSigner(identity, &entry); err != nil { o.deleteSigner(idHash) return errors.Wrap(err, "failed to store entry in kvs for the passed signer") } @@ -151,34 +143,11 @@ func (o *Service) RegisterVerifier(identity view.Identity, verifier driver.Verif } func (o *Service) RegisterAuditInfo(identity view.Identity, info []byte) error { - k := kvs.CreateCompositeKeyOrPanic( - "fsc.platform.view.sig", - []string{ - identity.String(), - }, - ) - if err := o.kvs.Put(k, info); err != nil { - return err - } - return nil + return o.auditInfoKVS.PutAuditInfo(identity, info) } func (o *Service) GetAuditInfo(identity view.Identity) ([]byte, error) { - k := kvs.CreateCompositeKeyOrPanic( - "fsc.platform.view.sig", - []string{ - identity.String(), - }, - ) - - if !o.kvs.Exists(k) { - return nil, nil - } - var res []byte - if err := o.kvs.Get(k, &res); err != nil { - return nil, err - } - return res, nil + return o.auditInfoKVS.GetAuditInfo(identity) } func (o *Service) IsMe(identity view.Identity) bool { @@ -186,37 +155,31 @@ func (o *Service) IsMe(identity view.Identity) bool { } func (o *Service) AreMe(identities ...view.Identity) []string { - idHashes := make([]string, len(identities)) - for i, id := range identities { - idHashes[i] = id.UniqueID() - } result := collections.NewSet[string]() - notFound := make([]string, 0) + notFound := make([]view.Identity, 0) // check local cache o.mutex.RLock() - for _, idHash := range idHashes { - if _, ok := o.signers[idHash]; ok { - result.Add(idHash) + for _, id := range identities { + if _, ok := o.signers[id.UniqueID()]; ok { + result.Add(id.UniqueID()) } else { - notFound = append(notFound, idHash) + notFound = append(notFound, id) } } o.mutex.RUnlock() - if len(notFound) == 0 || o.kvs == nil { + if len(notFound) == 0 || o.signerKVS == nil { return result.ToSlice() } // check kvs - keys := make([]string, len(notFound)) - for i, idHash := range notFound { - key, err := kvs.CreateCompositeKey("sigService", []string{"signer", idHash}) - if err != nil { - logger.Errorf("failed creating composite key: %v", err) + + if existing, err := o.signerKVS.FilterExistingSigners(notFound...); err != nil { + logger.Errorf("failed getting existing signers: %v", err) + } else { + for _, id := range existing { + result.Add(id.UniqueID()) } - keys[i] = key } - result.Add(o.kvs.GetExisting(keys...)...) - return result.ToSlice() } @@ -341,18 +304,6 @@ func (o *Service) GetSigningIdentity(identity view.Identity) (driver.SigningIden }, nil } -func (o *Service) registerSigner(id string, signer *SignerEntry) error { - k, err := kvs.CreateCompositeKey("sigService", []string{"signer", id}) - if err != nil { - return errors.Wrap(err, "failed to create composite key to store entry in kvs") - } - err = o.kvs.Put(k, signer) - if err != nil { - return errors.Wrap(err, "failed to store entry in kvs for the passed signer") - } - return nil -} - func (o *Service) deleteSigner(id string) { o.mutex.Lock() defer o.mutex.Unlock() diff --git a/platform/fabric/core/generic/channelprovider.go b/platform/fabric/core/generic/channelprovider.go index 294ad3cc8..35f6f48be 100644 --- a/platform/fabric/core/generic/channelprovider.go +++ b/platform/fabric/core/generic/channelprovider.go @@ -21,7 +21,6 @@ import ( driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/events" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/metrics" "github.com/hyperledger/fabric-protos-go/common" "github.com/pkg/errors" @@ -69,7 +68,9 @@ type ChannelProvider interface { } type provider struct { - kvss *kvs.KVS + envelopeKVS driver.EnvelopeKVS + metadataKVS driver.MetadataKVS + endorserTxKVS driver.EndorseTxKVS publisher events.Publisher hasher hash.Hasher newVault VaultConstructor @@ -87,7 +88,9 @@ type provider struct { } func NewChannelProvider( - kvss *kvs.KVS, + envelopeKVS driver.EnvelopeKVS, + metadataKVS driver.MetadataKVS, + endorserTxKVS driver.EndorseTxKVS, publisher events.Publisher, hasher hash.Hasher, tracerProvider trace.TracerProvider, @@ -104,7 +107,9 @@ func NewChannelProvider( acceptedHeaderTypes []common.HeaderType, ) *provider { return &provider{ - kvss: kvss, + envelopeKVS: envelopeKVS, + metadataKVS: metadataKVS, + endorserTxKVS: endorserTxKVS, publisher: publisher, hasher: hasher, newVault: newVault, @@ -141,9 +146,9 @@ func (p *provider) NewChannel(nw driver.FabricNetworkService, channelName string return nil, err } - envelopeService := transaction.NewEnvelopeService(p.kvss, nw.Name(), channelName) - transactionService := transaction.NewEndorseTransactionService(p.kvss, nw.Name(), channelName) - metadataService := transaction.NewMetadataService(p.kvss, nw.Name(), channelName) + envelopeService := transaction.NewEnvelopeService(p.envelopeKVS, nw.Name(), channelName) + transactionService := transaction.NewEndorseTransactionService(p.endorserTxKVS, nw.Name(), channelName) + metadataService := transaction.NewMetadataService(p.metadataKVS, nw.Name(), channelName) peerService := services.NewClientFactory(nw.ConfigService(), nw.LocalMembership().DefaultSigningIdentity()) // Fabric finality diff --git a/platform/fabric/core/generic/driver/provider.go b/platform/fabric/core/generic/driver/provider.go index d566520f2..9aa77b999 100644 --- a/platform/fabric/core/generic/driver/provider.go +++ b/platform/fabric/core/generic/driver/provider.go @@ -9,6 +9,7 @@ package driver import ( "fmt" + "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging" "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/sig" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic" @@ -39,10 +40,12 @@ func NewProvider( channelProvider generic.ChannelProvider, idProvider vdriver.IdentityProvider, identityLoaders []identity.NamedIdentityLoader, + signerKVS driver.SignerKVS, + auditInfoKVS driver.AuditInfoKVS, kvss *kvs.KVS, ) *Provider { deserializerManager := sig.NewMultiplexDeserializer() - sigService := sig.NewService(deserializerManager, kvss) + sigService := sig.NewService(deserializerManager, auditInfoKVS, signerKVS) return &Provider{ configProvider: configProvider, channelProvider: channelProvider, diff --git a/platform/fabric/core/generic/id/info_test.go b/platform/fabric/core/generic/id/info_test.go index 5acee967a..1e21aeda2 100644 --- a/platform/fabric/core/generic/id/info_test.go +++ b/platform/fabric/core/generic/id/info_test.go @@ -27,7 +27,7 @@ func TestInfoIdemix(t *testing.T) { kvss, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) assert.NoError(t, err) assert.NoError(t, registry.RegisterService(kvss)) - sigService := sig.NewService(sig.NewMultiplexDeserializer(), kvss) + sigService := sig.NewService(sig.NewMultiplexDeserializer(), kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) config, err := msp2.GetLocalMspConfigWithType("./testdata/idemix", nil, "idemix", "idemix") diff --git a/platform/fabric/core/generic/msp/idemix/provider_test.go b/platform/fabric/core/generic/msp/idemix/provider_test.go index 967917c31..083deb0d7 100644 --- a/platform/fabric/core/generic/msp/idemix/provider_test.go +++ b/platform/fabric/core/generic/msp/idemix/provider_test.go @@ -29,7 +29,7 @@ func TestProvider(t *testing.T) { kvss, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) assert.NoError(t, err) assert.NoError(t, registry.RegisterService(kvss)) - sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvss) + sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) config, err := msp2.GetLocalMspConfigWithType("./testdata/idemix", nil, "idemix", "idemix") @@ -54,7 +54,7 @@ func TestIdentityWithEidRhNymPolicy(t *testing.T) { kvss, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) assert.NoError(t, err) assert.NoError(t, registry.RegisterService(kvss)) - sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvss) + sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) config, err := msp2.GetLocalMspConfigWithType("./testdata/idemix", nil, "idemix", "idemix") @@ -119,7 +119,7 @@ func TestIdentityStandard(t *testing.T) { kvss, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) assert.NoError(t, err) assert.NoError(t, registry.RegisterService(kvss)) - sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvss) + sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) config, err := msp2.GetLocalMspConfigWithType("./testdata/idemix", nil, "idemix", "idemix") @@ -186,7 +186,7 @@ func TestAuditWithEidRhNymPolicy(t *testing.T) { kvss, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) assert.NoError(t, err) assert.NoError(t, registry.RegisterService(kvss)) - sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvss) + sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) config, err := msp2.GetLocalMspConfigWithType("./testdata/idemix", nil, "idemix", "idemix") @@ -228,7 +228,7 @@ func TestProvider_DeserializeSigner(t *testing.T) { kvss, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) assert.NoError(t, err) assert.NoError(t, registry.RegisterService(kvss)) - sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvss) + sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) config, err := msp2.GetLocalMspConfigWithType("./testdata/sameissuer/idemix", nil, "idemix", "idemix") @@ -284,7 +284,7 @@ func TestIdentityFromFabricCA(t *testing.T) { kvss, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) assert.NoError(t, err) assert.NoError(t, registry.RegisterService(kvss)) - sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvss) + sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) config, err := idemix2.GetLocalMspConfigWithType("./testdata/charlie.ExtraId2", "charlie.ExtraId2") @@ -351,7 +351,7 @@ func TestIdentityFromFabricCAWithEidRhNymPolicy(t *testing.T) { kvss, err := kvs.NewWithConfig(&mem.Driver{}, "", &mock.ConfigProvider{}) assert.NoError(t, err) assert.NoError(t, registry.RegisterService(kvss)) - sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvss) + sigService := sig2.NewService(sig2.NewMultiplexDeserializer(), kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) config, err := idemix2.GetLocalMspConfigWithType("./testdata/charlie.ExtraId2", "charlie.ExtraId2") diff --git a/platform/fabric/core/generic/msp/service_test.go b/platform/fabric/core/generic/msp/service_test.go index 77cdf32ea..b29f396d0 100644 --- a/platform/fabric/core/generic/msp/service_test.go +++ b/platform/fabric/core/generic/msp/service_test.go @@ -41,7 +41,7 @@ func TestRegisterIdemixLocalMSP(t *testing.T) { assert.NoError(t, err) mspService := msp2.NewLocalMSPManager(config, kvss, nil, nil, nil, des, 100) assert.NoError(t, registry.RegisterService(mspService)) - sigService := sig.NewService(des, kvss) + sigService := sig.NewService(des, kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) assert.NoError(t, mspService.RegisterIdemixMSP("apple", "./idemix/testdata/idemix", "idemix")) @@ -73,7 +73,7 @@ func TestIdemixTypeFolder(t *testing.T) { assert.NoError(t, err) mspService := msp2.NewLocalMSPManager(config, kvss, nil, nil, nil, des, 100) assert.NoError(t, registry.RegisterService(mspService)) - sigService := sig.NewService(des, kvss) + sigService := sig.NewService(des, kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) assert.NoError(t, mspService.Load()) @@ -101,7 +101,7 @@ func TestRegisterX509LocalMSP(t *testing.T) { assert.NoError(t, err) mspService := msp2.NewLocalMSPManager(config, kvss, nil, nil, nil, des, 100) assert.NoError(t, registry.RegisterService(mspService)) - sigService := sig.NewService(des, kvss) + sigService := sig.NewService(des, kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) assert.NoError(t, mspService.RegisterX509MSP("apple", "./x509/testdata/msp", "x509")) @@ -132,7 +132,7 @@ func TestX509TypeFolder(t *testing.T) { assert.NoError(t, err) mspService := msp2.NewLocalMSPManager(config, kvss, nil, nil, nil, des, 100) assert.NoError(t, registry.RegisterService(mspService)) - sigService := sig.NewService(des, kvss) + sigService := sig.NewService(des, kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) assert.NoError(t, mspService.Load()) @@ -160,7 +160,7 @@ func TestRefresh(t *testing.T) { assert.NoError(t, err) mspService := msp2.NewLocalMSPManager(config, kvss, nil, nil, nil, des, 100) assert.NoError(t, registry.RegisterService(mspService)) - sigService := sig.NewService(des, kvss) + sigService := sig.NewService(des, kvs.NewAuditInfoKVS(kvss), kvs.NewSignerKVS(kvss)) assert.NoError(t, registry.RegisterService(sigService)) assert.NoError(t, mspService.Load()) diff --git a/platform/fabric/core/generic/transaction/services.go b/platform/fabric/core/generic/transaction/services.go index 3dc756856..ad0731cdb 100644 --- a/platform/fabric/core/generic/transaction/services.go +++ b/platform/fabric/core/generic/transaction/services.go @@ -8,172 +8,94 @@ package transaction import ( "github.com/hyperledger-labs/fabric-smart-client/pkg/utils/proto" + driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/driver" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/hyperledger/fabric-protos-go/common" "github.com/pkg/errors" - "go.uber.org/zap/zapcore" ) var logger = logging.MustGetLogger("fabric-sdk.core") -type KVS interface { - Exists(id string) bool - Put(id string, state interface{}) error - Get(id string, state interface{}) error -} - type mds struct { - KVS KVS - network string - channel string + metadataKVS driver.MetadataKVS + key func(driver2.TxID) driver.Key } -func NewMetadataService(KVS KVS, network string, channel string) *mds { - return &mds{ - KVS: KVS, - network: network, - channel: channel, - } +func NewMetadataService(metadataKVS driver.MetadataKVS, network string, channel string) *mds { + return &mds{metadataKVS: metadataKVS, key: keyMapper(network, channel)} } func (s *mds) Exists(txid string) bool { - key, err := kvs.CreateCompositeKey("metadata", []string{s.channel, s.network, txid}) - if err != nil { - return false - } - return s.KVS.Exists(key) + ok, _ := s.metadataKVS.ExistMetadata(s.key(txid)) + return ok } func (s *mds) StoreTransient(txid string, transientMap driver.TransientMap) error { - key, err := kvs.CreateCompositeKey("metadata", []string{s.channel, s.network, txid}) - if err != nil { - return err - } - if logger.IsEnabledFor(zapcore.DebugLevel) { - logger.Debugf("store transient for [%s][%v]", txid, transientMap) - } - return s.KVS.Put(key, transientMap) + return s.metadataKVS.PutMetadata(s.key(txid), transientMap) } func (s *mds) LoadTransient(txid string) (driver.TransientMap, error) { - logger.Debugf("load transient for [%s]", txid) - - key, err := kvs.CreateCompositeKey("metadata", []string{s.channel, s.network, txid}) - if err != nil { - return nil, err - } - transientMap := driver.TransientMap{} - err = s.KVS.Get(key, &transientMap) - if err != nil { - return nil, err - } - return transientMap, nil + return s.metadataKVS.GetMetadata(s.key(txid)) } type envs struct { - KVS KVS - network string - channel string + envelopeKVS driver.EnvelopeKVS + key func(driver2.TxID) driver.Key } -func NewEnvelopeService(KVS KVS, network string, channel string) *envs { - return &envs{ - KVS: KVS, - network: network, - channel: channel, - } +func NewEnvelopeService(envelopeKVS driver.EnvelopeKVS, network string, channel string) *envs { + return &envs{envelopeKVS: envelopeKVS, key: keyMapper(network, channel)} } func (s *envs) Exists(txid string) bool { - key, err := kvs.CreateCompositeKey("envelope", []string{s.channel, s.network, txid}) - if err != nil { - return false - } - - return s.KVS.Exists(key) + ok, _ := s.envelopeKVS.ExistsEnvelope(s.key(txid)) + return ok } func (s *envs) StoreEnvelope(txID string, env interface{}) error { - key, err := kvs.CreateCompositeKey("envelope", []string{s.channel, s.network, txID}) - if err != nil { - return err - } - logger.Debugf("store env for [%s]", txID) - switch e := env.(type) { case []byte: - return s.KVS.Put(key, e) + return s.envelopeKVS.PutEnvelope(s.key(txID), e) case *common.Envelope: envBytes, err := proto.Marshal(e) if err != nil { return errors.WithMessagef(err, "failed marshalling envelop for tx [%s]", txID) } - return s.KVS.Put(key, envBytes) + return s.envelopeKVS.PutEnvelope(s.key(txID), envBytes) default: return errors.Errorf("invalid env, expected []byte or *common.Envelope, got [%T]", env) } } func (s *envs) LoadEnvelope(txid string) ([]byte, error) { - logger.Debugf("load env for [%s]", txid) - - key, err := kvs.CreateCompositeKey("envelope", []string{s.channel, s.network, txid}) - if err != nil { - return nil, err - } - env := []byte{} - err = s.KVS.Get(key, &env) - if err != nil { - return nil, err - } - return env, nil + return s.envelopeKVS.GetEnvelope(s.key(txid)) } type ets struct { - KVS KVS - network string - channel string + endorseTxKVS driver.EndorseTxKVS + key func(driver2.TxID) driver.Key } -func NewEndorseTransactionService(KVS KVS, network string, channel string) *ets { - return &ets{ - KVS: KVS, - network: network, - channel: channel, - } +func NewEndorseTransactionService(endorseTxKVS driver.EndorseTxKVS, network string, channel string) *ets { + return &ets{endorseTxKVS: endorseTxKVS, key: keyMapper(network, channel)} } func (s *ets) Exists(txid string) bool { - key, err := kvs.CreateCompositeKey("etx", []string{s.channel, s.network, txid}) - if err != nil { - return false - } - return s.KVS.Exists(key) + ok, _ := s.endorseTxKVS.ExistsEndorseTx(s.key(txid)) + return ok } func (s *ets) StoreTransaction(txid string, env []byte) error { - key, err := kvs.CreateCompositeKey("etx", []string{s.channel, s.network, txid}) - if err != nil { - return err - } - logger.Debugf("store etx for [%s]", txid) - - return s.KVS.Put(key, env) + return s.endorseTxKVS.PutEndorseTx(s.key(txid), env) } func (s *ets) LoadTransaction(txid string) ([]byte, error) { - logger.Debugf("load etx for [%s]", txid) + return s.endorseTxKVS.GetEndorseTx(s.key(txid)) +} - key, err := kvs.CreateCompositeKey("etx", []string{s.channel, s.network, txid}) - if err != nil { - return nil, err - } - env := []byte{} - err = s.KVS.Get(key, &env) - if err != nil { - return nil, err +func keyMapper(network, channel string) func(txID driver2.TxID) driver.Key { + return func(txID driver2.TxID) driver.Key { + return driver.Key{Network: network, Channel: channel, TxID: txID} } - return env, nil } diff --git a/platform/fabric/driver/kvs.go b/platform/fabric/driver/kvs.go new file mode 100644 index 000000000..2a17de750 --- /dev/null +++ b/platform/fabric/driver/kvs.go @@ -0,0 +1,27 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package driver + +import "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" + +type Key struct { + Network string + Channel string + TxID driver.TxID +} + +type MetadataKVS interface { + driver.MetadataKVS[Key, TransientMap] +} + +type EnvelopeKVS interface { + driver.EnvelopeKVS[Key] +} + +type EndorseTxKVS interface { + driver.EndorseTxKVS[Key] +} diff --git a/platform/fabric/sdk/dig/generic/providers.go b/platform/fabric/sdk/dig/generic/providers.go index 652637bc2..1419ee198 100644 --- a/platform/fabric/sdk/dig/generic/providers.go +++ b/platform/fabric/sdk/dig/generic/providers.go @@ -9,6 +9,7 @@ package generic import ( "github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors" committer2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/core/generic/committer" + driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" digutils "github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/dig" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic" @@ -54,6 +55,8 @@ func NewDriver(in struct { EndpointService vdriver.EndpointService IdProvider vdriver.IdentityProvider KVS *kvs.KVS + AuditInfoKVS driver2.AuditInfoKVS + SignerKVS driver2.SignerKVS ChannelProvider generic.ChannelProvider `name:"generic-channel-provider"` IdentityLoaders []identity.NamedIdentityLoader `group:"identity-loaders"` }) core.NamedDriver { @@ -66,6 +69,8 @@ func NewDriver(in struct { in.ChannelProvider, in.IdProvider, in.IdentityLoaders, + in.SignerKVS, + in.AuditInfoKVS, in.KVS, ), } @@ -75,7 +80,9 @@ func NewDriver(in struct { func NewChannelProvider(in struct { dig.In ConfigProvider config.Provider - KVS *kvs.KVS + EnvelopeKVS driver.EnvelopeKVS + MetadataKVS driver.MetadataKVS + EndorseTxKVS driver.EndorseTxKVS Publisher events.Publisher Hasher hash.Hasher TracerProvider trace.TracerProvider @@ -83,7 +90,9 @@ func NewChannelProvider(in struct { MetricsProvider metrics.Provider }) generic.ChannelProvider { return generic.NewChannelProvider( - in.KVS, + in.EnvelopeKVS, + in.MetadataKVS, + in.EndorseTxKVS, in.Publisher, in.Hasher, in.TracerProvider, diff --git a/platform/fabric/sdk/dig/sdk.go b/platform/fabric/sdk/dig/sdk.go index 7f4f32933..c16bb2a15 100644 --- a/platform/fabric/sdk/dig/sdk.go +++ b/platform/fabric/sdk/dig/sdk.go @@ -26,6 +26,7 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/sdk/dig/fns" generic2 "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/sdk/dig/generic" finality2 "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/sdk/finality" + "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/services/state" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/services/state/vault" "github.com/hyperledger-labs/fabric-smart-client/platform/view/core/endpoint" @@ -71,6 +72,9 @@ func (p *SDK) Install() error { p.Container().Provide(vault.NewService, dig.As(new(state.VaultService))), p.Container().Provide(generic2.NewEndorserTransactionHandlerProvider), p.Container().Provide(committer2.NewSerialDependencyResolver, dig.As(new(committer2.DependencyResolver))), + p.Container().Provide(kvs.NewMetadataKVS, dig.As(new(driver.MetadataKVS))), + p.Container().Provide(kvs.NewEnvelopeKVS, dig.As(new(driver.EnvelopeKVS))), + p.Container().Provide(kvs.NewEndorseTxKVS, dig.As(new(driver.EndorseTxKVS))), ) if err != nil { return err diff --git a/platform/fabric/services/kvs/kvs.go b/platform/fabric/services/kvs/kvs.go new file mode 100644 index 000000000..b57c15add --- /dev/null +++ b/platform/fabric/services/kvs/kvs.go @@ -0,0 +1,29 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package kvs + +import ( + "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/driver" + "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" +) + +func NewMetadataKVS(kvss *kvs.KVS) driver.MetadataKVS { + return kvs.NewMetadataKVS[driver.Key, driver.TransientMap](kvss, keyMapper("metadata")) +} + +func NewEnvelopeKVS(kvss *kvs.KVS) driver.EnvelopeKVS { + return kvs.NewEnvelopeKVS(kvss, keyMapper("envelope")) +} + +func NewEndorseTxKVS(kvss *kvs.KVS) driver.EndorseTxKVS { + return kvs.NewEndorseTxKVS[driver.Key](kvss, keyMapper("etx")) +} +func keyMapper(prefix string) kvs.KeyMapper[driver.Key] { + return func(k driver.Key) (string, error) { + return kvs.CreateCompositeKey(prefix, []string{k.Channel, k.Network, k.TxID}) + } +} diff --git a/platform/orion/core/generic/network.go b/platform/orion/core/generic/network.go index e58e0924d..2ebb46648 100644 --- a/platform/orion/core/generic/network.go +++ b/platform/orion/core/generic/network.go @@ -21,7 +21,6 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db" driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/events" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/metrics" "github.com/hyperledger-labs/orion-server/pkg/types" "github.com/pkg/errors" @@ -52,7 +51,14 @@ type network struct { deliveryService driver.DeliveryService } -func NewDB(ctx context.Context, kvss *kvs.KVS, config *config2.Config, name string) (*network, error) { +func NewDB( + ctx context.Context, + endorseTxKVS driver.EndorseTxKVS, + metadataKVS driver.MetadataKVS, + envelopeKVS driver.EnvelopeKVS, + config *config2.Config, + name string, +) (*network, error) { // Load configuration n := &network{ ctx: ctx, @@ -79,16 +85,29 @@ func NewDB(ctx context.Context, kvss *kvs.KVS, config *config2.Config, name stri config: config, identityManager: n.identityManager, } - n.metadataService = transaction.NewMetadataService(kvss, name) - n.envelopeService = transaction.NewEnvelopeService(kvss, name) + n.metadataService = transaction.NewMetadataService(metadataKVS, name) + n.envelopeService = transaction.NewEnvelopeService(envelopeKVS, name) n.transactionManager = transaction.NewManager(n.sessionManager) - n.transactionService = transaction.NewEndorseTransactionService(kvss, name) + n.transactionService = transaction.NewEndorseTransactionService(endorseTxKVS, name) n.processorManager = rwset.NewProcessorManager(n, nil) return n, nil } -func NewNetwork(ctx context.Context, kvss *kvs.KVS, eventsPublisher events.Publisher, eventsSubscriber events.Subscriber, metricsProvider metrics.Provider, tracerProvider trace.TracerProvider, config *config2.Config, name string, drivers []driver2.NamedDriver, networkConfig driver.NetworkConfig, listenerManager driver.ListenerManager) (*network, error) { +func NewNetwork( + ctx context.Context, + endorseTxKVS driver.EndorseTxKVS, + metadataKVS driver.MetadataKVS, + envelopeKVS driver.EnvelopeKVS, + eventsPublisher events.Publisher, + eventsSubscriber events.Subscriber, + metricsProvider metrics.Provider, + tracerProvider trace.TracerProvider, + config *config2.Config, + name string, drivers []driver2.NamedDriver, + networkConfig driver.NetworkConfig, + listenerManager driver.ListenerManager, +) (*network, error) { // Load configuration n := &network{ ctx: ctx, @@ -115,10 +134,10 @@ func NewNetwork(ctx context.Context, kvss *kvs.KVS, eventsPublisher events.Publi config: config, identityManager: n.identityManager, } - n.metadataService = transaction.NewMetadataService(kvss, name) - n.envelopeService = transaction.NewEnvelopeService(kvss, name) + n.metadataService = transaction.NewMetadataService(metadataKVS, name) + n.envelopeService = transaction.NewEnvelopeService(envelopeKVS, name) n.transactionManager = transaction.NewManager(n.sessionManager) - n.transactionService = transaction.NewEndorseTransactionService(kvss, name) + n.transactionService = transaction.NewEndorseTransactionService(endorseTxKVS, name) var d driver2.Driver for _, driver := range drivers { diff --git a/platform/orion/core/generic/transaction/services.go b/platform/orion/core/generic/transaction/services.go index 06e841a46..b09d332c4 100644 --- a/platform/orion/core/generic/transaction/services.go +++ b/platform/orion/core/generic/transaction/services.go @@ -7,151 +7,85 @@ SPDX-License-Identifier: Apache-2.0 package transaction import ( + driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging" "github.com/hyperledger-labs/fabric-smart-client/platform/orion/driver" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/pkg/errors" ) var logger = logging.MustGetLogger("orion-sdk.core") type mds struct { - kvss *kvs.KVS - network string + metadataKVS driver.MetadataKVS + key func(id driver2.TxID) driver.Key } -func NewMetadataService(kvss *kvs.KVS, network string) *mds { - return &mds{ - kvss: kvss, - network: network, - } +func NewMetadataService(metadataKVS driver.MetadataKVS, network string) *mds { + return &mds{metadataKVS: metadataKVS, key: keyMapper(network)} } func (s *mds) Exists(txid string) bool { - key, err := kvs.CreateCompositeKey("metadata", []string{s.network, txid}) - if err != nil { - return false - } - return s.kvss.Exists(key) + ok, _ := s.metadataKVS.ExistMetadata(s.key(txid)) + return ok } func (s *mds) StoreTransient(txid string, transientMap driver.TransientMap) error { - key, err := kvs.CreateCompositeKey("metadata", []string{s.network, txid}) - if err != nil { - return err - } - logger.Debugf("store transient for [%s]", txid) - - return s.kvss.Put(key, transientMap) + return s.metadataKVS.PutMetadata(s.key(txid), transientMap) } func (s *mds) LoadTransient(txid string) (driver.TransientMap, error) { - logger.Debugf("load transient for [%s]", txid) - - key, err := kvs.CreateCompositeKey("metadata", []string{s.network, txid}) - if err != nil { - return nil, err - } - transientMap := driver.TransientMap{} - err = s.kvss.Get(key, &transientMap) - if err != nil { - return nil, err - } - return transientMap, nil + return s.metadataKVS.GetMetadata(s.key(txid)) } type envs struct { - kvss *kvs.KVS - network string + envelopeKVS driver.EnvelopeKVS + key func(id driver2.TxID) driver.Key } -func NewEnvelopeService(kvss *kvs.KVS, network string) *envs { - return &envs{ - kvss: kvss, - network: network, - } +func NewEnvelopeService(envelopeKVS driver.EnvelopeKVS, network string) *envs { + return &envs{envelopeKVS: envelopeKVS, key: keyMapper(network)} } func (s *envs) Exists(txid string) bool { - key, err := kvs.CreateCompositeKey("envelope", []string{s.network, txid}) - if err != nil { - return false - } - - return s.kvss.Exists(key) + ok, _ := s.envelopeKVS.ExistsEnvelope(s.key(txid)) + return ok } func (s *envs) StoreEnvelope(txid string, env interface{}) error { - key, err := kvs.CreateCompositeKey("envelope", []string{s.network, txid}) - if err != nil { - return err - } - logger.Debugf("store env for [%s]", txid) - switch e := env.(type) { case []byte: - return s.kvss.Put(key, e) + return s.envelopeKVS.PutEnvelope(s.key(txid), e) default: return errors.Errorf("invalid env, expected []byte, got [%T]", env) } } func (s *envs) LoadEnvelope(txid string) ([]byte, error) { - logger.Debugf("load env for [%s]", txid) - - key, err := kvs.CreateCompositeKey("envelope", []string{s.network, txid}) - if err != nil { - return nil, err - } - env := []byte{} - err = s.kvss.Get(key, &env) - if err != nil { - return nil, err - } - return env, nil + return s.envelopeKVS.GetEnvelope(s.key(txid)) } type ets struct { - kvss *kvs.KVS - network string + endorseTxKVS driver.EndorseTxKVS + key func(id driver2.TxID) driver.Key } -func NewEndorseTransactionService(kvss *kvs.KVS, network string) *ets { - return &ets{ - kvss: kvss, - network: network, - } +func NewEndorseTransactionService(endorseTxKVS driver.EndorseTxKVS, network string) *ets { + return &ets{endorseTxKVS: endorseTxKVS, key: keyMapper(network)} } func (s *ets) Exists(txid string) bool { - key, err := kvs.CreateCompositeKey("etx", []string{s.network, txid}) - if err != nil { - return false - } - return s.kvss.Exists(key) + ok, _ := s.endorseTxKVS.ExistsEndorseTx(s.key(txid)) + return ok } func (s *ets) StoreTransaction(txid string, env []byte) error { - key, err := kvs.CreateCompositeKey("etx", []string{s.network, txid}) - if err != nil { - return err - } - logger.Debugf("store etx for [%s]", txid) - - return s.kvss.Put(key, env) + return s.endorseTxKVS.PutEndorseTx(s.key(txid), env) } func (s *ets) LoadTransaction(txid string) ([]byte, error) { - logger.Debugf("load etx for [%s]", txid) + return s.endorseTxKVS.GetEndorseTx(s.key(txid)) +} - key, err := kvs.CreateCompositeKey("etx", []string{s.network, txid}) - if err != nil { - return nil, err - } - env := []byte{} - err = s.kvss.Get(key, &env) - if err != nil { - return nil, err - } - return env, nil +func keyMapper(network string) func(txID driver2.TxID) driver.Key { + return func(txID driver2.TxID) driver.Key { return driver.Key{Network: network, TxID: txID} } } diff --git a/platform/orion/core/provider.go b/platform/orion/core/provider.go index 75a8677cc..1feb20ced 100644 --- a/platform/orion/core/provider.go +++ b/platform/orion/core/provider.go @@ -17,7 +17,6 @@ import ( driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/driver" driver3 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/events" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/metrics" "github.com/pkg/errors" "go.opentelemetry.io/otel/trace" @@ -31,7 +30,9 @@ type ONSProvider struct { configService driver2.ConfigService config *Config ctx context.Context - kvss *kvs.KVS + endorseTxKVS driver.EndorseTxKVS + metadataKVS driver.MetadataKVS + envelopeKVS driver.EnvelopeKVS publisher events.Publisher subscriber events.Subscriber @@ -44,11 +45,26 @@ type ONSProvider struct { listenerManagerProvider driver.ListenerManagerProvider } -func NewOrionNetworkServiceProvider(configService driver2.ConfigService, config *Config, kvss *kvs.KVS, publisher events.Publisher, subscriber events.Subscriber, metricsProvider metrics.Provider, tracerProvider trace.TracerProvider, drivers []driver3.NamedDriver, networkConfigProvider driver.NetworkConfigProvider, listenerManagerProvider driver.ListenerManagerProvider) (*ONSProvider, error) { +func NewOrionNetworkServiceProvider( + configService driver2.ConfigService, + config *Config, + endorseTxKVS driver.EndorseTxKVS, + metadataKVS driver.MetadataKVS, + envelopeKVS driver.EnvelopeKVS, + publisher events.Publisher, + subscriber events.Subscriber, + metricsProvider metrics.Provider, + tracerProvider trace.TracerProvider, + drivers []driver3.NamedDriver, + networkConfigProvider driver.NetworkConfigProvider, + listenerManagerProvider driver.ListenerManagerProvider, +) (*ONSProvider, error) { provider := &ONSProvider{ configService: configService, config: config, - kvss: kvss, + endorseTxKVS: endorseTxKVS, + metadataKVS: metadataKVS, + envelopeKVS: envelopeKVS, publisher: publisher, subscriber: subscriber, networks: map[string]driver.OrionNetworkService{}, @@ -129,5 +145,5 @@ func (p *ONSProvider) newONS(network string) (driver.OrionNetworkService, error) return nil, err } - return generic.NewNetwork(p.ctx, p.kvss, p.publisher, p.subscriber, p.metricsProvider, p.tracerProvider, c, network, p.drivers, networkConfig, p.listenerManagerProvider.NewManager()) + return generic.NewNetwork(p.ctx, p.endorseTxKVS, p.metadataKVS, p.envelopeKVS, p.publisher, p.subscriber, p.metricsProvider, p.tracerProvider, c, network, p.drivers, networkConfig, p.listenerManagerProvider.NewManager()) } diff --git a/platform/orion/driver/kvs.go b/platform/orion/driver/kvs.go new file mode 100644 index 000000000..3bf87357a --- /dev/null +++ b/platform/orion/driver/kvs.go @@ -0,0 +1,26 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package driver + +import "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" + +type Key struct { + Network string + TxID driver.TxID +} + +type MetadataKVS interface { + driver.MetadataKVS[Key, TransientMap] +} + +type EnvelopeKVS interface { + driver.EnvelopeKVS[Key] +} + +type EndorseTxKVS interface { + driver.EndorseTxKVS[Key] +} diff --git a/platform/orion/sdk/dig/sdk.go b/platform/orion/sdk/dig/sdk.go index 31acad279..7ab29d8e2 100644 --- a/platform/orion/sdk/dig/sdk.go +++ b/platform/orion/sdk/dig/sdk.go @@ -21,12 +21,12 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/platform/orion/core/generic" driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/orion/driver" finality2 "github.com/hyperledger-labs/fabric-smart-client/platform/orion/sdk/finality" + "github.com/hyperledger-labs/fabric-smart-client/platform/orion/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/view/driver" viewsdk "github.com/hyperledger-labs/fabric-smart-client/platform/view/sdk/dig" "github.com/hyperledger-labs/fabric-smart-client/platform/view/sdk/finality" driver3 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/events" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/metrics" "go.opentelemetry.io/otel/trace" "go.uber.org/dig" @@ -78,6 +78,9 @@ func (p *SDK) Install() error { p.Container().Provide(orion.NewNetworkServiceProvider), p.Container().Provide(digutils.Identity[*core.ONSProvider](), dig.As(new(driver2.OrionNetworkServiceProvider))), p.Container().Provide(finality2.NewHandler, dig.Group("finality-handlers")), + p.Container().Provide(kvs.NewMetadataKVS, dig.As(new(driver2.MetadataKVS))), + p.Container().Provide(kvs.NewEndorseTxKVS, dig.As(new(driver2.EndorseTxKVS))), + p.Container().Provide(kvs.NewEnvelopeKVS, dig.As(new(driver2.EnvelopeKVS))), ) if err != nil { return err @@ -154,7 +157,9 @@ func newNetworkConfigProvider() driver2.NetworkConfigProvider { func newOrionNetworkServiceProvider(in struct { dig.In - KVSS *kvs.KVS + EndorseTxKVS driver2.EndorseTxKVS + MetadataKVS driver2.MetadataKVS + EnvelopeKVS driver2.EnvelopeKVS Publisher events.Publisher Subscriber events.Subscriber ConfigService driver.ConfigService @@ -165,5 +170,5 @@ func newOrionNetworkServiceProvider(in struct { NetworkConfigProvider driver2.NetworkConfigProvider ListenerManagerProvider driver2.ListenerManagerProvider }) (*core.ONSProvider, error) { - return core.NewOrionNetworkServiceProvider(in.ConfigService, in.Config, in.KVSS, in.Publisher, in.Subscriber, in.MetricsProvider, in.TracerProvider, in.Drivers, in.NetworkConfigProvider, in.ListenerManagerProvider) + return core.NewOrionNetworkServiceProvider(in.ConfigService, in.Config, in.EndorseTxKVS, in.MetadataKVS, in.EnvelopeKVS, in.Publisher, in.Subscriber, in.MetricsProvider, in.TracerProvider, in.Drivers, in.NetworkConfigProvider, in.ListenerManagerProvider) } diff --git a/platform/orion/services/kvs/kvs.go b/platform/orion/services/kvs/kvs.go new file mode 100644 index 000000000..f7b9bccc0 --- /dev/null +++ b/platform/orion/services/kvs/kvs.go @@ -0,0 +1,28 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package kvs + +import ( + "github.com/hyperledger-labs/fabric-smart-client/platform/orion/driver" + "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" +) + +func NewMetadataKVS(kvss *kvs.KVS) driver.MetadataKVS { + return kvs.NewMetadataKVS[driver.Key, driver.TransientMap](kvss, keyMapper("metadata")) +} + +func NewEnvelopeKVS(kvss *kvs.KVS) driver.EnvelopeKVS { + return kvs.NewEnvelopeKVS[driver.Key](kvss, keyMapper("envelope")) +} + +func NewEndorseTxKVS(kvss *kvs.KVS) driver.EndorseTxKVS { + return kvs.NewEndorseTxKVS[driver.Key](kvss, keyMapper("etx")) +} + +func keyMapper(prefix string) kvs.KeyMapper[driver.Key] { + return func(k driver.Key) (string, error) { return kvs.CreateCompositeKey(prefix, []string{k.Network, k.TxID}) } +} diff --git a/platform/view/core/endpoint/endpoint.go b/platform/view/core/endpoint/endpoint.go index 7176a1778..8f4f85439 100644 --- a/platform/view/core/endpoint/endpoint.go +++ b/platform/view/core/endpoint/endpoint.go @@ -13,9 +13,9 @@ import ( "strings" "sync" + driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging" "github.com/hyperledger-labs/fabric-smart-client/platform/view/driver" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs" "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" "github.com/pkg/errors" "go.uber.org/zap/zapcore" @@ -55,16 +55,10 @@ type Discovery interface { Peers() []NetworkMember } -type KVS interface { - Exists(id string) bool - Put(id string, state interface{}) error - Get(id string, state interface{}) error -} - type Service struct { resolvers []*Resolver resolversMutex sync.RWMutex - kvs KVS + bindingKVS driver2.BindingKVS pkiExtractorsLock sync.RWMutex publicKeyExtractors []driver.PublicKeyExtractor @@ -72,9 +66,9 @@ type Service struct { } // NewService returns a new instance of the view-sdk endpoint service -func NewService(kvs KVS) (*Service, error) { +func NewService(bindingKVS driver2.BindingKVS) (*Service, error) { er := &Service{ - kvs: kvs, + bindingKVS: bindingKVS, publicKeyExtractors: []driver.PublicKeyExtractor{}, publicKeyIDSynthesizer: DefaultPublicKeyIDSynthesizer{}, } @@ -104,7 +98,7 @@ func (r *Service) resolve(party view.Identity) (view.Identity, map[driver.PortNa return cursor, e, resolver, nil } logger.Debugf("resolving via binding for %s", cursor) - cursor, err = r.getBinding(cursor) + cursor, err = r.bindingKVS.GetBinding(cursor) if err != nil { return nil, nil, nil, err } @@ -120,7 +114,7 @@ func (r *Service) Bind(longTerm view.Identity, ephemeral view.Identity) error { logger.Debugf("bind [%s] to [%s]", ephemeral, longTerm) - if err := r.putBinding(ephemeral, longTerm); err != nil { + if err := r.bindingKVS.PutBinding(ephemeral, longTerm); err != nil { return errors.WithMessagef(err, "failed storing binding of [%s] to [%s]", ephemeral.UniqueID(), longTerm.UniqueID()) } @@ -132,7 +126,7 @@ func (r *Service) IsBoundTo(a view.Identity, b view.Identity) bool { if a.Equal(b) { return true } - next, err := r.getBinding(a) + next, err := r.bindingKVS.GetBinding(a) if err != nil { return false } @@ -284,32 +278,6 @@ func (r *Service) rootEndpoint(party view.Identity) (*Resolver, map[driver.PortN return nil, nil, errors.Errorf("endpoint not found for identity %s", party.UniqueID()) } -func (r *Service) putBinding(ephemeral, longTerm view.Identity) error { - k := kvs.CreateCompositeKeyOrPanic( - "platform.fsc.endpoint.binding", - []string{ephemeral.UniqueID()}, - ) - if err := r.kvs.Put(k, longTerm); err != nil { - return err - } - return nil -} - -func (r *Service) getBinding(ephemeral view.Identity) (view.Identity, error) { - k := kvs.CreateCompositeKeyOrPanic( - "platform.fsc.endpoint.binding", - []string{ephemeral.UniqueID()}, - ) - if !r.kvs.Exists(k) { - return nil, errors.Errorf("binding not found for [%s]", ephemeral.UniqueID()) - } - longTerm := view.Identity{} - if err := r.kvs.Get(k, &longTerm); err != nil { - return nil, err - } - return longTerm, nil -} - var portNameMap = map[string]driver.PortName{ strings.ToLower(string(driver.ListenPort)): driver.ListenPort, strings.ToLower(string(driver.ViewPort)): driver.ViewPort, diff --git a/platform/view/core/endpoint/endpoint_test.go b/platform/view/core/endpoint/endpoint_test.go index a31719901..eb3208f62 100644 --- a/platform/view/core/endpoint/endpoint_test.go +++ b/platform/view/core/endpoint/endpoint_test.go @@ -16,15 +16,8 @@ import ( type mockKVS struct{} -func (k mockKVS) Exists(id string) bool { - return true -} -func (k mockKVS) Put(id string, state interface{}) error { - return nil -} -func (k mockKVS) Get(id string, state interface{}) error { - return nil -} +func (k mockKVS) GetBinding(ephemeral view.Identity) (view.Identity, error) { return nil, nil } +func (k mockKVS) PutBinding(ephemeral, longTerm view.Identity) error { return nil } type mockExtractor struct{} diff --git a/platform/view/sdk/dig/sdk.go b/platform/view/sdk/dig/sdk.go index d832aa772..f0d8f40b2 100644 --- a/platform/view/sdk/dig/sdk.go +++ b/platform/view/sdk/dig/sdk.go @@ -12,6 +12,7 @@ import ( "github.com/go-kit/log" "github.com/hyperledger-labs/fabric-smart-client/pkg/node" + driver4 "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" dig2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/sdk/dig" "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging" sig2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/sig" @@ -102,8 +103,10 @@ func (p *SDK) Install() error { p.C.Provide(sig2.NewDeserializer), p.C.Provide(sig2.NewService, dig.As(new(id.SigService), new(driver.SigService), new(driver.SigRegistry), new(driver.AuditRegistry))), p.C.Provide(view.NewSigService, dig.As(new(view3.VerifierProvider), new(view3.SignerProvider))), - p.C.Provide(digutils.Identity[*kvs.KVS](), dig.As(new(sig2.KVS))), - p.C.Provide(func(defaultKVS *kvs.KVS) (*endpoint.Service, error) { return endpoint.NewService(defaultKVS) }), + p.C.Provide(kvs.NewBindingKVS, dig.As(new(driver4.BindingKVS))), + p.C.Provide(kvs.NewSignerKVS, dig.As(new(driver4.SignerKVS))), + p.C.Provide(kvs.NewAuditInfoKVS, dig.As(new(driver4.AuditInfoKVS))), + p.C.Provide(endpoint.NewService), p.C.Provide(digutils.Identity[*endpoint.Service](), dig.As(new(driver.EndpointService))), p.C.Provide(view.NewEndpointService), p.C.Provide(digutils.Identity[*view.EndpointService](), dig.As(new(comm.EndpointService), new(id.EndpointService), new(endpoint.Backend))), diff --git a/platform/view/services/kvs/enhanced.go b/platform/view/services/kvs/enhanced.go new file mode 100644 index 000000000..70d0a0497 --- /dev/null +++ b/platform/view/services/kvs/enhanced.go @@ -0,0 +1,75 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package kvs + +import "github.com/hyperledger-labs/fabric-smart-client/platform/common/utils" + +type KeyMapper[K any] func(K) (string, error) + +func newEnhancedKVS[K any, V any](kvs *KVS, keyMapper KeyMapper[K]) *enhancedKVS[K, V] { + return &enhancedKVS[K, V]{ + kvs: kvs, + keyMapper: keyMapper, + } +} + +type enhancedKVS[K any, V any] struct { + kvs *KVS + keyMapper KeyMapper[K] +} + +func (kvs *enhancedKVS[K, V]) Get(id K) (V, error) { + k, err := kvs.keyMapper(id) + if err != nil { + return utils.Zero[V](), err + } + + if !kvs.kvs.Exists(k) { + return utils.Zero[V](), nil + } + var res V + if err := kvs.kvs.Get(k, &res); err != nil { + return utils.Zero[V](), err + } + return res, nil +} + +func (kvs *enhancedKVS[K, V]) FilterExisting(inputKeys ...K) ([]K, error) { + stringKeyMap := make(map[string]K, len(inputKeys)) + inputStrings := make([]string, len(inputKeys)) + for i, key := range inputKeys { + k, err := kvs.keyMapper(key) + if err != nil { + return nil, err + } + inputStrings[i] = k + stringKeyMap[k] = key + } + existingStrings := kvs.kvs.GetExisting(inputStrings...) + existingKeys := make([]K, len(existingStrings)) + for i, key := range existingStrings { + existingKeys[i] = stringKeyMap[key] + } + return existingKeys, nil +} + +func (kvs *enhancedKVS[K, V]) Exists(id K) (bool, error) { + k, err := kvs.keyMapper(id) + if err != nil { + return false, err + } + + return kvs.kvs.Exists(k), nil +} + +func (kvs *enhancedKVS[K, V]) Put(id K, info V) error { + k, err := kvs.keyMapper(id) + if err != nil { + return err + } + return kvs.kvs.Put(k, info) +} diff --git a/platform/view/services/kvs/scope.go b/platform/view/services/kvs/scope.go new file mode 100644 index 000000000..366a3afb4 --- /dev/null +++ b/platform/view/services/kvs/scope.go @@ -0,0 +1,114 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package kvs + +import ( + "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/sig" + "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" +) + +// Signer + +func NewSignerKVS(kvs *KVS) *signerKVS { + return &signerKVS{e: newEnhancedKVS[view.Identity, *sig.SignerEntry](kvs, signerKey)} +} + +func signerKey(id view.Identity) (string, error) { + return CreateCompositeKey("sigService", []string{"signer", id.UniqueID()}) +} + +type signerKVS struct { + e *enhancedKVS[view.Identity, *sig.SignerEntry] +} + +func (kvs *signerKVS) GetSigner(id view.Identity) (*sig.SignerEntry, error) { return kvs.e.Get(id) } +func (kvs *signerKVS) FilterExistingSigners(ids ...view.Identity) ([]view.Identity, error) { + return kvs.e.FilterExisting(ids...) +} +func (kvs *signerKVS) PutSigner(id view.Identity, entry *sig.SignerEntry) error { + return kvs.e.Put(id, entry) +} + +// Audit info + +func NewAuditInfoKVS(kvs *KVS) *auditInfoKVS { + return &auditInfoKVS{e: newEnhancedKVS[view.Identity, []byte](kvs, auditInfoKey)} +} + +func auditInfoKey(id view.Identity) (string, error) { + return CreateCompositeKey("fsc.platform.view.sig", []string{id.UniqueID()}) +} + +type auditInfoKVS struct { + e *enhancedKVS[view.Identity, []byte] +} + +func (kvs *auditInfoKVS) GetAuditInfo(id view.Identity) ([]byte, error) { return kvs.e.Get(id) } +func (kvs *auditInfoKVS) PutAuditInfo(id view.Identity, info []byte) error { + return kvs.e.Put(id, info) +} + +// Binding + +func NewBindingKVS(kvs *KVS) *bindingKVS { + return &bindingKVS{e: newEnhancedKVS[view.Identity, view.Identity](kvs, bindingKey)} +} + +type bindingKVS struct { + e *enhancedKVS[view.Identity, view.Identity] +} + +func (kvs *bindingKVS) GetBinding(ephemeral view.Identity) (view.Identity, error) { + return kvs.e.Get(ephemeral) +} +func (kvs *bindingKVS) PutBinding(ephemeral, longTerm view.Identity) error { + return kvs.e.Put(ephemeral, longTerm) +} + +func bindingKey(ephemeral view.Identity) (string, error) { + return CreateCompositeKey("platform.fsc.endpoint.binding", []string{ephemeral.UniqueID()}) +} + +func NewMetadataKVS[K any, M any](kvss *KVS, keyMapper KeyMapper[K]) *metadataKVS[K, M] { + return &metadataKVS[K, M]{e: newEnhancedKVS[K, M](kvss, keyMapper)} +} + +type metadataKVS[K any, M any] struct { + e *enhancedKVS[K, M] +} + +func (kvs *metadataKVS[K, M]) GetMetadata(key K) (M, error) { + return kvs.e.Get(key) +} +func (kvs *metadataKVS[K, M]) ExistMetadata(key K) (bool, error) { return kvs.e.Exists(key) } +func (kvs *metadataKVS[K, M]) PutMetadata(key K, tm M) error { + return kvs.e.Put(key, tm) +} + +func NewEnvelopeKVS[K any](kvss *KVS, keyMapper KeyMapper[K]) *envelopeKVS[K] { + return &envelopeKVS[K]{e: newEnhancedKVS[K, []byte](kvss, keyMapper)} +} + +type envelopeKVS[K any] struct { + e *enhancedKVS[K, []byte] +} + +func (kvs *envelopeKVS[K]) GetEnvelope(key K) ([]byte, error) { return kvs.e.Get(key) } +func (kvs *envelopeKVS[K]) ExistsEnvelope(key K) (bool, error) { return kvs.e.Exists(key) } +func (kvs *envelopeKVS[K]) PutEnvelope(key K, env []byte) error { return kvs.e.Put(key, env) } + +func NewEndorseTxKVS[K any](kvss *KVS, keyMapper KeyMapper[K]) *endorseTxKVS[K] { + return &endorseTxKVS[K]{e: newEnhancedKVS[K, []byte](kvss, keyMapper)} +} + +type endorseTxKVS[K any] struct { + e *enhancedKVS[K, []byte] +} + +func (kvs *endorseTxKVS[K]) GetEndorseTx(key K) ([]byte, error) { return kvs.e.Get(key) } +func (kvs *endorseTxKVS[K]) ExistsEndorseTx(key K) (bool, error) { return kvs.e.Exists(key) } +func (kvs *endorseTxKVS[K]) PutEndorseTx(key K, etx []byte) error { return kvs.e.Put(key, etx) }