Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .apilinter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

---
- disabled_rules:
- core::0192::only-leading-comments # Forbid inline comments
- core::0192::has-comments # Required comment in every service, message, and field
- core::0141::forbidden-types # E.g., uint is forbidden
- core::0215::versioned-packages # E.g., applicationpb.v1
- core::0131::method-signature # A google.api.method_signature annotation should be present
- core::0215::foreign-type-reference # We require foreign types.
- core::0127::http-annotation # HTTP annotations (might be added in the future)
- core::0203::field-behavior-required # E.g., [(google.api.field_behavior) = REQUIRED]
- core::0123::resource-annotation # Forces resources annotation (not applicable)
# Enforces connection between method names to the request/reposne message name.
- core::0136::response-message-name
- core::0131::response-message-name
- core::0136::request-message-name
- core::0131::request-message-name
# Grammar related issues (e.g., forbid use "of" and "with").
- core::0140::prepositions
- core::0136::prepositions
- core::0134::synonyms
- core::0216::synonyms
# Java related issues (might be addressed in the future if required)
- core::0191::java-multiple-files
- core::0191::java-package
- core::0191::java-outer-classnam
- core::0191::java-outer-classname
39 changes: 26 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ GO_TAGS ?=

go_cmd ?= go
go_test ?= $(go_cmd) test -json -v -timeout 30m
project_dir := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
proto_flags ?=

ifneq ("$(wildcard /usr/include)","")
proto_flags += --proto_path="/usr/include"
endif

TOOLS_EXES = configtxgen configtxlator cryptogen

Expand Down Expand Up @@ -58,7 +64,7 @@ $(BUILD_DIR)/%:
clean: ## Cleans the build area
-@rm -rf $(BUILD_DIR)

lint: FORCE
lint: lint-proto FORCE
@echo "Running Go Linters..."
golangci-lint run --color=always --new-from-rev=main --timeout=4m
@echo "Running License Header Linters..."
Expand All @@ -74,28 +80,35 @@ FORCE:
# Generate protos
#########################

PROTO_TARGETS ?= $(shell find ./api \
-name '*.proto' -print0 | \
xargs -0 -n 1 dirname | xargs -n 1 basename | \
sort -u | sed -e "s/^proto/proto-/" \
)

BUILD_DIR := .build
PROTOS_REPO := https://github.com/hyperledger/fabric-protos.git
PROTOS_DIR := $(BUILD_DIR)/fabric-protos
# We depend on this specific file to ensure the repo is actually cloned
PROTOS_SENTINEL := $(PROTOS_DIR)/.git

proto: $(PROTOS_SENTINEL)
@echo "==> Compiling protos..."
protoc \
-I=. \
proto: FORCE $(PROTOS_SENTINEL)
@echo "Generating protobufs: $(shell find ${project_dir}/api -name '*.proto' -print0 \
| xargs -0 -n 1 dirname | xargs -n 1 basename | sort -u)"
@protoc \
-I=${project_dir} \
-I=$(PROTOS_DIR) \
--go_opt=Mmsp/msp_config.proto=github.com/hyperledger/fabric-protos-go-apiv2/msp \
--go-grpc_opt=Mmsp/msp_config.proto=github.com/hyperledger/fabric-protos-go-apiv2/msp \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
--go-grpc_out=. \
--go-grpc_opt=paths=source_relative \
--go_out=paths=source_relative:. \
./api/*/*.proto
${proto_flags} \
${project_dir}/api/*/*.proto

lint-proto: FORCE $(PROTOS_SENTINEL)
@echo "Running protobuf linters..."
@api-linter \
-I="${project_dir}/api" \
-I="$(PROTOS_DIR)" \
--config .apilinter.yaml \
--set-exit-status \
--output-format github \
$(shell find ${project_dir}/api -name '*.proto' -exec realpath --relative-to ${project_dir}/api {} \;)

$(PROTOS_SENTINEL):
@mkdir -p $(BUILD_DIR)
Expand Down
108 changes: 108 additions & 0 deletions api/applicationpb/asn1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package applicationpb

import (
"encoding/asn1"

"github.com/cockroachdb/errors"
)

// ASN1Marshal marshals a transactions for a given namespace index.
// It uses the schema described in asn1_tx_schema.asn.
func (ns *TxNamespace) ASN1Marshal(txID string) ([]byte, error) {
ret, err := asn1.Marshal(*ns.translate(txID))
return ret, errors.Wrap(err, "failed to marshal tx namespace")
}

// translate translates a [TxNamespace] to a stab struct for asn1_tx_schema.asn.
// Any change to [TxNamespace] requires a change to this method.
func (ns *TxNamespace) translate(txID string) *asn1Namespace {
n := asn1Namespace{
TxID: txID,
NamespaceID: ns.NsId,
NamespaceVersion: protoToAsnVersion(&ns.NsVersion),
ReadsOnly: make([]asn1Read, len(ns.ReadsOnly)),
ReadWrites: make([]asn1ReadWrite, len(ns.ReadWrites)),
BlindWrites: make([]asn1Write, len(ns.BlindWrites)),
}
for i, r := range ns.ReadsOnly {
n.ReadsOnly[i] = asn1Read{
Key: r.Key,
Version: protoToAsnVersion(r.Version),
}
}
for i, rw := range ns.ReadWrites {
n.ReadWrites[i] = asn1ReadWrite{
Key: rw.Key,
Version: protoToAsnVersion(rw.Version),
Value: rw.Value,
}
}
for i, w := range ns.BlindWrites {
n.BlindWrites[i] = asn1Write{
Key: w.Key,
Value: w.Value,
}
}
return &n
}

// protoToAsnVersion converts the proto version to ASN.1 version.
// ASN.1 uses -1 to encode nil version.
func protoToAsnVersion(ver *uint64) int64 {
if ver == nil {
return -1
}
return int64(*ver) //nolint:gosec // ASN.1 does not support unsigned numbers.
}

// asnToProtoVersion converts the ASN.1 version to proto version.
// ASN.1 uses -1 to encode nil version.
func asnToProtoVersion(ver int64) *uint64 {
if ver < 0 {
return nil
}
protoVer := uint64(ver)
return &protoVer
}

type (
// asn1Namespace is a stab for [Tx] and [TxNamespace].
// Any change to these protobuf requires a change to these structures.
// It conforms with asn1_tx_schema.asn.
// We force the ASN.1 library to use UTF8 strings to avoid incompatibility with the schema.
// If not specified, the library choose to use ASCII (PrintableString) for simple strings,
// and UTF8 otherwise.
asn1Namespace struct {
TxID string `asn1:"utf8"`
NamespaceID string `asn1:"utf8"`
NamespaceVersion int64
ReadsOnly []asn1Read
ReadWrites []asn1ReadWrite
BlindWrites []asn1Write
}
// asn1Read is a stab for [Read].
// Any change to this protobuf requires a change to these structures.
asn1Read struct {
Key []byte
Version int64 `asn1:"optional,default:-1"`
}
// asn1ReadWrite is a stab for [ReadWrite].
// Any change to this protobuf requires a change to these structures.
asn1ReadWrite struct {
Key []byte
Value []byte
Version int64 `asn1:"optional,default:-1"`
}
// asn1Write is a stab for [Write].
// Any change to this protobuf requires a change to these structures.
asn1Write struct {
Key []byte
Value []byte
}
)
Loading