diff --git a/integration/fsc/pingpong/cmd/initiator/main.go b/integration/fsc/pingpong/cmd/initiator/main.go index f78860804..6a63c6727 100644 --- a/integration/fsc/pingpong/cmd/initiator/main.go +++ b/integration/fsc/pingpong/cmd/initiator/main.go @@ -10,20 +10,18 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/integration/fsc/pingpong" "github.com/hyperledger-labs/fabric-smart-client/integration/fsc/pingpong/mock" fscnode "github.com/hyperledger-labs/fabric-smart-client/node" - "github.com/hyperledger-labs/fabric-smart-client/platform/view" ) func main() { node := fscnode.New() node.Execute(func() error { - registry := view.GetRegistry(node) - if err := registry.RegisterFactory("init", &pingpong.InitiatorViewFactory{}); err != nil { + if err := node.RegisterFactory("init", &pingpong.InitiatorViewFactory{}); err != nil { return err } - if err := registry.RegisterFactory("mockInit", &mock.InitiatorViewFactory{}); err != nil { + if err := node.RegisterFactory("mockInit", &mock.InitiatorViewFactory{}); err != nil { return err } - if err := registry.RegisterFactory("stream", &pingpong.StreamerViewFactory{}); err != nil { + if err := node.RegisterFactory("stream", &pingpong.StreamerViewFactory{}); err != nil { return err } return nil diff --git a/integration/fsc/pingpong/cmd/responder/main.go b/integration/fsc/pingpong/cmd/responder/main.go index 735ca7d58..ba92bb098 100644 --- a/integration/fsc/pingpong/cmd/responder/main.go +++ b/integration/fsc/pingpong/cmd/responder/main.go @@ -10,18 +10,17 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/integration/fsc/pingpong" "github.com/hyperledger-labs/fabric-smart-client/integration/fsc/pingpong/mock" fscnode "github.com/hyperledger-labs/fabric-smart-client/node" - "github.com/hyperledger-labs/fabric-smart-client/platform/view" + "github.com/hyperledger-labs/fabric-smart-client/platform/view/core/registry" ) func main() { node := fscnode.New() node.Execute(func() error { - registry := view.GetRegistry(node) initiatorID := registry.GetIdentifier(&pingpong.Initiator{}) - if err := registry.RegisterResponder(&pingpong.Responder{}, initiatorID); err != nil { + if err := node.RegisterResponder(&pingpong.Responder{}, initiatorID); err != nil { return err } - if err := registry.RegisterResponder(&pingpong.Responder{}, &mock.Initiator{}); err != nil { + if err := node.RegisterResponder(&pingpong.Responder{}, &mock.Initiator{}); err != nil { return err } return nil diff --git a/integration/fsc/pingpong/pingpong_test.go b/integration/fsc/pingpong/pingpong_test.go index dd125a720..68a2ea32f 100644 --- a/integration/fsc/pingpong/pingpong_test.go +++ b/integration/fsc/pingpong/pingpong_test.go @@ -194,7 +194,7 @@ var _ = Describe("EndToEnd", func() { func newNode(conf string) api.FabricSmartClientNode { n := node.NewEmpty(conf) Expect(n).NotTo(BeNil()) - n.AddSDK(viewsdk.NewSDK(n.Registry())) + n.AddSDK(viewsdk.NewSDK(n)) return n } diff --git a/integration/nwo/fsc/node/node_template.go b/integration/nwo/fsc/node/node_template.go index 29506cf0f..179fa38c4 100644 --- a/integration/nwo/fsc/node/node_template.go +++ b/integration/nwo/fsc/node/node_template.go @@ -17,7 +17,6 @@ package main import ( fscnode "github.com/hyperledger-labs/fabric-smart-client/node" - {{ if InstallView }}viewregistry "github.com/hyperledger-labs/fabric-smart-client/platform/view"{{ end }} {{- range .Imports }} {{ Alias . }} "{{ . }}"{{ end }} ) @@ -29,13 +28,12 @@ func main() { {{ end }} n.Execute(func() error { {{- if InstallView }} - registry := viewregistry.GetRegistry(n) {{- range .Factories }} - if err := registry.RegisterFactory("{{ .Id }}", {{ .Type }}); err != nil { + if err := n.RegisterFactory("{{ .Id }}", {{ .Type }}); err != nil { return err }{{ end }} {{- range .Responders }} - registry.RegisterResponder({{ .Responder }}, {{ .Initiator }}){{ end }} + n.RegisterResponder({{ .Responder }}, {{ .Initiator }}){{ end }} {{ end }} return nil }) diff --git a/node/node.go b/node/node.go index 0af1d6323..03c0ea28a 100644 --- a/node/node.go +++ b/node/node.go @@ -28,13 +28,17 @@ type FabricSmartClient interface { Stop() InstallSDK(p api.SDK) error ConfigService() node3.ConfigService - Registry() node3.Registry GetService(v interface{}) (interface{}, error) RegisterService(service interface{}) error RegisterFactory(id string, factory api.Factory) error RegisterResponder(responder view.View, initiatedBy interface{}) error RegisterResponderWithIdentity(responder view.View, id view.Identity, initiatedBy view.View) error - ResolveIdentities(endpoints ...string) ([]view.Identity, error) + + // RegisterViewManager injects the ViewManager dependency + RegisterViewManager(manager node3.ViewManager) + + // RegisterViewRegistry injects the ViewRegistry dependency + RegisterViewRegistry(registry node3.ViewRegistry) } type node struct { @@ -51,7 +55,7 @@ func New() *node { func NewFromConfPath(confPath string) *node { n := node3.NewEmpty(confPath) - n.AddSDK(sdk.NewSDK(n.Registry())) + n.AddSDK(sdk.NewSDK(n)) return newFromFsc(n) } diff --git a/pkg/node/node.go b/pkg/node/node.go index 5af3b4253..84f247b05 100755 --- a/pkg/node/node.go +++ b/pkg/node/node.go @@ -17,12 +17,12 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging" view2 "github.com/hyperledger-labs/fabric-smart-client/platform/view" "github.com/hyperledger-labs/fabric-smart-client/platform/view/core/config" - tracing2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/sdk/tracing" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/registry" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/tracing" "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" "github.com/pkg/errors" "go.opentelemetry.io/otel/trace" + "go.opentelemetry.io/otel/trace/noop" ) const ( @@ -33,6 +33,12 @@ var logger = logging.MustGetLogger("fsc") type ExecuteCallbackFunc = func() error +type ViewRegistry interface { + RegisterFactory(id string, factory view2.Factory) error + RegisterResponder(responder view2.View, initiatedBy interface{}) error + RegisterResponderWithIdentity(responder view2.View, id view.Identity, initiatedBy interface{}) error +} + type ViewManager interface { NewView(id string, in []byte) (view.View, error) InitiateView(view view.View, ctx context.Context) (interface{}, error) @@ -43,8 +49,13 @@ type ViewManager interface { } type Registry interface { - GetService(v interface{}) (interface{}, error) + serviceRegistry + RegisterViewManager(manager ViewManager) + RegisterViewRegistry(registry ViewRegistry) +} +type serviceRegistry interface { + GetService(v interface{}) (interface{}, error) RegisterService(service interface{}) error } @@ -58,13 +69,15 @@ type PostStart interface { } type node struct { - registry Registry + registry serviceRegistry configService ConfigService sdks []api.SDK context context.Context cancel context.CancelFunc running bool tracer trace.Tracer + viewManager ViewManager + viewRegistry ViewRegistry } func NewEmpty(confPath string) *node { @@ -81,9 +94,26 @@ func NewEmpty(confPath string) *node { sdks: []api.SDK{}, registry: registry, configService: configService, + tracer: noop.NewTracerProvider().Tracer("noop"), } } +func (n *node) RegisterTracerProvider(provider trace.TracerProvider) { + logger.Infof("Register tracer provider") + n.tracer = provider.Tracer("node_view_client", tracing.WithMetricsOpts(tracing.MetricsOpts{ + Namespace: "viewsdk", + LabelNames: []tracing.LabelName{fidLabel}, + })) +} + +func (n *node) RegisterViewManager(manager ViewManager) { + n.viewManager = manager +} + +func (n *node) RegisterViewRegistry(registry ViewRegistry) { + n.viewRegistry = registry +} + func (n *node) AddSDK(sdk api.SDK) { n.sdks = append(n.sdks, sdk) } @@ -157,56 +187,29 @@ func (n *node) InstallSDK(p api.SDK) error { } func (n *node) RegisterFactory(id string, factory api.Factory) error { - return view2.GetRegistry(n.registry).RegisterFactory(id, factory) + return n.viewRegistry.RegisterFactory(id, factory) } func (n *node) RegisterResponder(responder view.View, initiatedBy interface{}) error { - return view2.GetRegistry(n.registry).RegisterResponder(responder, initiatedBy) + return n.viewRegistry.RegisterResponder(responder, initiatedBy) } func (n *node) RegisterResponderWithIdentity(responder view.View, id view.Identity, initiatedBy view.View) error { - return view2.GetRegistry(n.registry).RegisterResponderWithIdentity(responder, id, initiatedBy) + return n.viewRegistry.RegisterResponderWithIdentity(responder, id, initiatedBy) } +// RegisterService To be deprecated func (n *node) RegisterService(service interface{}) error { return n.registry.RegisterService(service) } +// GetService to be deprecated func (n *node) GetService(v interface{}) (interface{}, error) { return n.registry.GetService(v) } -func (n *node) Registry() Registry { - return n.registry -} - -func (n *node) ResolveIdentities(endpoints ...string) ([]view.Identity, error) { - resolver := view2.GetEndpointService(n.registry) - - var ids []view.Identity - for _, e := range endpoints { - identity, err := resolver.GetIdentity(e, nil) - if err != nil { - return nil, errors.Wrapf(err, "cannot find the identity at %s", e) - } - ids = append(ids, identity) - } - - return ids, nil -} - -func (n *node) getTracer() trace.Tracer { - if n.tracer == nil { - n.tracer = tracing2.Get(n.registry).Tracer("node_view_client", tracing.WithMetricsOpts(tracing.MetricsOpts{ - Namespace: "viewsdk", - LabelNames: []tracing.LabelName{fidLabel}, - })) - } - return n.tracer -} - func (n *node) CallView(fid string, in []byte) (interface{}, error) { - ctx, span := n.getTracer().Start(context.Background(), "CallView", + ctx, span := n.tracer.Start(context.Background(), "CallView", trace.WithSpanKind(trace.SpanKindClient), tracing.WithAttributes(tracing.String(fidLabel, fid))) defer span.End() @@ -239,44 +242,20 @@ func (n *node) CallView(fid string, in []byte) (interface{}, error) { } func (n *node) InitiateContext(view view.View) (view.Context, error) { - s, err := n.GetService(reflect.TypeOf((*ViewManager)(nil))) - if err != nil { - return nil, err - } - manager := s.(ViewManager) - - return manager.InitiateContext(view) + return n.viewManager.InitiateContext(view) } // InitiateContextFrom creates a new view context, derived from the passed context.Context func (n *node) InitiateContextFrom(ctx context.Context, view view.View) (view.Context, error) { - s, err := n.GetService(reflect.TypeOf((*ViewManager)(nil))) - if err != nil { - return nil, err - } - manager := s.(ViewManager) - - return manager.InitiateContextFrom(ctx, view, nil, "") + return n.viewManager.InitiateContextFrom(ctx, view, nil, "") } func (n *node) InitiateContextWithIdentity(view view.View, id view.Identity) (view.Context, error) { - s, err := n.GetService(reflect.TypeOf((*ViewManager)(nil))) - if err != nil { - return nil, err - } - manager := s.(ViewManager) - - return manager.InitiateContextWithIdentity(view, id) + return n.viewManager.InitiateContextWithIdentity(view, id) } func (n *node) Context(contextID string) (view.Context, error) { - s, err := n.GetService(reflect.TypeOf((*ViewManager)(nil))) - if err != nil { - return nil, err - } - manager := s.(ViewManager) - - return manager.Context(contextID) + return n.viewManager.Context(contextID) } func (n *node) Initiate(fid string, in []byte) (string, error) { diff --git a/platform/common/utils/dig/dig.go b/platform/common/utils/dig/dig.go index e0e9c06e4..92ca6bf36 100644 --- a/platform/common/utils/dig/dig.go +++ b/platform/common/utils/dig/dig.go @@ -10,12 +10,16 @@ import ( "bytes" "errors" "fmt" + "reflect" "runtime/debug" "github.com/hyperledger-labs/fabric-smart-client/pkg/node" + "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging" "go.uber.org/dig" ) +var logger = logging.MustGetLogger("dig-utils") + type invoker interface { Invoke(function interface{}, opts ...dig.InvokeOption) error } @@ -40,6 +44,26 @@ func Register[T any](c invoker) error { return nil } +func RegisterOptional[T any](c invoker) error { + //Temporary workaround for services that are imported still using the registry + err := c.Invoke(func(in struct { + dig.In + Registry node.Registry + Service T `optional:"true"` + }) error { + if reflect.ValueOf(in.Service).IsNil() { + logger.Warnf("Skipping registration of optional dependency [%T]", new(T)) + return nil + } + return in.Registry.RegisterService(in.Service) + }) + if err != nil { + debug.PrintStack() + return fmt.Errorf("failed registering type %T: %+v", *new(T), err) + } + return nil +} + func ProvideAll(c *dig.Container, constructors ...interface{}) error { errs := make([]error, len(constructors)) for i, constructor := range constructors { diff --git a/platform/fabric/services/endorser/builder.go b/platform/fabric/services/endorser/builder.go index 6245920eb..95d97a7c1 100644 --- a/platform/fabric/services/endorser/builder.go +++ b/platform/fabric/services/endorser/builder.go @@ -13,7 +13,6 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/platform/common/services/logging" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric" - view2 "github.com/hyperledger-labs/fabric-smart-client/platform/view" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/session" "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" @@ -22,21 +21,14 @@ import ( var logger = logging.MustGetLogger("fabric-sdk.services.endorser") type Builder struct { - sp view2.ServiceProvider + fnsProvider *fabric.NetworkServiceProvider } -func NewBuilder(context view.Context) *Builder { - if context == nil { +func NewBuilder(fnsProvider *fabric.NetworkServiceProvider) *Builder { + if fnsProvider == nil { panic("context must be set") } - return &Builder{sp: context} -} - -func NewBuilderWithServiceProvider(sp view2.ServiceProvider) *Builder { - if sp == nil { - panic("service provider must be set") - } - return &Builder{sp: sp} + return &Builder{fnsProvider: fnsProvider} } func (t *Builder) NewTransaction(ctx context.Context, opts ...fabric.TransactionOption) (*Transaction, error) { @@ -94,7 +86,7 @@ func (t *Builder) newTransactionWithType(ctx context.Context, creator []byte, ne logger.Debugf("NewTransaction [%s,%s,%s]", view.Identity(creator).UniqueID(), channel, hash.Hashable(raw).String()) defer logger.Debugf("NewTransaction...done.") - fNetwork, err := fabric.GetFabricNetworkService(t.sp, network) + fNetwork, err := t.fnsProvider.FabricNetworkService(network) if err != nil { return nil, errors.WithMessagef(err, "fabric network service [%s] not found", network) } @@ -128,13 +120,13 @@ func (t *Builder) newTransactionWithType(ctx context.Context, creator []byte, ne return nil, err } return &Transaction{ - ServiceProvider: t.sp, - Transaction: fabricTransaction, + fnsProvider: t.fnsProvider, + Transaction: fabricTransaction, }, nil } -func NewTransaction(context view.Context, opts ...fabric.TransactionOption) (*Builder, *Transaction, error) { - txBuilder := NewBuilder(context) +func NewTransaction(fnsProvider *fabric.NetworkServiceProvider, context view.Context, opts ...fabric.TransactionOption) (*Builder, *Transaction, error) { + txBuilder := NewBuilder(fnsProvider) tx, err := txBuilder.NewTransaction(context.Context(), opts...) if err != nil { return nil, nil, err @@ -143,8 +135,8 @@ func NewTransaction(context view.Context, opts ...fabric.TransactionOption) (*Bu return txBuilder, tx, nil } -func NewTransactionFromBytes(context view.Context, bytes []byte) (*Builder, *Transaction, error) { - txBuilder := NewBuilder(context) +func NewTransactionFromBytes(fnsProvider *fabric.NetworkServiceProvider, context view.Context, bytes []byte) (*Builder, *Transaction, error) { + txBuilder := NewBuilder(fnsProvider) tx, err := txBuilder.NewTransactionFromBytes(bytes) if err != nil { return nil, nil, err @@ -153,18 +145,18 @@ func NewTransactionFromBytes(context view.Context, bytes []byte) (*Builder, *Tra return txBuilder, tx, nil } -func NewTransactionWithSigner(context view.Context, network, channel string, id view.Identity) (*Builder, *Transaction, error) { - txBuilder := NewBuilderWithServiceProvider(context) - tx, err := txBuilder.newTransaction(context.Context(), id, network, channel, nil, nil, false) +func NewTransactionWithSigner(fnsProvider *fabric.NetworkServiceProvider, ctx view.Context, network, channel string, id view.Identity) (*Builder, *Transaction, error) { + txBuilder := NewBuilder(fnsProvider) + tx, err := txBuilder.newTransaction(ctx.Context(), id, network, channel, nil, nil, false) if err != nil { return nil, nil, err } - context.OnError(tx.Close) + ctx.OnError(tx.Close) return txBuilder, tx, nil } -func NewTransactionWith(ctx context.Context, sp view2.ServiceProvider, network, channel string, id view.Identity) (*Builder, *Transaction, error) { - txBuilder := NewBuilderWithServiceProvider(sp) +func NewTransactionWith(fnsProvider *fabric.NetworkServiceProvider, ctx context.Context, network, channel string, id view.Identity) (*Builder, *Transaction, error) { + txBuilder := NewBuilder(fnsProvider) tx, err := txBuilder.newTransaction(ctx, id, network, channel, nil, nil, false) if err != nil { return nil, nil, err @@ -172,8 +164,8 @@ func NewTransactionWith(ctx context.Context, sp view2.ServiceProvider, network, return txBuilder, tx, nil } -func NewTransactionFromEnvelopeBytes(ctx context.Context, sp view2.ServiceProvider, bytes []byte) (*Builder, *Transaction, error) { - txBuilder := NewBuilderWithServiceProvider(sp) +func NewTransactionFromEnvelopeBytes(fnsProvider *fabric.NetworkServiceProvider, ctx context.Context, bytes []byte) (*Builder, *Transaction, error) { + txBuilder := NewBuilder(fnsProvider) tx, err := txBuilder.NewTransactionFromEnvelopeBytes(ctx, bytes) if err != nil { return nil, nil, err @@ -181,7 +173,7 @@ func NewTransactionFromEnvelopeBytes(ctx context.Context, sp view2.ServiceProvid return txBuilder, tx, nil } -func ReceiveTransaction(context view.Context) (*Transaction, error) { - _, tx, err := NewTransactionFromBytes(context, session.ReadFirstMessageOrPanic(context)) +func ReceiveTransaction(fnsProvider *fabric.NetworkServiceProvider, context view.Context) (*Transaction, error) { + _, tx, err := NewTransactionFromBytes(fnsProvider, context, session.ReadFirstMessageOrPanic(context)) return tx, err } diff --git a/platform/fabric/services/endorser/flow.go b/platform/fabric/services/endorser/flow.go index 9de93e9e6..f0f895dbe 100644 --- a/platform/fabric/services/endorser/flow.go +++ b/platform/fabric/services/endorser/flow.go @@ -7,6 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package endorser import ( + "github.com/hyperledger-labs/fabric-smart-client/platform/common/utils" + "github.com/hyperledger-labs/fabric-smart-client/platform/fabric" "github.com/pkg/errors" "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" @@ -20,7 +22,7 @@ func (r *receiveTransactionView) Call(context view.Context) (interface{}, error) return nil, errors.Wrap(err, "failed receiving transaction content") } - builder := NewBuilder(context) + builder := NewBuilder(utils.MustGet(fabric.GetNetworkServiceProvider(context))) tx, err := builder.NewTransactionFromBytes(raw.([]byte)) if err != nil { return nil, errors.Wrap(err, "failed reconstructing transaction") diff --git a/platform/fabric/services/endorser/transaction.go b/platform/fabric/services/endorser/transaction.go index d66618f08..df254cb69 100644 --- a/platform/fabric/services/endorser/transaction.go +++ b/platform/fabric/services/endorser/transaction.go @@ -10,19 +10,22 @@ import ( "bytes" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric" - view2 "github.com/hyperledger-labs/fabric-smart-client/platform/view" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" "github.com/pkg/errors" ) type Transaction struct { - view2.ServiceProvider + fnsProvider *fabric.NetworkServiceProvider Transaction *fabric.Transaction verifierProviders []fabric.VerifierProvider } +func (t *Transaction) NetworkServiceProvider() *fabric.NetworkServiceProvider { + return t.fnsProvider +} + func (t *Transaction) ID() string { return t.Transaction.ID() } diff --git a/platform/fabric/services/state/certification.go b/platform/fabric/services/state/certification.go index 39d10468d..9aabe0672 100644 --- a/platform/fabric/services/state/certification.go +++ b/platform/fabric/services/state/certification.go @@ -118,7 +118,7 @@ func (n *Namespace) VerifyInputCertificationAt(index int, key string) error { // raw is an envelope, it must be signed by enough endorsers cn, cv := n.tx.Chaincode() - _, ch, err := fabric.GetChannel(n.tx.ServiceProvider, n.tx.Network(), n.tx.Channel()) + ch, err := n.tx.FabricNetworkService().Channel(n.tx.Channel()) if err != nil { return errors.Wrapf(err, "failed getting channel [%s:%s]", n.tx.Network(), n.tx.Channel()) } @@ -126,7 +126,7 @@ func (n *Namespace) VerifyInputCertificationAt(index int, key string) error { if err != nil { return errors.Wrapf(err, "failed asking endorsers for to [%s,%s,%s] for [%s]", n.tx.Channel(), cn, cv, id) } - _, certTx, err := endorser.NewTransactionFromEnvelopeBytes(context.Background(), n.tx.ServiceProvider, raw) + _, certTx, err := endorser.NewTransactionFromEnvelopeBytes(n.tx.NetworkServiceProvider(), context.Background(), raw) if err != nil { return errors.Wrapf(err, "failed parsing certification [%s,%s,%s] for [%s]", n.tx.Channel(), cn, cv, id) } @@ -175,12 +175,12 @@ func (n *Namespace) certifyInput(id string) error { case ChaincodeCertification: // Invoke chaincode cn, cv := n.tx.Chaincode() - fns, ch, err := fabric.GetChannel(n.tx.ServiceProvider, n.tx.Network(), n.tx.Channel()) + ch, err := n.tx.FabricNetworkService().Channel(n.tx.Channel()) if err != nil { return errors.Wrapf(err, "failed getting channel [%s:%s]", n.tx.Network(), n.tx.Channel()) } env, err := ch.Chaincode(cn).Endorse(CertificationFnc, id, n.tx.ID()).WithInvokerIdentity( - fns.IdentityProvider().DefaultIdentity(), + n.tx.FabricNetworkService().IdentityProvider().DefaultIdentity(), ).Call() if err != nil { return errors.Wrapf(err, "failed asking certification to [%s,%s,%s] for [%s]", n.tx.Channel(), cn, cv, id) diff --git a/platform/fabric/services/state/namespace.go b/platform/fabric/services/state/namespace.go index 2ebda1b50..430cbe3e6 100755 --- a/platform/fabric/services/state/namespace.go +++ b/platform/fabric/services/state/namespace.go @@ -51,15 +51,7 @@ type Namespace struct { } func NewNamespace(tx *endorser.Transaction, forceSBE bool) *Namespace { - return &Namespace{ - tx: tx, - codec: &JSONCodec{}, - metaHandlers: []MetaHandler{ - &sbeMetaHandler{forceSBE: forceSBE}, - &contractMetaHandler{}, - }, - certifiedInputs: map[string][]byte{}, - } + return NewNamespaceForName(tx, "", forceSBE) } func NewNamespaceForName(tx *endorser.Transaction, ns string, forceSBE bool) *Namespace { @@ -458,10 +450,6 @@ func (n *Namespace) RWSet() (*fabric.RWSet, error) { return n.tx.RWSet() } -func (n *Namespace) GetService(v interface{}) (interface{}, error) { - return n.tx.GetService(v) -} - func (n *Namespace) getStateID(s interface{}) (string, error) { logger.Debugf("getStateID %v...", s) defer logger.Debugf("getStateID...done") diff --git a/platform/fabric/services/state/transaction.go b/platform/fabric/services/state/transaction.go index 5d3032e47..d93932e2e 100755 --- a/platform/fabric/services/state/transaction.go +++ b/platform/fabric/services/state/transaction.go @@ -10,6 +10,7 @@ import ( "encoding/base64" "time" + "github.com/hyperledger-labs/fabric-smart-client/platform/common/utils" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/services/endorser" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash" @@ -35,7 +36,11 @@ func Wrap(tx *endorser.Transaction) (*Transaction, error) { // NewTransaction returns a new instance of a state-based transaction that embeds a single namespace. func NewTransaction(context view.Context) (*Transaction, error) { - _, tx, err := endorser.NewTransaction(context) + return newTransaction(utils.MustGet(fabric.GetNetworkServiceProvider(context)), context) +} + +func newTransaction(fnsProvider *fabric.NetworkServiceProvider, context view.Context) (*Transaction, error) { + _, tx, err := endorser.NewTransaction(fnsProvider, context) if err != nil { return nil, err } @@ -50,10 +55,14 @@ func NewTransaction(context view.Context) (*Transaction, error) { }, nil } +func NewAnonymousTransaction(context view.Context) (*Transaction, error) { + return newAnonymousTransaction(utils.MustGet(fabric.GetNetworkServiceProvider(context)), context) +} + // NewAnonymousTransaction returns a new instance of a state-based transaction that embeds a single namespace and is signed // by an anonymous identity -func NewAnonymousTransaction(context view.Context) (*Transaction, error) { - fns, err := fabric.GetDefaultFNS(context) +func newAnonymousTransaction(fnsProvider *fabric.NetworkServiceProvider, context view.Context) (*Transaction, error) { + fns, err := fnsProvider.FabricNetworkService("") if err != nil { return nil, err } @@ -62,6 +71,7 @@ func NewAnonymousTransaction(context view.Context) (*Transaction, error) { return nil, errors.WithMessagef(err, "failed getting anonymous identity") } _, tx, err := endorser.NewTransactionWithSigner( + fnsProvider, context, fns.Name(), fns.ConfigService().DefaultChannel(), @@ -81,8 +91,8 @@ func NewAnonymousTransaction(context view.Context) (*Transaction, error) { }, nil } -func NewTransactionFromBytes(context view.Context, raw []byte) (*Transaction, error) { - _, tx, err := endorser.NewTransactionFromBytes(context, raw) +func NewTransactionFromBytes(fnsProvider *fabric.NetworkServiceProvider, context view.Context, raw []byte) (*Transaction, error) { + _, tx, err := endorser.NewTransactionFromBytes(fnsProvider, context, raw) if err != nil { return nil, err } @@ -97,6 +107,13 @@ type receiveTransactionView struct { party view.Identity } +func (f *receiveTransactionView) Call(context view.Context) (interface{}, error) { + return context.RunView(&ReceiveTransactionView{ + party: f.party, + fnsProvider: utils.MustGet(fabric.GetNetworkServiceProvider(context)), + }) +} + func NewReceiveTransactionView() *receiveTransactionView { return &receiveTransactionView{} } @@ -127,7 +144,13 @@ func ReceiveTransactionFrom(context view.Context, party view.Identity) (*Transac return cctx, nil } -func (f *receiveTransactionView) Call(context view.Context) (interface{}, error) { +type ReceiveTransactionView struct { + party view.Identity + + fnsProvider *fabric.NetworkServiceProvider +} + +func (f *ReceiveTransactionView) Call(context view.Context) (interface{}, error) { // Wait to receive a transaction back var ch <-chan *view.Message if f.party.IsNone() { @@ -148,7 +171,7 @@ func (f *receiveTransactionView) Call(context view.Context) (interface{}, error) if msg.Status == view.ERROR { return nil, errors.New(string(msg.Payload)) } - tx, err := NewTransactionFromBytes(context, msg.Payload) + tx, err := NewTransactionFromBytes(f.fnsProvider, context, msg.Payload) if err != nil { return nil, err } @@ -158,6 +181,21 @@ func (f *receiveTransactionView) Call(context view.Context) (interface{}, error) } } +type ReceiveTransactionViewFactory struct { + fnsProvider *fabric.NetworkServiceProvider +} + +func NewReceiveTransactionViewFactory(fnsProvider *fabric.NetworkServiceProvider) *ReceiveTransactionViewFactory { + return &ReceiveTransactionViewFactory{fnsProvider: fnsProvider} +} + +func (f *ReceiveTransactionViewFactory) New(party view.Identity) *ReceiveTransactionView { + return &ReceiveTransactionView{ + party: party, + fnsProvider: f.fnsProvider, + } +} + type sendTransactionView struct { tx *Transaction parties []view.Identity diff --git a/platform/fabric/services/state/vault/vault.go b/platform/fabric/services/state/vault/vault.go index f46141abc..fb24b2c3a 100644 --- a/platform/fabric/services/state/vault/vault.go +++ b/platform/fabric/services/state/vault/vault.go @@ -11,10 +11,9 @@ import ( "encoding/json" "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver" - driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/driver" + "github.com/hyperledger-labs/fabric-smart-client/platform/fabric" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/services/endorser" "github.com/hyperledger-labs/fabric-smart-client/platform/fabric/services/state" - driver3 "github.com/hyperledger-labs/fabric-smart-client/platform/view/driver" view2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" "github.com/pkg/errors" ) @@ -28,7 +27,7 @@ type localMembership interface { } type vault struct { - sp driver3.ServiceProvider + fnsProvider *fabric.NetworkServiceProvider network string channel string vaultStore vaultStore @@ -61,7 +60,7 @@ func (f *vault) GetStateByPartialCompositeID(ctx context.Context, ns driver.Name } func (f *vault) GetStateCertification(ctx context.Context, namespace driver.Namespace, key driver.PKey) ([]byte, error) { - _, tx, err := endorser.NewTransactionWith(ctx, f.sp, f.network, f.channel, f.localMembership.DefaultIdentity()) + _, tx, err := endorser.NewTransactionWith(f.fnsProvider, ctx, f.network, f.channel, f.localMembership.DefaultIdentity()) if err != nil { return nil, errors.Wrapf(err, "failed creating transaction [%s:%s]", namespace, key) } @@ -90,12 +89,11 @@ func (f *vault) GetStateCertification(ctx context.Context, namespace driver.Name } type service struct { - sp driver3.ServiceProvider - fnsp driver2.FabricNetworkServiceProvider + fnsp *fabric.NetworkServiceProvider } -func NewService(sp driver3.ServiceProvider, fnsp driver2.FabricNetworkServiceProvider) *service { - return &service{sp: sp, fnsp: fnsp} +func NewService(fnsp *fabric.NetworkServiceProvider) *service { + return &service{fnsp: fnsp} } func (w *service) Vault(network string, channel string) (state.Vault, error) { @@ -108,10 +106,10 @@ func (w *service) Vault(network string, channel string) (state.Vault, error) { return nil, err } return &vault{ - sp: w.sp, + fnsProvider: w.fnsp, network: fns.Name(), channel: ch.Name(), - vaultStore: ch.VaultStore(), + vaultStore: ch.Vault().Store(), localMembership: fns.LocalMembership(), }, nil } diff --git a/platform/fabric/vault.go b/platform/fabric/vault.go index e67e5f07a..0dce13b6b 100644 --- a/platform/fabric/vault.go +++ b/platform/fabric/vault.go @@ -89,14 +89,10 @@ func (r *RWSet) Equals(rws interface{}, nss ...string) error { } } -type lastTxGetter interface { - GetLast(ctx context.Context) (*driver.TxStatus, error) -} - // Vault models a key-value store that can be updated by committing rwsets type Vault struct { vault fdriver.Vault - vaultStore lastTxGetter + vaultStore fdriver.VaultStore committer fdriver.Committer transactionService fdriver.EndorserTransactionService envelopeService fdriver.EnvelopeService @@ -114,6 +110,10 @@ func newVault(ch fdriver.Channel) *Vault { } } +func (c *Vault) Store() fdriver.VaultStore { + return c.vaultStore +} + func (c *Vault) NewQueryExecutor(ctx context.Context) (driver.QueryExecutor, error) { return c.vault.NewQueryExecutor(ctx) } diff --git a/platform/view/core/manager/context.go b/platform/view/core/manager/context.go index bb9ad267d..3c4eef82c 100644 --- a/platform/view/core/manager/context.go +++ b/platform/view/core/manager/context.go @@ -24,6 +24,18 @@ import ( "go.uber.org/zap/zapcore" ) +type sigService interface { + // IsMe returns true if a signer was ever registered for the passed identity + IsMe(identity view.Identity) bool +} + +type identityProvider interface { + // DefaultIdentity returns the default identity known by this provider + DefaultIdentity() view.Identity + // Identity returns the identity bound to the passed label + Identity(label string) view.Identity +} + type ctx struct { context context.Context sp driver.ServiceProvider @@ -40,7 +52,9 @@ type ctx struct { sessions map[string]view.Session errorCallbackFuncs []func() - tracer trace.Tracer + identityProvider identityProvider + sigService sigService + tracer trace.Tracer } func (ctx *ctx) StartSpan(name string, opts ...trace.SpanStartOption) trace.Span { @@ -53,11 +67,11 @@ func (ctx *ctx) StartSpanFrom(c context.Context, name string, opts ...trace.Span return ctx.tracer.Start(c, name, opts...) } -func NewContextForInitiator(contextID string, context context.Context, sp driver.ServiceProvider, sessionFactory SessionFactory, resolver driver.EndpointService, party view.Identity, initiator view.View, tracer trace.Tracer) (*ctx, error) { +func NewContextForInitiator(contextID string, context context.Context, sp driver.ServiceProvider, sessionFactory SessionFactory, resolver driver.EndpointService, identityProvider identityProvider, sigService sigService, party view.Identity, initiator view.View, tracer trace.Tracer) (*ctx, error) { if len(contextID) == 0 { contextID = GenerateUUID() } - ctx, err := NewContext(context, sp, contextID, sessionFactory, resolver, party, nil, nil, tracer) + ctx, err := NewContext(context, sp, contextID, sessionFactory, resolver, identityProvider, sigService, party, nil, nil, tracer) if err != nil { return nil, err } @@ -66,7 +80,7 @@ func NewContextForInitiator(contextID string, context context.Context, sp driver return ctx, nil } -func NewContext(context context.Context, sp driver.ServiceProvider, contextID string, sessionFactory SessionFactory, resolver driver.EndpointService, party view.Identity, session view.Session, caller view.Identity, tracer trace.Tracer) (*ctx, error) { +func NewContext(context context.Context, sp driver.ServiceProvider, contextID string, sessionFactory SessionFactory, resolver driver.EndpointService, identityProvider identityProvider, sigService sigService, party view.Identity, session view.Session, caller view.Identity, tracer trace.Tracer) (*ctx, error) { ctx := &ctx{ context: context, id: contextID, @@ -79,7 +93,9 @@ func NewContext(context context.Context, sp driver.ServiceProvider, contextID st sp: sp, localSP: registry.New(), - tracer: tracer, + tracer: tracer, + identityProvider: identityProvider, + sigService: sigService, } if session != nil { // Register default session @@ -188,7 +204,7 @@ func (ctx *ctx) Identity(ref string) (view.Identity, error) { } func (ctx *ctx) IsMe(id view.Identity) bool { - return view2.GetSigService(ctx).IsMe(id) + return ctx.sigService.IsMe(id) } func (ctx *ctx) Caller() view.Identity { @@ -213,7 +229,7 @@ func (ctx *ctx) GetSession(f view.View, party view.Identity) (view.Session, erro logger.Debugf("session for [%s] does not exists, resolve", id.UniqueID()) } - id, _, _, err = view2.GetEndpointService(ctx).Resolve(party) + id, _, _, err = view2.NewEndpointService(ctx.resolver).Resolve(party) if err == nil { s, ok = ctx.sessions[id.UniqueID()] if logger.IsEnabledFor(zapcore.DebugLevel) { @@ -221,9 +237,9 @@ func (ctx *ctx) GetSession(f view.View, party view.Identity) (view.Session, erro } } else { // give it a second chance, check if party can be resolved as an identity - partyIdentity := view2.GetIdentityProvider(ctx).Identity(string(party)) + partyIdentity := ctx.identityProvider.Identity(string(party)) if !partyIdentity.IsNone() { - id, _, _, err = view2.GetEndpointService(ctx).Resolve(partyIdentity) + id, _, _, err = view2.NewEndpointService(ctx.resolver).Resolve(partyIdentity) if err == nil { s, ok = ctx.sessions[id.UniqueID()] if logger.IsEnabledFor(zapcore.DebugLevel) { diff --git a/platform/view/core/manager/context_test.go b/platform/view/core/manager/context_test.go index 18159e65d..5a067828d 100644 --- a/platform/view/core/manager/context_test.go +++ b/platform/view/core/manager/context_test.go @@ -16,7 +16,6 @@ import ( "github.com/hyperledger-labs/fabric-smart-client/platform/view/core/manager" mock2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/core/manager/mock" - "github.com/hyperledger-labs/fabric-smart-client/platform/view/driver" "github.com/hyperledger-labs/fabric-smart-client/platform/view/driver/mock" registry2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/registry" "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" @@ -33,22 +32,18 @@ func TestContext(t *testing.T) { registry := registry2.New() idProvider := &mock.IdentityProvider{} idProvider.DefaultIdentityReturns([]byte("alice")) - assert.NoError(t, registry.RegisterService(idProvider)) + assert.NoError(t, registry.RegisterService(&mock2.CommLayer{})) resolver := &mock.EndpointService{} resolver.GetIdentityReturns([]byte("bob"), nil) - assert.NoError(t, registry.RegisterService(resolver)) assert.NoError(t, registry.RegisterService(&mock2.SessionFactory{})) session := &mock.Session{} - ctx, err := manager.NewContext(context.TODO(), registry, "pineapple", nil, driver.GetEndpointService(registry), []byte("charlie"), session, []byte("caller"), emptyTracer) + ctx, err := manager.NewContext(context.TODO(), registry, "pineapple", nil, resolver, idProvider, nil, []byte("charlie"), session, []byte("caller"), emptyTracer) assert.NoError(t, err) // Session assert.Equal(t, session, ctx.Session()) - // GetService - assert.NotNil(t, driver.GetEndpointService(ctx)) - // Id assert.Equal(t, "pineapple", ctx.ID()) @@ -68,11 +63,9 @@ func TestContextRace(t *testing.T) { registry := registry2.New() idProvider := &mock.IdentityProvider{} idProvider.DefaultIdentityReturns([]byte("alice")) - assert.NoError(t, registry.RegisterService(idProvider)) assert.NoError(t, registry.RegisterService(&mock2.CommLayer{})) resolver := &mock.EndpointService{} resolver.GetIdentityReturns([]byte("bob"), nil) - assert.NoError(t, registry.RegisterService(resolver)) assert.NoError(t, registry.RegisterService(&mock2.SessionFactory{})) defaultSession := &mock.Session{} session := &mock.Session{} @@ -87,7 +80,7 @@ func TestContextRace(t *testing.T) { sessionFactory := &mock2.SessionFactory{} sessionFactory.NewSessionReturns(session, nil) - ctx, err := manager.NewContext(context.TODO(), registry, "pineapple", sessionFactory, resolver, []byte("charlie"), defaultSession, []byte("caller"), emptyTracer) + ctx, err := manager.NewContext(context.TODO(), registry, "pineapple", sessionFactory, resolver, idProvider, nil, []byte("charlie"), defaultSession, []byte("caller"), emptyTracer) assert.NoError(t, err) wg := &sync.WaitGroup{} diff --git a/platform/view/core/manager/manager.go b/platform/view/core/manager/manager.go index f070c472f..52d29d511 100644 --- a/platform/view/core/manager/manager.go +++ b/platform/view/core/manager/manager.go @@ -37,7 +37,8 @@ type manager struct { commLayer CommLayer endpointService driver.EndpointService - identityProvider driver.IdentityProvider + identityProvider identityProvider + sigService sigService ctx context.Context @@ -51,12 +52,13 @@ type manager struct { m *Metrics } -func New(serviceProvider driver.ServiceProvider, commLayer CommLayer, endpointService driver.EndpointService, identityProvider driver.IdentityProvider, viewProvider *registry.ViewProvider, provider trace.TracerProvider, metricsProvider metrics.Provider) *manager { +func New(serviceProvider driver.ServiceProvider, commLayer CommLayer, endpointService driver.EndpointService, identityProvider driver.IdentityProvider, sigService driver.SigService, viewProvider *registry.ViewProvider, provider trace.TracerProvider, metricsProvider metrics.Provider) *manager { return &manager{ sp: serviceProvider, commLayer: commLayer, endpointService: endpointService, identityProvider: identityProvider, + sigService: sigService, contexts: map[string]disposableContext{}, viewProvider: viewProvider, @@ -116,7 +118,7 @@ func (cm *manager) InitiateViewWithIdentity(view view.View, id view.Identity, c } ctx = trace.ContextWithSpanContext(ctx, trace.SpanContextFromContext(c)) - viewContext, err := NewContextForInitiator("", ctx, cm.sp, cm.commLayer, cm.endpointService, id, view, cm.viewTracer) + viewContext, err := NewContextForInitiator("", ctx, cm.sp, cm.commLayer, cm.endpointService, cm.identityProvider, cm.sigService, id, view, cm.viewTracer) if err != nil { return nil, err } @@ -159,7 +161,7 @@ func (cm *manager) InitiateContextFrom(ctx context.Context, view view.View, id v if id.IsNone() { id = cm.me() } - viewContext, err := NewContextForInitiator(contextID, ctx, cm.sp, cm.commLayer, cm.endpointService, id, view, cm.viewTracer) + viewContext, err := NewContextForInitiator(contextID, ctx, cm.sp, cm.commLayer, cm.endpointService, cm.identityProvider, cm.sigService, id, view, cm.viewTracer) if err != nil { return nil, err } @@ -316,7 +318,7 @@ func (cm *manager) newContext(id view.Identity, msg *view.Message) (view.Context return nil, false, err } ctx := trace.ContextWithSpanContext(cm.ctx, trace.SpanContextFromContext(msg.Ctx)) - newCtx, err := NewContext(ctx, cm.sp, contextID, cm.commLayer, cm.endpointService, id, backend, caller, cm.viewTracer) + newCtx, err := NewContext(ctx, cm.sp, contextID, cm.commLayer, cm.endpointService, cm.identityProvider, cm.sigService, id, backend, caller, cm.viewTracer) if err != nil { return nil, false, err } diff --git a/platform/view/core/manager/manager_test.go b/platform/view/core/manager/manager_test.go index 1ca99e27b..b4d766f95 100644 --- a/platform/view/core/manager/manager_test.go +++ b/platform/view/core/manager/manager_test.go @@ -63,7 +63,7 @@ func TestGetIdentifier(t *testing.T) { registry := registry2.New() idProvider := &mock.IdentityProvider{} idProvider.DefaultIdentityReturns([]byte("alice")) - manager := manager.New(registry, &mock2.CommLayer{}, &mock.EndpointService{}, idProvider, registry3.NewViewProvider(), noop.NewTracerProvider(), &disabled.Provider{}) + manager := manager.New(registry, &mock2.CommLayer{}, &mock.EndpointService{}, idProvider, nil, registry3.NewViewProvider(), noop.NewTracerProvider(), &disabled.Provider{}) assert.Equal(t, "github.com/hyperledger-labs/fabric-smart-client/platform/view/core/manager_test/DummyView", manager.GetIdentifier(DummyView{})) assert.Equal(t, "github.com/hyperledger-labs/fabric-smart-client/platform/view/core/manager_test/DummyView", manager.GetIdentifier(&DummyView{})) @@ -75,11 +75,9 @@ func TestManagerRace(t *testing.T) { registry := registry2.New() idProvider := &mock.IdentityProvider{} idProvider.DefaultIdentityReturns([]byte("alice")) - assert.NoError(t, registry.RegisterService(idProvider)) assert.NoError(t, registry.RegisterService(&mock2.CommLayer{})) - assert.NoError(t, registry.RegisterService(&mock.EndpointService{})) assert.NoError(t, registry.RegisterService(&mock2.SessionFactory{})) - manager := manager.New(registry, &mock2.CommLayer{}, &mock.EndpointService{}, idProvider, registry3.NewViewProvider(), noop.NewTracerProvider(), &disabled.Provider{}) + manager := manager.New(registry, &mock2.CommLayer{}, &mock.EndpointService{}, idProvider, nil, registry3.NewViewProvider(), noop.NewTracerProvider(), &disabled.Provider{}) wg := &sync.WaitGroup{} for i := 0; i < 100; i++ { @@ -98,8 +96,7 @@ func TestRegisterResponderWithInitiatorView(t *testing.T) { registry := registry2.New() idProvider := &mock.IdentityProvider{} idProvider.DefaultIdentityReturns([]byte("alice")) - - manager := manager.New(registry, &mock2.CommLayer{}, &mock.EndpointService{}, idProvider, registry3.NewViewProvider(), noop.NewTracerProvider(), &disabled.Provider{}) + manager := manager.New(registry, &mock2.CommLayer{}, &mock.EndpointService{}, idProvider, nil, registry3.NewViewProvider(), noop.NewTracerProvider(), &disabled.Provider{}) err := manager.RegisterResponder(&ResponderView{}, &InitiatorView{}) assert.NoError(t, err) responder, _, err := manager.ExistResponderForCaller(manager.GetIdentifier(&InitiatorView{})) @@ -115,7 +112,7 @@ func TestRegisterResponderWithViewIdentifier(t *testing.T) { idProvider := &mock.IdentityProvider{} idProvider.DefaultIdentityReturns([]byte("alice")) - manager := manager.New(registry, &mock2.CommLayer{}, &mock.EndpointService{}, idProvider, registry3.NewViewProvider(), noop.NewTracerProvider(), &disabled.Provider{}) + manager := manager.New(registry, &mock2.CommLayer{}, &mock.EndpointService{}, idProvider, nil, registry3.NewViewProvider(), noop.NewTracerProvider(), &disabled.Provider{}) err := manager.RegisterResponder(&ResponderView{}, manager.GetIdentifier(&InitiatorView{})) assert.NoError(t, err) responder, _, err := manager.ExistResponderForCaller(manager.GetIdentifier(&InitiatorView{})) diff --git a/platform/view/core/registry/viewprovider.go b/platform/view/core/registry/viewprovider.go index 30b90d64a..2d4b3c507 100644 --- a/platform/view/core/registry/viewprovider.go +++ b/platform/view/core/registry/viewprovider.go @@ -85,7 +85,7 @@ func (cm *ViewProvider) RegisterResponder(responder view.View, initiatedBy inter func (cm *ViewProvider) RegisterResponderWithIdentity(responder view.View, id view.Identity, initiatedBy interface{}) error { switch t := initiatedBy.(type) { case view.View: - cm.registerResponderWithIdentity(responder, id, cm.GetIdentifier(t)) + cm.registerResponderWithIdentity(responder, id, GetIdentifier(t)) case string: cm.registerResponderWithIdentity(responder, id, t) default: @@ -98,7 +98,7 @@ func (cm *ViewProvider) GetResponder(initiatedBy interface{}) (view.View, error) var initiatedByID string switch t := initiatedBy.(type) { case view.View: - initiatedByID = cm.GetIdentifier(t) + initiatedByID = GetIdentifier(t) case string: initiatedByID = t default: diff --git a/platform/view/driver/flowmanager.go b/platform/view/driver/flowmanager.go index 27cd12e60..dfdc55631 100644 --- a/platform/view/driver/flowmanager.go +++ b/platform/view/driver/flowmanager.go @@ -23,6 +23,8 @@ type ViewManager interface { InitiateView(view view.View, ctx context.Context) (interface{}, error) // InitiateContext initiates a new context for the passed view InitiateContext(view view.View) (view.Context, error) + // InitiateContextWithIdentity initiates a new context + InitiateContextWithIdentity(view view.View, id view.Identity) (view.Context, error) // InitiateContextWithIdentityAndID initiates a new context InitiateContextWithIdentityAndID(view view.View, id view.Identity, contextID string) (view.Context, error) // InitiateContextFrom initiates a new context for the passed view, derived from the passed context diff --git a/platform/view/driver/flowregistry.go b/platform/view/driver/flowregistry.go index 2a000b514..5e7f3a5a3 100644 --- a/platform/view/driver/flowregistry.go +++ b/platform/view/driver/flowregistry.go @@ -14,8 +14,6 @@ import ( // Registry keeps track of the available view and view factories type Registry interface { - // GetIdentifier returns the identifier of the passed view - GetIdentifier(f view.View) string // RegisterFactory binds an id to a View Factory RegisterFactory(id string, factory Factory) error diff --git a/platform/view/registry.go b/platform/view/registry.go index 6af0ef4eb..f1a021ad8 100644 --- a/platform/view/registry.go +++ b/platform/view/registry.go @@ -35,11 +35,6 @@ func NewRegistry(registry driver.Registry) *Registry { return &Registry{registry: registry} } -// GetIdentifier returns the identifier of the passed view -func (r *Registry) GetIdentifier(f View) string { - return r.registry.GetIdentifier(f) -} - // RegisterFactory binds an id to a View Factory func (r *Registry) RegisterFactory(id string, factory Factory) error { return r.registry.RegisterFactory(id, factory) diff --git a/platform/view/sdk/dig/sdk.go b/platform/view/sdk/dig/sdk.go index 212a9e830..4ebef94b5 100644 --- a/platform/view/sdk/dig/sdk.go +++ b/platform/view/sdk/dig/sdk.go @@ -66,7 +66,7 @@ func NewSDKFrom(baseSDK dig2.SDK, registry node.Registry) *SDK { sdk := &SDK{SDK: baseSDK} err := errors.Join( sdk.Container().Provide(func() node.Registry { return registry }), - sdk.Container().Provide(digutils.Identity[node.Registry](), dig.As(new(driver.ServiceProvider), new(node.Registry), new(view.ServiceProvider), new(finality.Registry))), + sdk.Container().Provide(digutils.Identity[node.Registry](), dig.As(new(driver.ServiceProvider), new(node.Registry), new(view.ServiceProvider))), sdk.Container().Provide(func() *view.ConfigService { return view.GetConfigService(registry) }), sdk.Container().Provide(digutils.Identity[*view.ConfigService](), dig.As(new(driver.ConfigService), new(id.ConfigProvider), new(endpoint.ConfigService))), sdk.Container().Provide(view.NewRegistry), @@ -158,7 +158,13 @@ func (p *SDK) Install() error { return err } - if err := p.Container().Invoke(func(resolverService *endpoint.ResolverService) error { return resolverService.LoadResolvers() }); err != nil { + err = errors.Join( + p.Container().Invoke(func(resolverService *endpoint.ResolverService) error { return resolverService.LoadResolvers() }), + p.Container().Invoke(func(r node.Registry, s driver.ViewManager) { r.RegisterViewManager(s) }), + p.Container().Invoke(func(r node.Registry, s *view.Registry) { r.RegisterViewRegistry(s) }), + ) + + if err != nil { return err } return nil diff --git a/platform/view/sdk/dig/test_utils.go b/platform/view/sdk/dig/test_utils.go index ada4f3956..c599ef351 100644 --- a/platform/view/sdk/dig/test_utils.go +++ b/platform/view/sdk/dig/test_utils.go @@ -10,6 +10,7 @@ import ( "context" "time" + "github.com/hyperledger-labs/fabric-smart-client/pkg/node" dig2 "github.com/hyperledger-labs/fabric-smart-client/platform/common/sdk/dig" "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/registry" "go.uber.org/dig" @@ -64,7 +65,7 @@ func DryRunWiringWithContainer[S dig2.SDK](decorator func(sdk dig2.SDK) S, c dig if err := provider.RegisterService(config); err != nil { return err } - viewSDK := NewSDKFrom(dig2.NewBaseSDK(c, config), provider) + viewSDK := NewSDKFrom(dig2.NewBaseSDK(c, config), &mockNodeProvider{provider}) sdk := decorator(viewSDK) if err := sdk.Install(); err != nil { return err @@ -74,3 +75,10 @@ func DryRunWiringWithContainer[S dig2.SDK](decorator func(sdk dig2.SDK) S, c dig } return nil } + +type mockNodeProvider struct { + *registry.ServiceProvider +} + +func (p *mockNodeProvider) RegisterViewManager(node.ViewManager) {} +func (p *mockNodeProvider) RegisterViewRegistry(node.ViewRegistry) {} diff --git a/platform/view/services/view/view.go b/platform/view/services/view/view.go index 8fa4cc90b..c1a9f43f9 100644 --- a/platform/view/services/view/view.go +++ b/platform/view/services/view/view.go @@ -7,7 +7,6 @@ SPDX-License-Identifier: Apache-2.0 package view import ( - view2 "github.com/hyperledger-labs/fabric-smart-client/platform/view" "github.com/hyperledger-labs/fabric-smart-client/platform/view/view" ) @@ -19,13 +18,6 @@ func RunCall(context view.Context, v func(context view.Context) (interface{}, er ) } -// Initiate initiates a new protocol whose initiator's view is the passed one. -// The execution happens in a freshly created context. -// This is a shortcut for `view.GetManager(context).InitiateView(initiator)`. -func Initiate(context view.Context, initiator view.View) (interface{}, error) { - return view2.GetManager(context).InitiateView(initiator, context.Context()) -} - // AsResponder can be used by an initiator to behave temporarily as a responder. // Recall that a responder is characterized by having a default session (`context.Session()`) established by an initiator. func AsResponder(context view.Context, session view.Session, v func(context view.Context) (interface{}, error)) (interface{}, error) {