Skip to content

feat: migrate to fabric-chaincode-go/v2 and release as cc-tools/v2 - #57

Open
PsychoPunkSage wants to merge 1 commit into
hyperledger-labs:mainfrom
PsychoPunkSage:feat/fabric-chaincode-go-v2
Open

PsychoPunkSage wants to merge 1 commit into
hyperledger-labs:mainfrom
PsychoPunkSage:feat/fabric-chaincode-go-v2

Conversation

@PsychoPunkSage

Copy link
Copy Markdown

What

Retargets cc-tools from the 2021-era Fabric Go packages to their current successors, and moves the module to the /v2 path:

before after
module github.com/hyperledger-labs/cc-tools github.com/hyperledger-labs/cc-tools/v2
shim fabric-chaincode-go v0.0.0-20210603161043 fabric-chaincode-go/v2 v2.3.0
protos fabric-protos-go v0.0.0-20210528200356 fabric-protos-go-apiv2 v0.3.7
protobuf github.com/golang/protobuf google.golang.org/protobuf
go 1.21 1.22

Closes #56

Why

Consumers that have migrated to fabric-chaincode-go/v2 cannot use cc-tools at all. The v1 and v2 module lines are distinct types to the Go compiler, so tx.Run(stub) and TxError.GetErrorResponse() reject v2 values. This surfaced in Hyperledger Fabric Private Chaincode, where the confidential-escrow sample stopped building after FPC's v2 migration. It isn't fixable at the call site, since the signatures are cc-tools'.

Breaking changes

This is why it needs /v2 rather than a patch release:

  • ICCError.GetErrorResponse() now returns *peer.Response instead of peer.Response. Required because shim v2's Invoke returns *peer.Response, so the common response = err.GetErrorResponse() pattern needs a pointer. protobuf-go v2 messages also shouldn't be copied by value.
  • MockStub.MockInit, MockInvoke, MockInvokeWithSignedProposal, InvokeChaincode return *pb.Response.
  • MockStub.TxTimestamp is *timestamppb.Timestamp instead of *timestamp.Timestamp.

Existing users are unaffected. Under semantic import versioning cc-tools/v2 is a separate module, so anything pinned at v1.0.x keeps resolving v1.0.x.

Changes

  • go.mod: module path, Go 1.22, dependency swap.
  • All packages (79 files): internal imports rewritten to cc-tools/v2/..., and Fabric imports to fabric-chaincode-go/v2/... and fabric-protos-go-apiv2/.... Mechanical.
  • errors/errors.go: GetErrorResponse() returns a pointer.
  • mock/mockstub.go: protobuf v1 to v2 API (ptypes.TimestampNow() becomes timestamppb.Now()), pointer responses, and five methods added to satisfy the v2 ChaincodeStubInterface:
    • GetMultipleStates and GetMultiplePrivateData, implemented by looping the single-key getter
    • GetAllStatesCompositeKeyWithPagination, returns nil, nil, nil to match the existing *WithPagination stubs
    • StartWriteBatch and FinishWriteBatch, no-ops since MockStub doesn't batch
  • .github/workflows/go.yml: Go 1.21 to 1.22. Required, because fabric-chaincode-go/v2 declares go 1.22.0 and CI images pin GOTOOLCHAIN=local, so 1.21 hard-refuses rather than fetching a newer toolchain.

Compatibility with older Fabric peers

Checked before proposing this, since cc-tools has users on older peers. Full write-up: hyperledger/fabric-private-chaincode#957 (comment)

Summary:

  1. ChaincodeMessage.Type values 0-22 are identical between fabric-protos-go and -apiv2, with the same names, same numbers, and nothing renumbered or removed. Protobuf encoding depends only on those numbers, so the wire bytes are unchanged. The v1 to v2 move is Go codegen, not protocol.
  2. The three added message types are gated. PURGE_PRIVATE_DATA (23) and GET_STATE_MULTIPLE (25) are only emitted from their opt-in stub methods. WRITE_BATCH_STATE (24) is negotiated: the shim reads ChaincodeAdditionalParams from the peer's REGISTERED payload, and an older peer that predates the field leaves UseWriteBatch false, so writes go out as ordinary PUT_STATE. Upstream tests this in stub_test.go under "WriteBatch - Old peer (usePeerWriteBatch false)".
  3. cc-tools calls none of the newer-peer methods outside MockStub.

So runtime behaviour against older peers is unchanged. The one real constraint is the build toolchain: chaincode using this will need a Go 1.22 or newer build path, which means a newer ccenv in core.yaml or an external builder for anyone on an older peer's default build image.

Testing

  • go build ./..., go vet ./..., go test ./... all pass
  • Existing test suite unchanged and green. No tests were modified to accommodate the migration.

Notes and possible follow-ups

  • github.com/hyperledger/fabric v2.1.1+incompatible is still a direct dependency, used only for util.ComputeSHA256 in stubwrapper. It's +incompatible so it contributes no transitive requirements and doesn't reintroduce v1 protos. I left it alone to keep this PR to the migration, but it could be dropped for crypto/sha256 separately.
  • doc.go is flagged by newer gofmt. Pre-existing, untouched here.
  • Happy to adjust the approach if you'd prefer the v1 line maintained on a branch alongside v2.

Signed-off-by: Abhinav Prakash <abhinav.prakash319@gmail.com>
@samuelvenzi

Copy link
Copy Markdown
Member

Hey @PsychoPunkSage, this looks good overall. I'm just running some tests on cc-tools-demo with this code before proceeding with the approval

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

Successfully merging this pull request may close these issues.

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

2 participants