@ -1,17 +1,19 @@ | |||
name: Check Markdown links | |||
# TODO: Re-enable when https://github.com/gaurav-nelson/github-action-markdown-link-check/pull/126 lands. | |||
on: | |||
push: | |||
branches: | |||
- master | |||
pull_request: | |||
branches: [master] | |||
jobs: | |||
markdown-link-check: | |||
runs-on: ubuntu-latest | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- uses: gaurav-nelson/github-action-markdown-link-check@1.0.13 | |||
with: | |||
check-modified-files-only: 'yes' | |||
#name: Check Markdown links | |||
# | |||
#on: | |||
# push: | |||
# branches: | |||
# - master | |||
# pull_request: | |||
# branches: [master] | |||
# | |||
#jobs: | |||
# markdown-link-check: | |||
# runs-on: ubuntu-latest | |||
# steps: | |||
# - uses: actions/checkout@v3 | |||
# - uses: gaurav-nelson/github-action-markdown-link-check@v1.0.13 | |||
# with: | |||
# check-modified-files-only: 'yes' |
@ -1,24 +0,0 @@ | |||
name: Proto Check | |||
# Protobuf runs buf (https://buf.build/) lint and check-breakage | |||
# This workflow is only run when a file in the proto directory | |||
# has been modified. | |||
on: | |||
workflow_dispatch: # allow running workflow manually | |||
pull_request: | |||
paths: | |||
- "proto/*" | |||
jobs: | |||
proto-lint: | |||
runs-on: ubuntu-latest | |||
timeout-minutes: 4 | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- name: lint | |||
run: make proto-lint | |||
proto-breakage: | |||
runs-on: ubuntu-latest | |||
timeout-minutes: 4 | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- name: check-breakage | |||
run: make proto-check-breaking-ci |
@ -1,64 +0,0 @@ | |||
# This workflow (re)builds and pushes a Docker image containing the | |||
# protobuf build tools used by the other workflows. | |||
# | |||
# When making changes that require updates to the builder image, you | |||
# should merge the updates first and wait for this workflow to complete, | |||
# so that the changes will be available for the dependent workflows. | |||
# | |||
name: Build & Push Proto Builder Image | |||
on: | |||
pull_request: | |||
paths: | |||
- "proto/*" | |||
push: | |||
branches: | |||
- master | |||
paths: | |||
- "proto/*" | |||
schedule: | |||
# run this job once a month to recieve any go or buf updates | |||
- cron: "0 9 1 * *" | |||
env: | |||
REGISTRY: ghcr.io | |||
IMAGE_NAME: tendermint/docker-build-proto | |||
jobs: | |||
build: | |||
runs-on: ubuntu-latest | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- name: Check out and assign tags | |||
id: prep | |||
run: | | |||
DOCKER_IMAGE="${REGISTRY}/${IMAGE_NAME}" | |||
VERSION=noop | |||
if [[ "$GITHUB_REF" == "refs/tags/*" ]]; then | |||
VERSION="${GITHUB_REF#refs/tags/}" | |||
elif [[ "$GITHUB_REF" == "refs/heads/*" ]]; then | |||
VERSION="$(echo "${GITHUB_REF#refs/heads/}" | sed -r 's#/+#-#g')" | |||
if [[ "${{ github.event.repository.default_branch }}" = "$VERSION" ]]; then | |||
VERSION=latest | |||
fi | |||
fi | |||
TAGS="${DOCKER_IMAGE}:${VERSION}" | |||
echo ::set-output name=tags::"${TAGS}" | |||
- name: Set up docker buildx | |||
uses: docker/setup-buildx-action@v1.6.0 | |||
- name: Log in to the container registry | |||
uses: docker/login-action@v1.14.1 | |||
with: | |||
registry: ${{ env.REGISTRY }} | |||
username: ${{ github.actor }} | |||
password: ${{ secrets.GITHUB_TOKEN }} | |||
- name: Build and publish image | |||
uses: docker/build-push-action@v2.9.0 | |||
with: | |||
context: ./proto | |||
file: ./proto/Dockerfile | |||
push: ${{ github.event_name != 'pull_request' }} | |||
tags: ${{ steps.prep.outputs.tags }} |
@ -0,0 +1,21 @@ | |||
name: Protobuf Lint | |||
on: | |||
pull_request: | |||
paths: | |||
- 'proto/**' | |||
push: | |||
branches: | |||
- master | |||
paths: | |||
- 'proto/**' | |||
jobs: | |||
lint: | |||
runs-on: ubuntu-latest | |||
timeout-minutes: 5 | |||
steps: | |||
- uses: actions/checkout@v3 | |||
- uses: bufbuild/buf-setup-action@v1.1.0 | |||
- uses: bufbuild/buf-lint-action@v1 | |||
with: | |||
input: 'proto' |
@ -1,14 +1,9 @@ | |||
# The version of the generation template (required). | |||
# The only currently-valid value is v1beta1. | |||
version: v1beta1 | |||
# The plugins to run. | |||
version: v1 | |||
plugins: | |||
# The name of the plugin. | |||
- name: gogofaster | |||
# The directory where the generated proto output will be written. | |||
# The directory is relative to where the generation tool was run. | |||
out: proto | |||
# Set options to assign import paths to the well-known types | |||
# and to enable service generation. | |||
opt: Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration,plugins=grpc,paths=source_relative | |||
out: ./proto/ | |||
opt: | |||
- Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types | |||
- Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration | |||
- plugins=grpc | |||
- paths=source_relative |
@ -0,0 +1,3 @@ | |||
version: v1 | |||
directories: | |||
- proto |
@ -0,0 +1,261 @@ | |||
# RFC 015: ABCI++ TX Mutation | |||
## Changelog | |||
- 23-Feb-2022: Initial draft (@williambanfield). | |||
- 28-Feb-2022: Revised draft (@williambanfield). | |||
## Abstract | |||
A previous version of the ABCI++ specification detailed a mechanism for proposers to replace transactions | |||
in the proposed block. This scheme required the proposer to construct new transactions | |||
and mark these new transactions as replacing other removed transactions. The specification | |||
was ambiguous as to how the replacement may be communicated to peer nodes. | |||
This RFC discusses issues with this mechanism and possible solutions. | |||
## Background | |||
### What is the proposed change? | |||
A previous version of the ABCI++ specification proposed mechanisms for adding, removing, and replacing | |||
transactions in a proposed block. To replace a transaction, the application running | |||
`ProcessProposal` could mark a transaction as replaced by other application-supplied | |||
transactions by returning a new transaction marked with the `ADDED` flag setting | |||
the `new_hashes` field of the removed transaction to contain the list of transaction hashes | |||
that replace it. In that previous specification for ABCI++, the full use of the | |||
`new_hashes` field is left somewhat ambiguous. At present, these hashes are not | |||
gossiped and are not eventually included in the block to signal replacement to | |||
other nodes. The specification did indicate that the transactions specified in | |||
the `new_hashes` field will be removed from the mempool but it's not clear how | |||
peer nodes will learn about them. | |||
### What systems would be affected by adding transaction replacement? | |||
The 'transaction' is a central building block of a Tendermint blockchain, so adding | |||
a mechanism for transaction replacement would require changes to many aspects of Tendermint. | |||
The following is a rough list of the functionality that this mechanism would affect: | |||
#### Transaction indexing | |||
Tendermint's indexer stores transactions and transaction results using the hash of the executed | |||
transaction [as the key][tx-result-index] and the ABCI results and transaction bytes as the value. | |||
To allow transaction replacement, the replaced transactions would need to stored as well in the | |||
indexer, likely as a mapping of original transaction to list of transaction hashes that replaced | |||
the original transaction. | |||
#### Transaction inclusion proofs | |||
The result of a transaction query includes a Merkle proof of the existence of the | |||
transaction in the block chain. This [proof is built][inclusion-proof] as a merkle tree | |||
of the hashes of all of the transactions in the block where the queried transaction was executed. | |||
To allow transaction replacement, these proofs would need to be updated to prove | |||
that a replaced transaction was included by replacement in the block. | |||
#### RPC-based transaction query parameters and results | |||
Tendermint's RPC allows clients to retrieve information about transactions via the | |||
`/tx_search` and `/tx` RPC endpoints. | |||
RPC query results containing replaced transactions would need to be updated to include | |||
information on replaced transactions, either by returning results for all of the replaced | |||
transactions, or by including a response with just the hashes of the replaced transactions | |||
which clients could proceed to query individually. | |||
#### Mempool transaction removal | |||
Additional logic would need to be added to the Tendermint mempool to clear out replaced | |||
transactions after each block is executed. Tendermint currently removes executed transactions | |||
from the mempool, so this would be a pretty straightforward change. | |||
## Discussion | |||
### What value may be added to Tendermint by introducing transaction replacement? | |||
Transaction replacement would would enable applications to aggregate or disaggregate transactions. | |||
For aggregation, a set of transactions that all related work, such as transferring | |||
tokens between the same two accounts, could be replaced with a single transaction, | |||
i.e. one that transfers a single sum from one account to the other. | |||
Applications that make frequent use of aggregation may be able to achieve a higher throughput. | |||
Aggregation would decrease the space occupied by a single client-submitted transaction in the block, allowing | |||
more client-submitted transactions to be executed per block. | |||
For disaggregation, a very complex transaction could be split into multiple smaller transactions. | |||
This may be useful if an application wishes to perform more fine-grained indexing on intermediate parts | |||
of a multi-part transaction. | |||
### Drawbacks to transaction replacement | |||
Transaction replacement would require updating and shimming many of the places that | |||
Tendermint records and exposes information about executed transactions. While | |||
systems within Tendermint could be updated to account for transaction replacement, | |||
such a system would leave new issues and rough edges. | |||
#### No way of guaranteeing correct replacement | |||
If a user issues a transaction to the network and the transaction is replaced, the | |||
user has no guarantee that the replacement was correct. For example, suppose a set of users issue | |||
transactions A, B, and C and they are all aggregated into a new transaction, D. | |||
There is nothing guaranteeing that D was constructed correctly from the inputs. | |||
The only way for users to ensure D is correct would be if D contained all of the | |||
information of its constituent transactions, in which case, nothing is really gained by the replacement. | |||
#### Replacement transactions not signed by submitter | |||
Abstractly, Tendermint simply views transactions as a ball of bytes and therefore | |||
should be fine with replacing one for another. However, many applications require | |||
that transactions submitted to the chain be signed by some private key to authenticate | |||
and authorize the transaction. Replaced transactions could not be signed by the | |||
submitter, only by the application node. Therefore, any use of transaction replacement | |||
could not contain authorization from the submitter and would either need to grant | |||
application-submitted transactions power to perform application logic on behalf | |||
of a user without their consent. | |||
Granting this power to application-submitted transactions would be very dangerous | |||
and therefore might not be of much value to application developers. | |||
Transaction replacement might only be really safe in the case of application-submitted | |||
transactions or for transactions that require no authorization. For such transactions, | |||
it's quite not quite clear what the utility of replacement is: the application can already | |||
generate any transactions that it wants. The fact that such a transaction was a replacement | |||
is not particularly relevant to participants in the chain since the application is | |||
merely replacing its own transactions. | |||
#### New vector for censorship | |||
Depending on the implementation, transaction replacement may allow a node signal | |||
to the rest of the chain that some transaction should no longer be considered for execution. | |||
Honest nodes will use the replacement mechanism to signal that a transaction has been aggregated. | |||
Malicious nodes will be granted a new vector for censoring transactions. | |||
There is no guarantee that a replaced transactions is actually executed at all. | |||
A malicious node could censor a transaction by simply listing it as replaced. | |||
Honest nodes seeing the replacement would flush the transaction from their mempool | |||
and not execute or propose it it in later blocks. | |||
### Transaction tracking implementations | |||
This section discusses possible ways to flesh out the implementation of transaction replacement. | |||
Specifically, this section proposes a few alternative ways that Tendermint blockchains could | |||
track and store transaction replacements. | |||
#### Include transaction replacements in the block | |||
One option to track transaction replacement is to include information on the | |||
transaction replacement within the block. An additional structure may be added | |||
the block of the following form: | |||
```proto | |||
message Block { | |||
... | |||
repeated Replacement replacements = 5; | |||
} | |||
message Replacement { | |||
bytes included_tx_key = 1; | |||
repeated bytes replaced_txs_keys = 2; | |||
} | |||
``` | |||
Applications executing `PrepareProposal` would return the list of replacements and | |||
Tendermint would include an encoding of these replacements in the block that is gossiped | |||
and committed. | |||
Tendermint's transaction indexing would include a new mapping for each replaced transaction | |||
key to the committed transaction. | |||
Transaction inclusion proofs would be updated to include these additional new transaction | |||
keys in the Merkle tree and queries for transaction hashes that were replaced would return | |||
information indicating that the transaction was replaced along with the hash of the | |||
transaction that replaced it. | |||
Block validation of gossiped blocks would be updated to check that each of the | |||
`included_txs_key` matches the hash of some transaction in the proposed block. | |||
Implementing the changes described in this section would allow Tendermint to gossip | |||
and index transaction replacements as part of block propagation. These changes would | |||
still require the application to certify that the replacements were valid. This | |||
validation may be performed in one of two ways: | |||
1. **Applications optimistically trust that the proposer performed a legitimate replacement.** | |||
In this validation scheme, applications would not verify that the substitution | |||
is valid during consensus and instead simply trust that the proposer is correct. | |||
This would have the drawback of allowing a malicious proposer to remove transactions | |||
it did not want executed. | |||
2. **Applications completely validate transaction replacement.** | |||
In this validation scheme, applications that allow replacement would check that | |||
each listed replaced transaction was correctly reflected in the replacement transaction. | |||
In order to perform such validation, the node would need to have the replaced transactions | |||
locally. This could be accomplished one of a few ways: by querying the mempool, | |||
by adding an additional p2p gossip channel for transaction replacements, or by including the replaced transactions | |||
in the block. Replacement validation via mempool querying would require the node | |||
to have received all of the replaced transactions in the mempool which is far from | |||
guaranteed. Adding an additional gossip channel would make gossiping replaced transactions | |||
a requirement for consensus to proceed, since all nodes would need to receive all replacement | |||
messages before considering a block valid. Finally, including replaced transactions in | |||
the block seems to obviate any benefit gained from performing a transaction replacement | |||
since the replaced transaction and the original transactions would now both appear in the block. | |||
#### Application defined transaction replacement | |||
An additional option for allowing transaction replacement is to leave it entirely as a responsibility | |||
of the application. The `PrepareProposal` ABCI++ call allows for applications to add | |||
new transactions to a proposed block. Applications that wished to implement a transaction | |||
replacement mechanism would be free to do so without the newly defined `new_hashes` field. | |||
Applications wishing to implement transaction replacement would add the aggregated | |||
transactions in the `PrepareProposal` response, and include one additional bookkeeping | |||
transaction that listed all of the replacements, with a similar scheme to the `new_hashes` | |||
field described in ABCI++. This new bookkeeping transaction could be used by the | |||
application to determine which transactions to clear from the mempool in future calls | |||
to `CheckTx`. | |||
The meaning of any transaction in the block is completely opaque to Tendermint, | |||
so applications performing this style of replacement would not be able to have the replacement | |||
reflected in any most of Tendermint's transaction tracking mechanisms, such as transaction indexing | |||
and the `/tx` endpoint. | |||
#### Application defined Tx Keys | |||
Tendermint currently uses cryptographic hashes, SHA256, as a key for each transaction. | |||
As noted in the section on systems that would require changing, this key is used | |||
to identify the transaction in the mempool, in the indexer, and within the RPC system. | |||
An alternative approach to allowing `ProcessProposal` to specify a set of transaction | |||
replacements would be instead to allow the application to specify an additional key or set | |||
of keys for each transaction during `ProcessProposal`. This new `secondary_keys` set | |||
would be included in the block and therefore gossiped during block propagation. | |||
Additional RPC endpoints could be exposed to query by the application-defined keys. | |||
Applications wishing to implement replacement would leverage this new field by providing the | |||
replaced transaction hashes as the `secondary_keys` and checking their validity during | |||
`ProcessProposal`. During `RecheckTx` the application would then be responsible for | |||
clearing out transactions that matched the `secondary_keys`. | |||
It is worth noting that something like this would be possible without `secondary_keys`. | |||
An application wishing to implement a system like this one could define a replacement | |||
transaction, as discussed in the section on application-defined transaction replacement, | |||
and use a custom [ABCI event type][abci-event-type] to communicate that the replacement should | |||
be indexed within Tendermint's ABCI event indexing. | |||
### Complexity to value-add tradeoff | |||
It is worth remarking that adding a system like this may introduce a decent amount | |||
of new complexity into Tendermint. An approach that leaves much of the replacement | |||
logic to Tendermint would require altering the core transaction indexing and querying | |||
data. In many of the cases listed, a system for transaction replacement is possible | |||
without explicitly defining it as part of `PrepareProposal`. Since applications | |||
can now add transactions during `PrepareProposal` they can and should leverage this | |||
functionality to include additional bookkeeping transactions in the block. It may | |||
be worth encouraging applications to discover new and interesting ways to leverage this | |||
power instead of immediately solving the problem for them. | |||
### References | |||
[inclusion-proof]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/types/tx.go#L67 | |||
[tx-serach-result]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/rpc/coretypes/responses.go#L267 | |||
[tx-rpc-func]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/internal/rpc/core/tx.go#L21 | |||
[tx-result-index]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/internal/state/indexer/tx/kv/kv.go#L90 | |||
[abci-event-type]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/abci/types/types.pb.go#L3168 |
@ -1,20 +0,0 @@ | |||
# This Dockerfile defines an image containing tools for linting, formatting, | |||
# and compiling the Tendermint protos. | |||
FROM golang:1.17-alpine | |||
# Install a commonly used set of programs for use with our protos. | |||
# clang-extra-tools is included here because it provides clang-format, | |||
# used to format the .proto files. | |||
RUN apk add --no-cache build-base clang-extra-tools curl git | |||
ENV GOLANG_PROTOBUF_VERSION=1.3.1 \ | |||
GOGO_PROTOBUF_VERSION=1.3.2 | |||
# Retrieve the go protoc programs and copy them into the PATH | |||
RUN go install github.com/golang/protobuf/protoc-gen-go@v${GOLANG_PROTOBUF_VERSION} && \ | |||
go install github.com/gogo/protobuf/protoc-gen-gogo@v${GOGO_PROTOBUF_VERSION} && \ | |||
go install github.com/gogo/protobuf/protoc-gen-gogofaster@v${GOGO_PROTOBUF_VERSION} && \ | |||
mv "$(go env GOPATH)"/bin/* /usr/local/bin/ | |||
# Copy the 'buf' program out of the buildbuf/buf container. | |||
COPY --from=bufbuild/buf:latest /usr/local/bin/* /usr/local/bin/ |
@ -0,0 +1,7 @@ | |||
# Generated by buf. DO NOT EDIT. | |||
version: v1 | |||
deps: | |||
- remote: buf.build | |||
owner: gogo | |||
repository: protobuf | |||
commit: 4df00b267f944190a229ce3695781e99 |
@ -1,6 +1,8 @@ | |||
syntax = "proto3"; | |||
package tendermint.libs.bits; | |||
option go_package = "github.com/tendermint/tendermint/proto/tendermint/libs/bits"; | |||
message BitArray { | |||
int64 bits = 1; | |||
repeated uint64 elems = 2; | |||
@ -1,44 +0,0 @@ | |||
#!/usr/bin/env bash | |||
set -euo pipefail | |||
# By default, this script runs against the latest commit to the master branch | |||
# in the Tendermint spec repository. To use this script with a different version | |||
# of the spec repository, run it with the $VERS environment variable set to the | |||
# desired branch name or commit hash from the spec repo. | |||
: ${VERS:=master} | |||
echo "fetching proto files" | |||
# Get shortened ref of commit | |||
REF=$(curl -H "Accept: application/vnd.github.v3.sha" -qL \ | |||
"https://api.github.com/repos/tendermint/spec/commits/${VERS}" \ | |||
| cut -c -7) | |||
readonly OUTDIR="tendermint-spec-${REF}" | |||
curl -qL "https://api.github.com/repos/tendermint/spec/tarball/${REF}" | tar -xzf - ${OUTDIR}/ | |||
cp -r ${OUTDIR}/proto/tendermint/* ./proto/tendermint | |||
cp -r ${OUTDIR}/third_party/** ./third_party | |||
MODNAME="$(go list -m)" | |||
find ./proto/tendermint -name '*.proto' -not -path "./proto/tendermint/abci/types.proto" \ | |||
-exec sh ./scripts/protopackage.sh {} "$MODNAME" ';' | |||
# For historical compatibility, the abci file needs to get a slightly different import name | |||
# so that it can be moved into the ./abci/types directory. | |||
sh ./scripts/protopackage.sh ./proto/tendermint/abci/types.proto $MODNAME "abci/types" | |||
buf generate --path proto/tendermint --template ./${OUTDIR}/buf.gen.yaml --config ./${OUTDIR}/buf.yaml | |||
mv ./proto/tendermint/abci/types.pb.go ./abci/types | |||
echo "proto files have been compiled" | |||
echo "removing copied files" | |||
find ${OUTDIR}/proto/tendermint/ -name *.proto \ | |||
| sed "s/$OUTDIR\/\(.*\)/\1/g" \ | |||
| xargs -I {} rm {} | |||
rm -rf ${OUTDIR} |
@ -1,147 +0,0 @@ | |||
// Protocol Buffers for Go with Gadgets | |||
// | |||
// Copied from https://github.com/gogo/protobuf/blob/master/gogoproto/gogo.proto | |||
// | |||
// Copyright (c) 2013, The GoGo Authors. All rights reserved. | |||
// http://github.com/gogo/protobuf | |||
// | |||
// Redistribution and use in source and binary forms, with or without | |||
// modification, are permitted provided that the following conditions are | |||
// met: | |||
// | |||
// * Redistributions of source code must retain the above copyright | |||
// notice, this list of conditions and the following disclaimer. | |||
// * Redistributions in binary form must reproduce the above | |||
// copyright notice, this list of conditions and the following disclaimer | |||
// in the documentation and/or other materials provided with the | |||
// distribution. | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
syntax = "proto2"; | |||
package gogoproto; | |||
import "google/protobuf/descriptor.proto"; | |||
option java_package = "com.google.protobuf"; | |||
option java_outer_classname = "GoGoProtos"; | |||
option go_package = "github.com/gogo/protobuf/gogoproto"; | |||
extend google.protobuf.EnumOptions { | |||
optional bool goproto_enum_prefix = 62001; | |||
optional bool goproto_enum_stringer = 62021; | |||
optional bool enum_stringer = 62022; | |||
optional string enum_customname = 62023; | |||
optional bool enumdecl = 62024; | |||
} | |||
extend google.protobuf.EnumValueOptions { | |||
optional string enumvalue_customname = 66001; | |||
} | |||
extend google.protobuf.FileOptions { | |||
optional bool goproto_getters_all = 63001; | |||
optional bool goproto_enum_prefix_all = 63002; | |||
optional bool goproto_stringer_all = 63003; | |||
optional bool verbose_equal_all = 63004; | |||
optional bool face_all = 63005; | |||
optional bool gostring_all = 63006; | |||
optional bool populate_all = 63007; | |||
optional bool stringer_all = 63008; | |||
optional bool onlyone_all = 63009; | |||
optional bool equal_all = 63013; | |||
optional bool description_all = 63014; | |||
optional bool testgen_all = 63015; | |||
optional bool benchgen_all = 63016; | |||
optional bool marshaler_all = 63017; | |||
optional bool unmarshaler_all = 63018; | |||
optional bool stable_marshaler_all = 63019; | |||
optional bool sizer_all = 63020; | |||
optional bool goproto_enum_stringer_all = 63021; | |||
optional bool enum_stringer_all = 63022; | |||
optional bool unsafe_marshaler_all = 63023; | |||
optional bool unsafe_unmarshaler_all = 63024; | |||
optional bool goproto_extensions_map_all = 63025; | |||
optional bool goproto_unrecognized_all = 63026; | |||
optional bool gogoproto_import = 63027; | |||
optional bool protosizer_all = 63028; | |||
optional bool compare_all = 63029; | |||
optional bool typedecl_all = 63030; | |||
optional bool enumdecl_all = 63031; | |||
optional bool goproto_registration = 63032; | |||
optional bool messagename_all = 63033; | |||
optional bool goproto_sizecache_all = 63034; | |||
optional bool goproto_unkeyed_all = 63035; | |||
} | |||
extend google.protobuf.MessageOptions { | |||
optional bool goproto_getters = 64001; | |||
optional bool goproto_stringer = 64003; | |||
optional bool verbose_equal = 64004; | |||
optional bool face = 64005; | |||
optional bool gostring = 64006; | |||
optional bool populate = 64007; | |||
optional bool stringer = 67008; | |||
optional bool onlyone = 64009; | |||
optional bool equal = 64013; | |||
optional bool description = 64014; | |||
optional bool testgen = 64015; | |||
optional bool benchgen = 64016; | |||
optional bool marshaler = 64017; | |||
optional bool unmarshaler = 64018; | |||
optional bool stable_marshaler = 64019; | |||
optional bool sizer = 64020; | |||
optional bool unsafe_marshaler = 64023; | |||
optional bool unsafe_unmarshaler = 64024; | |||
optional bool goproto_extensions_map = 64025; | |||
optional bool goproto_unrecognized = 64026; | |||
optional bool protosizer = 64028; | |||
optional bool compare = 64029; | |||
optional bool typedecl = 64030; | |||
optional bool messagename = 64033; | |||
optional bool goproto_sizecache = 64034; | |||
optional bool goproto_unkeyed = 64035; | |||
} | |||
extend google.protobuf.FieldOptions { | |||
optional bool nullable = 65001; | |||
optional bool embed = 65002; | |||
optional string customtype = 65003; | |||
optional string customname = 65004; | |||
optional string jsontag = 65005; | |||
optional string moretags = 65006; | |||
optional string casttype = 65007; | |||
optional string castkey = 65008; | |||
optional string castvalue = 65009; | |||
optional bool stdtime = 65010; | |||
optional bool stdduration = 65011; | |||
optional bool wktpointer = 65012; | |||
optional string castrepeated = 65013; | |||
} |