fix: Remove google.golang.org/protobuf Any prefix (#14119)
* refactor: Remove Any's ypes.googleapis.com prefix * Add docs * go mod tidy * Update
This commit is contained in:
parent
4cfc79ad4e
commit
0c65734bbe
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-proto/any"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
@ -41,7 +42,7 @@ func LoadYAML(bz []byte) depinject.Config {
|
||||
|
||||
// WrapAny marshals a proto message into a proto Any instance
|
||||
func WrapAny(config protoreflect.ProtoMessage) *anypb.Any {
|
||||
cfg, err := anypb.New(config)
|
||||
cfg, err := any.New(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -244,6 +244,34 @@ A real-life example of encoding the pubkey as `Any` inside the Validator struct
|
||||
https://github.com/cosmos/cosmos-sdk/blob/v0.46.0/x/staking/types/validator.go#L40-L61
|
||||
```
|
||||
|
||||
#### `Any`'s TypeURL
|
||||
|
||||
When packing a protobuf message inside an `Any`, the message's type is uniquely defined by its type URL, which is the message's fully qualified name prefixed by a `/` (slash) character. In some implementations of `Any`, like the gogoproto one, there's generally [a resolvable prefix, e.g. `type.googleapis.com`](https://github.com/gogo/protobuf/blob/b03c65ea87cdc3521ede29f62fe3ce239267c1bc/protobuf/google/protobuf/any.proto#L87-L91). However, in the Cosmos SDK, we made the decision to not include such prefix, to have shorter type URLs. The Cosmos SDK's own `Any` implementation can be found in `github.com/cosmos/cosmos-sdk/codec/types`.
|
||||
|
||||
The Cosmos SDK is also switching away from gogoproto to the official `google.golang.org/protobuf` (known as the Protobuf API v2). Its default `Any` implementation also contains the [`type.googleapis.com`](https://github.com/protocolbuffers/protobuf-go/blob/v1.28.1/types/known/anypb/any.pb.go#L266) prefix. To maintain compatibility with the SDK, the following methods from `"google.golang.org/protobuf/types/known/anypb"` should not be used:
|
||||
- `anypb.New`
|
||||
- `anypb.MarshalFrom`
|
||||
- `anypb.Any#MarshalFrom`
|
||||
|
||||
Instead, the Cosmos SDK provides helper functions in `"github.com/cosmos/cosmos-proto/any"`, which create an official `anypb.Any` without inserting the prefixes:
|
||||
- `any.New`
|
||||
- `any.MarshalFrom`
|
||||
|
||||
For example, to pack a `sdk.Msg` called `internalMsg`, use:
|
||||
|
||||
```diff
|
||||
import (
|
||||
- "google.golang.org/protobuf/types/known/anypb"
|
||||
+ "github.com/cosmos/cosmos-proto/any"
|
||||
)
|
||||
|
||||
- anyMsg, err := anypb.New(internalMsg.Message().Interface())
|
||||
+ anyMsg, err := any.New(internalMsg.Message().Interface())
|
||||
|
||||
- fmt.Println(anyMsg.TypeURL) // type.googleapis.com/cosmos.bank.v1beta1.MsgSend
|
||||
+ fmt.Println(anyMsg.TypeURL) // /cosmos.bank.v1beta1.MsgSend
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### How to create modules using protobuf encoding
|
||||
|
||||
@ -10,11 +10,12 @@ import (
|
||||
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
|
||||
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
|
||||
txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
|
||||
"github.com/cosmos/cosmos-proto/any"
|
||||
"github.com/cosmos/cosmos-sdk/orm/internal/stablejson"
|
||||
)
|
||||
|
||||
func TestStableJSON(t *testing.T) {
|
||||
msg, err := anypb.New(&bankv1beta1.MsgSend{
|
||||
msg, err := any.New(&bankv1beta1.MsgSend{
|
||||
FromAddress: "foo213325",
|
||||
ToAddress: "foo32t5sdfh",
|
||||
Amount: []*basev1beta1.Coin{
|
||||
|
||||
36
tx/textual/internal/testdata/any.json
vendored
36
tx/textual/internal/testdata/any.json
vendored
@ -1,74 +1,74 @@
|
||||
[
|
||||
{
|
||||
"proto": {
|
||||
"@type": "type.googleapis.com/Foo"
|
||||
"@type": "/Foo"
|
||||
},
|
||||
"screens": [
|
||||
{"text": "Object: type.googleapis.com/Foo"},
|
||||
{"text": "Object: /Foo"},
|
||||
{"text": "Foo object", "indent": 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
"proto": {
|
||||
"@type": "type.googleapis.com/Foo",
|
||||
"@type": "/Foo",
|
||||
"full_name": "testing"
|
||||
},
|
||||
"screens": [
|
||||
{"text": "Object: type.googleapis.com/Foo"},
|
||||
{"text": "Object: /Foo"},
|
||||
{"text": "Foo object", "indent": 1},
|
||||
{"text": "Full name: testing", "indent": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"proto": {
|
||||
"@type": "type.googleapis.com/google.protobuf.Timestamp",
|
||||
"@type": "/google.protobuf.Timestamp",
|
||||
"value": "2006-01-02T15:04:05Z"
|
||||
},
|
||||
"screens": [
|
||||
{"text": "Object: type.googleapis.com/google.protobuf.Timestamp"},
|
||||
{"text": "Object: /google.protobuf.Timestamp"},
|
||||
{"text": "2006-01-02T15:04:05Z", "indent": 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
"proto": {
|
||||
"@type": "type.googleapis.com/google.protobuf.Any",
|
||||
"@type": "/google.protobuf.Any",
|
||||
"value": {
|
||||
"@type": "type.googleapis.com/Foo"
|
||||
"@type": "/Foo"
|
||||
}
|
||||
},
|
||||
"screens": [
|
||||
{"text": "Object: type.googleapis.com/google.protobuf.Any"},
|
||||
{"text": "Object: type.googleapis.com/Foo", "indent": 1},
|
||||
{"text": "Object: /google.protobuf.Any"},
|
||||
{"text": "Object: /Foo", "indent": 1},
|
||||
{"text": "Foo object", "indent": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"proto": {
|
||||
"@type": "type.googleapis.com/google.protobuf.Any",
|
||||
"@type": "/google.protobuf.Any",
|
||||
"value": {
|
||||
"@type": "type.googleapis.com/Foo",
|
||||
"@type": "/Foo",
|
||||
"full_name": "testing"
|
||||
}
|
||||
},
|
||||
"screens": [
|
||||
{"text": "Object: type.googleapis.com/google.protobuf.Any"},
|
||||
{"text": "Object: type.googleapis.com/Foo", "indent": 1},
|
||||
{"text": "Object: /google.protobuf.Any"},
|
||||
{"text": "Object: /Foo", "indent": 1},
|
||||
{"text": "Foo object", "indent": 2},
|
||||
{"text": "Full name: testing", "indent": 3}
|
||||
]
|
||||
},
|
||||
{
|
||||
"proto": {
|
||||
"@type": "type.googleapis.com/A",
|
||||
"@type": "/A",
|
||||
"ANY": {
|
||||
"@type": "type.googleapis.com/Foo",
|
||||
"@type": "/Foo",
|
||||
"full_name": "testing"
|
||||
}
|
||||
},
|
||||
"screens": [
|
||||
{"text": "Object: type.googleapis.com/A"},
|
||||
{"text": "Object: /A"},
|
||||
{"text": "A object", "indent": 1},
|
||||
{"text": "ANY: Object: type.googleapis.com/Foo", "indent": 2},
|
||||
{"text": "ANY: Object: /Foo", "indent": 2},
|
||||
{"text": "Foo object", "indent": 3},
|
||||
{"text": "Full name: testing", "indent": 4}
|
||||
]
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-proto/any"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
"google.golang.org/protobuf/reflect/protoregistry"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
@ -93,7 +94,7 @@ func (ar anyValueRenderer) Parse(ctx context.Context, screens []Screen) (protore
|
||||
return nilValue, err
|
||||
}
|
||||
|
||||
anyMsg, err := anypb.New(internalMsg.Message().Interface())
|
||||
anyMsg, err := any.New(internalMsg.Message().Interface())
|
||||
if err != nil {
|
||||
return nilValue, err
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user