Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to convert proto encoded buffer using new protobuf library "google.golang.org/protobuf" #181

Closed
Tej81r opened this issue Apr 11, 2023 · 11 comments

Comments

@Tej81r
Copy link

Tej81r commented Apr 11, 2023

Hi team,

We use proto from the protobuf lib in our Golang chain codes to unmarshal the "stub.GetCreator()" result. First, we create an instance of the Serailizedidentity from "github.com/hyperledger/fabric-protos-go/msp" to hold the Unmarshall result from "stub.GetCreator()" and then unmarshall it using proto.

creator, err := stub.GetCreator()
if err != nil {
    return nil, err
}
    //Create a SerializedIdentity to hold Unmarshal GetCreator() result
sId := &msp.SerializedIdentity{}
//Unmarshal the creator from []byte to structure
err := proto.Unmarshal(creator, sId)
if err != nil {
    return nil, err
}

Our product is enterprise edition, and we are not permitted by our company to use deprecated packages. So I tried to use the new protobuf, which is not deprecated and is recommended by the protobuf team, i.e. "google.golang.org/protobuf."
I am getting the following error:

"cannot use sId (variable of type msp.SerializedIdentity) as protoreflect.ProtoMessage value in argument to proto.Unmarshal:msp.SerializedIdentity does not implement protoreflect.ProtoMessage (missing method ProtoReflect)compilerInvalidIfaceAssign
var sId *msp.SerializedIdentity"

I believe the old "protoc" written by "github.com/golang/protobuf" is used to generate the go code for proto files i.e "identities.pb.go" file. We are unable to unmarshall the serailize data from "stub.Creator()" to msp.SerailizeIdentity using the most recent protobuf "google.golang.org/protobuf/proto" due to "identities.pb.go" file generated using protoc of a deprecated version. Is there any way to use the new protobuf "google.golang.org/protobuf" lib to unmarshal the serialised data from "stub.Creator()" using fabric-protos-go/msp, or is there any plan to update fabric-protos-go in the future so that identities.pb.go generated by "google.golang.org/protobuf"?

@bestbeforetoday
Copy link
Member

Go bindings for the Fabric protobufs generated using the newer Go protobuf API are published as hyperledger/fabric-photos-apiv2. See docs for details:

https://hyperledger.github.io/fabric-protos/

It is possible that referencing both versions of the Fabric Go protobuf bindings in the same project might cause a protobuf namespace conflict. You might have to try it and see.

@Tej81r
Copy link
Author

Tej81r commented Apr 13, 2023 via email

@bestbeforetoday
Copy link
Member

fabric-photos-go-apiv2 is just generated using the protoc compiler from the same protobuf definitions (in this repository) as fabric-protos-go. To generate different output would require different input.

I think modifying the protobuf message definition - either the message or package name - and generating new bindings, as you have done, is probably the most pragmatic approach to get you running. No breaking changes should be introduced into the protobufs so I think you should be pretty safe doing this.

@Tej81r
Copy link
Author

Tej81r commented Apr 14, 2023

Thanks, @bestbeforetoday. Is it planned to update the "pb.go" files in the "fabric-protos-go" package in the future with the new protoc compiler developed by "google.golang.org/protobuf"?
Is there another way to overcome the namespace-conflict problem in my chain code without introducing the "pb.go" file by modifying the message and package names?

@bestbeforetoday
Copy link
Member

The fabric-protos-go package continues to use the deprecated protoc compiler and Go protocol buffer API precisely because of the incompatibilities you've hit. fabric-protos-go-apiv2 is the equivalent using the new protoc compiler and v2 Go protocol buffer API.

My understanding is that the namespace conflict is a limitation of the global registry used by the Go protobuf implementation. Unless the Go protobuf implementation can fix it, I'm not sure there is other workaround. At least not that I know of, but somebody else might have better information.

@jt-nti
Copy link
Member

jt-nti commented Apr 17, 2023

I think the best long term solution would be to update fabric-chaincode-go to use fabric-protos-go-apiv2. (Would that count as a breaking change?)

Until that happens it probably makes sense to just carry on using fabric-protos-go since the deprecated protobuf API is presumably getting pulled in by fabric-chaincode-go anyway?

@bestbeforetoday
Copy link
Member

I agree that updating fabric-chaincode-go (and also fabric-contract-api-go) to use fabric-protos-go-apiv2 would be a good approach. With the potential for mixing different protobuf bindings in the same project to cause failures, perhaps releasing those packages (using the v2 protobuf API) at v2.x would be sensible, with the current (v1.x) releases sticking with fabric-protos-go.

@davidkhala
Copy link

@bestbeforetoday I would like to nominate myself to help on the apiv2 creation, while I am also suffering from this issue.

@jt-nti
Copy link
Member

jt-nti commented Jan 15, 2024

@davidkhala it looks like there's already a draft PR for fabric-chaincode-go: hyperledger/fabric-chaincode-go#84

@denyeart
Copy link
Contributor

I commented in the main fabric APIv2 issue.

I would be in favor of updating all fabric repositories to APIv2 before Fabric v3 gets released (including Go chaincode repositories), if somebody tests and successfully proves that having a mixed set of Fabric v2.x orderers and peers (old protobuf) and new v3.x orderers and peers (new APIv2) works seamlessly. Any volunteers?

@bestbeforetoday
Copy link
Member

There is now a github.com/hyperledger/fabric-chaincode-go/v2 and an accompanying github.com/hyperledger/fabric-contract-api-go/v2 that both use fabric-protos-go-apiv2, which in turn uses google.golang.org/protobuf. Smart contract implementors can choose whether they want to work with the older or newer protobuf APIs by selecting the appropriate chaincode API version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants