Skip to content

Support fabric-chaincode-go/v2 + fabric-protos-go-apiv2 (release as cc-tools/v2) #56

Description

@PsychoPunkSage

Is your feature request related to a problem? Please describe.

cc-tools is currently typed against the pre-v2 Fabric Go packages:

github.com/hyperledger/fabric-chaincode-go v0.0.0-20210603161043-af0e3898842a
github.com/hyperledger/fabric-protos-go    v0.0.0-20210528200356-82833ecdac31

This blocks any consumer that has migrated to fabric-chaincode-go/v2 + fabric-protos-go-apiv2, because the two module lines are distinct types to the Go compiler and cannot be mixed.

Concretely, this surfaced in Hyperledger Fabric Private Chaincode. The confidential-escrow sample uses cc-tools, and after FPC's v1 -> v2 migration it no longer builds:

chaincode/escrow.go:60:14: cannot use err.GetErrorResponse() (value of struct type
  "github.com/hyperledger/fabric-protos-go/peer".Response) as
  "github.com/hyperledger/fabric-protos-go-apiv2/peer".Response value in assignment

chaincode/escrow.go:99:24: cannot use stub (variable of interface type
  "github.com/hyperledger/fabric-chaincode-go/v2/shim".ChaincodeStubInterface) as
  "github.com/hyperledger/fabric-chaincode-go/shim".ChaincodeStubInterface
  value in argument to tx.Run

The mismatch is inside cc-tools' own signatures (tx.Run(...), TxError.GetErrorResponse()), so it isn't fixable at the consumer's call sites. I checked every published tag through v1.0.3 and all still pin the 2021-era v1 pseudo-versions.

Describe the solution you'd like

Retarget cc-tools to fabric-chaincode-go/v2 + fabric-protos-go-apiv2 and release it under the github.com/hyperledger-labs/cc-tools/v2 module path.

The /v2 path matters: several signatures change shape, not just import path, e.g. Init / Invoke / InvokeChaincode return *peer.Response instead of pb.Response by value, and GetTxTimestamp returns *timestamppb.Timestamp. That's a breaking API change, so semantic import versioning requires a new major path. It also means existing users are entirely unaffected: projects pinned at v1.0.x keep resolving v1.0.x and never see v2. The v1 line can stay alive alongside it, the same approach fabric-chaincode-go itself took.

Describe alternatives you've considered

  • Fork/patch cc-tools locally in FPC: works, but fragments the ecosystem and leaves FPC carrying a permanent downstream patch.
  • Exclude confidential-escrow from the build: defers the problem; the sample stays dead and any other v2 consumer hits the same wall.
  • Keep everything on v1: not viable for FPC, which now targets Fabric 3.1.x.

Additional context

Before proposing this I checked whether a v2 move would break deployments on older peers (notably Fabric 2.2), since cc-tools has downstream users there. Full write-up in the FPC thread: hyperledger/fabric-private-chaincode#957 (comment)

Summary of the findings:

  1. Wire format is unchanged. Diffing the ChaincodeMessage.Type enum between fabric-protos-go v0.0.0-20210528200356 and fabric-protos-go-apiv2 v0.3.7, values 0-22 are identical i.e. same names, same numbers, nothing renumbered or removed. Only three additions: PURGE_PRIVATE_DATA (23), WRITE_BATCH_STATE (24), GET_STATE_MULTIPLE (25). Since protobuf encoding depends only on field/enum numbers, -apiv2 produces byte-identical messages for every pre-existing type. The v1 -> v2 change is Go codegen (gogo -> google.golang.org/protobuf), not protocol.

  2. The new message types are all gated. PURGE_PRIVATE_DATA and GET_STATE_MULTIPLE are only emitted from stub.PurgePrivateData() / stub.GetMultipleStates(), opt-in. WRITE_BATCH_STATE is negotiated, not assumed: on REGISTERED the shim reads ChaincodeAdditionalParams from the peer's payload (handler.go:801-811) and sets usePeerWriteBatch. An older peer predates that field, replies with an empty payload, the flag defaults to false, and writes go out as ordinary PUT_STATE. Upstream tests this case explicitly (stub_test.go:647, "WriteBatch - Old peer (usePeerWriteBatch false)"), so old-peer compatibility is a deliberate, tested guarantee in the shim.

  3. Only three of six new APIs carry a newer-peer requirement. Diffing ChaincodeStubInterface: GetAllStatesCompositeKeyWithPagination is a convenience wrapper over GET_STATE_BY_RANGE (14, present since 1.x) and StartWriteBatch / FinishWriteBatch are gated by the flag above, all safe. PurgePrivateData (2.5+), GetMultipleStates and GetMultiplePrivateData (3.0) are the ones to avoid. No methods were removed, so cc-tools loses no API it depends on.

  4. cc-tools doesn't call any of them. The only hit is mock/mockstub.go (MockStub.PurgePrivateData), an interface-satisfaction stub operating on the in-memory map, never sending a ChaincodeMessage, only reachable under go test. Zero hits for GetMultipleStates, GetMultiplePrivateData, StartWriteBatch, or FinishWriteBatch.

So the port looks mechanical rather than semantic, and shouldn't change runtime behaviour against older peers, provided production paths continue to avoid those three methods. That's worth a note in CONTRIBUTING or a lint rule if older-peer support is a maintained guarantee rather than best-effort.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions