diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml index 114bbca..6c989bf 100644 --- a/.github/workflows/proto.yml +++ b/.github/workflows/proto.yml @@ -1,5 +1,5 @@ name: Protobuf -# Protobuf runs buf (https://buf.build/) lint and check-breakage +# Protobuf runs buf[](https://buf.build/) lint and check-breakage # This workflow is only run when a .proto file has been changed on: pull_request: @@ -14,10 +14,21 @@ jobs: timeout-minutes: 5 steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - uses: technote-space/get-diff-action@f27caffdd0fb9b13f4fc191c016bb4e0632844af # v6 with: PATTERNS: | **/**.proto + - uses: bufbuild/buf-setup-action@v1 + with: + version: 1.41.0 + github_token: ${{ secrets.GITHUB_TOKEN }} + - name: Update Buf Dependencies + if: env.GIT_DIFF + run: | + cd proto + buf dep update - name: lint run: make proto-lint if: env.GIT_DIFF @@ -25,25 +36,67 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - uses: technote-space/get-diff-action@f27caffdd0fb9b13f4fc191c016bb4e0632844af # v6 with: PATTERNS: | **/**.proto + - name: Check if proto files exist on base branch + id: check_base_proto + if: env.GIT_DIFF + run: | + if git ls-tree -r origin/${{ github.event.pull_request.base.ref }} -- proto | grep -q '\.proto$'; then + echo "has_proto=true" >> $GITHUB_OUTPUT + else + echo "has_proto=false" >> $GITHUB_OUTPUT + fi + - uses: bufbuild/buf-setup-action@v1 + if: env.GIT_DIFF && steps.check_base_proto.outputs.has_proto == 'true' + with: + version: 1.41.0 + github_token: ${{ secrets.GITHUB_TOKEN }} + - name: Update Buf Dependencies + if: env.GIT_DIFF && steps.check_base_proto.outputs.has_proto == 'true' + run: | + cd proto + buf dep update - name: check-breakage + if: env.GIT_DIFF && steps.check_base_proto.outputs.has_proto == 'true' run: make proto-check-breaking - if: env.GIT_DIFF + env: + BUF_BREAKING_AGAINST: origin/${{ github.event.pull_request.base.ref }} protogen: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - uses: technote-space/get-diff-action@f27caffdd0fb9b13f4fc191c016bb4e0632844af # v6 with: PATTERNS: | **/**.proto + - uses: bufbuild/buf-setup-action@v1 + with: + version: 1.41.0 + github_token: ${{ secrets.GITHUB_TOKEN }} + - name: Install Go + if: env.GIT_DIFF + uses: actions/setup-go@v5 + with: + go-version: '1.21' + - name: Install Proto Plugins + if: env.GIT_DIFF + run: go install github.com/cosmos/gogoproto/protoc-gen-gogofaster@v1.7.2 + - name: Update Buf Dependencies + if: env.GIT_DIFF + run: | + cd proto + buf dep update - name: proto-gen-ci if: env.GIT_DIFF run: | make proto-gen-ci # proto-swagger-gen FIXME swagger-gen result is not reproducible in CI - git checkout -- go.mod go.sum # FIXME doc gen not reproducible in CI + # Removed: git checkout -- go.mod go.sum # FIXME doc gen not reproducible in CI - name: check working directory is clean - uses: numtide/clean-git-action@30e3d6d6e2d6e77e73761cf5324467cb74386f87 # v2 + uses: numtide/clean-git-action@30e3d6d6e2d6e77e73761cf5324467cb74386f87 # v2 \ No newline at end of file diff --git a/Makefile b/Makefile index bc59e78..37cdcb5 100644 --- a/Makefile +++ b/Makefile @@ -1,31 +1,46 @@ COVERAGE ?= coverage.txt - -.PHONY: all build test clean +GO ?= go +GOBIN ?= $(shell $(GO) env GOBIN) +ifeq ($(strip $(GOBIN)),) +GOBIN := $(shell $(GO) env GOPATH)/bin +endif +BUF_VERSION ?= v1.41.0 +BUF_BIN ?= $(GOBIN)/buf +PROTO_DIR ?= proto +BUF_BREAKING_AGAINST ?= origin/main + +BUF := $(shell command -v buf 2>/dev/null) +ifeq ($(strip $(BUF)),) +BUF := $(BUF_BIN) +endif + +.PHONY: all build test clean fmt vet \ + proto-lint proto-gen proto-gen-ci proto-check-breaking buf-install all: build build: build-memiavl build-store build-versiondb build-memiavl: - @cd memiavl && go build -mod=readonly -tags=objstore ./... + @cd memiavl && $(GO) build -mod=readonly -tags=objstore ./... build-store: - @cd store && go build -mod=readonly -tags=objstore ./... + @cd store && $(GO) build -mod=readonly -tags=objstore ./... build-versiondb: - @cd versiondb && go build -mod=readonly -tags=objstore ./... + @cd versiondb && $(GO) build -mod=readonly -tags=objstore ./... test: test-memiavl test-store test-versiondb test-memiavl: - @cd memiavl && go test -tags=objstore -v -mod=readonly ./... -coverprofile=$(COVERAGE) -covermode=atomic; + @cd memiavl && $(GO) test -tags=objstore -v -mod=readonly ./... -coverprofile=$(COVERAGE) -covermode=atomic; test-store: - @cd store && go test -tags=objstore -v -mod=readonly ./... -coverprofile=$(COVERAGE) -covermode=atomic; + @cd store && $(GO) test -tags=objstore -v -mod=readonly ./... -coverprofile=$(COVERAGE) -covermode=atomic; test-versiondb: - @cd versiondb && go test -tags=objstore -v -mod=readonly ./... -coverprofile=$(COVERAGE) -covermode=atomic; + @cd versiondb && $(GO) test -tags=objstore -v -mod=readonly ./... -coverprofile=$(COVERAGE) -covermode=atomic; clean: clean-memiavl clean-store clean-versiondb @@ -36,10 +51,27 @@ clean-store: @cd store && go clean clean-versiondb: - @cd versiondb && go clean + @cd versiondb && $(GO) clean fmt: - go fmt ./memiavl/... ./store/... ./versiondb/... + $(GO) fmt ./memiavl/... ./store/... ./versiondb/... vet: - go vet ./memiavl/... ./store/... ./versiondb/... \ No newline at end of file + $(GO) vet ./memiavl/... ./store/... ./versiondb/... + +buf-install: + @if ! command -v buf >/dev/null 2>&1 && [ ! -x "$(BUF_BIN)" ]; then \ + echo "Installing buf $(BUF_VERSION)"; \ + GOBIN=$(GOBIN) $(GO) install github.com/bufbuild/buf/cmd/buf@$(BUF_VERSION); \ + fi + +proto-lint: buf-install + $(BUF) lint $(PROTO_DIR) --config $(PROTO_DIR)/buf.yaml + +proto-gen: buf-install + $(BUF) generate $(PROTO_DIR) --template $(PROTO_DIR)/buf.gen.yaml + +proto-gen-ci: proto-gen + +proto-check-breaking: buf-install + $(BUF) breaking $(PROTO_DIR) --against ".git#branch=$(BUF_BREAKING_AGAINST),subdir=$(PROTO_DIR)" --config $(PROTO_DIR)/buf.yaml diff --git a/proto/buf.gen.yaml b/proto/buf.gen.yaml new file mode 100644 index 0000000..911e1db --- /dev/null +++ b/proto/buf.gen.yaml @@ -0,0 +1,10 @@ +version: v1 +managed: + enabled: true + go_package_prefix: + default: github.com/crypto-org-chain/cronos-store +plugins: + - name: gogofaster # Changed from 'plugin: buf.build/community/gogo/protoc-gen-gogofaster' + out: . + opt: + - paths=source_relative diff --git a/proto/buf.yaml b/proto/buf.yaml new file mode 100644 index 0000000..7b773de --- /dev/null +++ b/proto/buf.yaml @@ -0,0 +1,18 @@ +version: v1 + +name: buf.build/crypto-org-chain/cronos-store + +deps: + - buf.build/cosmos/gogo-proto + +lint: + use: + - STANDARD + except: + - PACKAGE_VERSION_SUFFIX + - PACKAGE_SAME_DIRECTORY + - PACKAGE_DIRECTORY_MATCH + +breaking: + use: + - FILE diff --git a/proto/memiavl/changeset.proto b/proto/memiavl/changeset.proto new file mode 100644 index 0000000..c7d8a76 --- /dev/null +++ b/proto/memiavl/changeset.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package memiavl; + +option go_package = "github.com/crypto-org-chain/cronos-store/memiavl"; + +import "gogoproto/gogo.proto"; + +// KVPair represents a key-value pair in a change set. +message KVPair { + bool delete = 1; + bytes key = 2; + bytes value = 3; +} + +// ChangeSet represents a list of key-value updates. +message ChangeSet { + repeated KVPair pairs = 1 [(gogoproto.nullable) = false]; +} diff --git a/proto/memiavl/commit_info.proto b/proto/memiavl/commit_info.proto new file mode 100644 index 0000000..9e2dc5e --- /dev/null +++ b/proto/memiavl/commit_info.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +package memiavl; + +option go_package = "github.com/crypto-org-chain/cronos-store/memiavl"; + +import "gogoproto/gogo.proto"; + +// CommitInfo defines commit information used by the multi-store when committing a version. +message CommitInfo { + int64 version = 1; + repeated StoreInfo store_infos = 2 [(gogoproto.nullable) = false]; +} + +// StoreInfo defines store-specific commit information. +message StoreInfo { + string name = 1; + CommitID commit_id = 2 [(gogoproto.nullable) = false]; +} + +// CommitID defines the commitment information for a specific store. +message CommitID { + int64 version = 1; + bytes hash = 2; +} diff --git a/proto/memiavl/kv.proto b/proto/memiavl/kv.proto new file mode 100644 index 0000000..3d630fe --- /dev/null +++ b/proto/memiavl/kv.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package memiavl; + +option go_package = "github.com/crypto-org-chain/cronos-store/memiavl"; + +import "gogoproto/gogo.proto"; + +// Pairs defines a repeated slice of Pair objects. +message Pairs { + repeated Pair pairs = 1 [(gogoproto.nullable) = false]; +} + +// Pair defines a key/value bytes tuple. +message Pair { + bytes key = 1; + bytes value = 2; +} diff --git a/proto/memiavl/wal.proto b/proto/memiavl/wal.proto new file mode 100644 index 0000000..c3759cb --- /dev/null +++ b/proto/memiavl/wal.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package memiavl; + +option go_package = "github.com/crypto-org-chain/cronos-store/memiavl"; + +import "gogoproto/gogo.proto"; +import "memiavl/changeset.proto"; + +// NamedChangeSet combines a tree name with the associated change set. +message NamedChangeSet { + ChangeSet changeset = 1 [(gogoproto.nullable) = false]; + string name = 2; +} + +// TreeNameUpgrade defines upgrade operations on tree names. +message TreeNameUpgrade { + string name = 1; + string rename_from = 2; + bool delete = 3; +} + +// WALEntry represents a single write-ahead log entry. +message WALEntry { + repeated NamedChangeSet changesets = 1; + repeated TreeNameUpgrade upgrades = 2; +}