diff --git a/.github/workflows/auto-assign-prs.yml b/.github/workflows/auto-assign-prs.yml new file mode 100644 index 000000000000..c7bbd8c5dbe7 --- /dev/null +++ b/.github/workflows/auto-assign-prs.yml @@ -0,0 +1,60 @@ +name: Auto Assign Reviewers + +on: + pull_request: + types: [opened, edited, review_requested] + +jobs: + assign-reviewers: + runs-on: ubuntu-latest + + steps: + - name: Check out the repository + uses: actions/checkout@v4 + + - name: Assign reviewers as assignees + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.PRBOT_PAT }} + script: | + const { owner, repo } = context.repo; + + async function getCurrentPR() { + if (context.payload.pull_request) { + return context.payload.pull_request; + } + + const allPRs = await github.rest.pulls.list({ + owner, + repo, + state: 'open', + }); + + return allPRs.data.find(pr => pr.head.sha === context.sha); + } + + const pr = await getCurrentPR(); + if (!pr) { + console.log('No matching PR found.'); + return; + } + + console.log(`Processing PR #${pr.number}`); + + const reviewers = pr.requested_reviewers.map(reviewer => reviewer.login); + + if (reviewers.length === 0) { + console.log('No reviewers found for this PR.'); + return; + } + + console.log(`Current reviewers: ${reviewers.join(', ')}`); + + await github.rest.issues.addAssignees({ + owner, + repo, + issue_number: pr.number, + assignees: reviewers, + }); + + console.log(`Assigned ${reviewers.join(', ')} as assignees to PR #${pr.number}`); diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 46f3fd7bff7a..48c7e82a9677 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -144,8 +144,7 @@ jobs: name: "${{ github.sha }}-e2e-coverage" path: ./tests/e2e-profile.out - test-system: - needs: [tests, test-integration, test-e2e] + test-system: # v2 system tests are in v2-test.yml runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -175,16 +174,6 @@ jobs: run: | sudo apt-get install -y musl - name: system tests v1 - if: env.GIT_DIFF - run: | - COSMOS_BUILD_OPTIONS=legacy make test-system - - uses: actions/upload-artifact@v3 - if: failure() - with: - name: "testnet-setup" - path: ./systemtests/testnet/ - retention-days: 3 - - name: system tests v2 if: env.GIT_DIFF run: | make test-system diff --git a/.github/workflows/v2-test.yml b/.github/workflows/v2-test.yml index 6896f803a2c1..e26e12c0f402 100644 --- a/.github/workflows/v2-test.yml +++ b/.github/workflows/v2-test.yml @@ -109,3 +109,43 @@ jobs: if: env.GIT_DIFF run: | cd server/v2/cometbft && go test -mod=readonly -race -timeout 30m -tags='ledger test_ledger_mock' + + test-system-v2: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-tags: true + - uses: actions/setup-go@v5 + with: + go-version: "1.23" + check-latest: true + cache: true + cache-dependency-path: | + simapp/v2/go.sum + systemtest/go.sum + - uses: technote-space/get-diff-action@v6.1.2 + id: git_diff + with: + PATTERNS: | + **/*.go + go.mod + go.sum + **/go.mod + **/go.sum + **/Makefile + Makefile + - name: Install musl lib for simd (docker) binary + if: env.GIT_DIFF + run: | + sudo apt-get install -y musl + - name: system tests v2 + if: env.GIT_DIFF + run: | + COSMOS_BUILD_OPTIONS=v2 make test-system + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: "testnet-setup" + path: ./systemtests/testnet/ + retention-days: 3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 096a17085f4b..9aac848e00a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,14 +48,18 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i * (client/keys) [#21829](https://github.com/cosmos/cosmos-sdk/pull/21829) Add support for importing hex key using standard input. * (x/validate) [#21822](https://github.com/cosmos/cosmos-sdk/pull/21822) New module solely responsible for providing ante/post handlers and tx validators for v2. It can be extended by the app developer to provide extra tx validators. * In comparison to x/auth/tx/config, there is no app config to skip ante/post handlers, as overwriting them in baseapp or not injecting the x/validate module has the same effect. +* (baeapp) [#21979](https://github.com/cosmos/cosmos-sdk/pull/21979) Create CheckTxHandler to allow extending the logic of CheckTx. ### Improvements * (sims) [#21613](https://github.com/cosmos/cosmos-sdk/pull/21613) Add sims2 framework and factory methods for simpler message factories in modules +* (modules) [#21963](https://github.com/cosmos/cosmos-sdk/pull/21963) Duplicatable metrics are no more collected in modules. They were unecessary overhead. ### Bug Fixes -* (sims) [21906](https://github.com/cosmos/cosmos-sdk/pull/21906) Skip sims test when running dry on validators +* (sims) [#21952](https://github.com/cosmos/cosmos-sdk/pull/21952) Use liveness matrix for validator sign status in sims +* (sims) [#21906](https://github.com/cosmos/cosmos-sdk/pull/21906) Skip sims test when running dry on validators +* (cli) [#21919](https://github.com/cosmos/cosmos-sdk/pull/21919) Query address-by-acc-num by account_id instead of id. ### API Breaking Changes @@ -138,6 +142,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i * (internal) [#21412](https://github.com/cosmos/cosmos-sdk/pull/21412) Using unsafe.String and unsafe.SliceData. * (client) [#21436](https://github.com/cosmos/cosmos-sdk/pull/21436) Use `address.Codec` from client.Context in `tx.Sign`. * (x/genutil) [#21249](https://github.com/cosmos/cosmos-sdk/pull/21249) Incremental JSON parsing for AppGenesis where possible. +* (testnet) [#21941](https://github.com/cosmos/cosmos-sdk/pull/21941) Regenerate addrbook.json for in place testnet. ### Bug Fixes diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 60aeb1192746..59cd1e25e9b6 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -104,7 +104,7 @@ Make sure your code is well tested: We expect tests to use `require` or `assert` rather than `t.Skip` or `t.Fail`, unless there is a reason to do otherwise. When testing a function under a variety of different inputs, we prefer to use -[table driven tests](https://github.com/golang/go/wiki/TableDrivenTests). +[table driven tests](https://go.dev/wiki/TableDrivenTests). Table driven test error messages should follow the following format `, tc #, i #`. `` is an optional short description of what's failing, `tc` is the diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3cac0bfcbdb2..22653e51c334 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -200,7 +200,7 @@ that you would like early feedback and tagging whoever you would like to receive Codeowners are marked automatically as the reviewers. All PRs require at least two review approvals before they can be merged (one review might be acceptable in -the case of minor changes to [docs](./.github/PULL_REQUEST_TEMPLATE/docs.md) changes that do not affect production code). Each PR template has a reviewers checklist that must be completed before the PR can be merged. Each reviewer is responsible +the case of minor changes to docs changes that do not affect production code). Each PR template has a reviewers checklist that must be completed before the PR can be merged. Each reviewer is responsible for all checked items unless they have indicated otherwise by leaving their handle next to specific items. In addition, use the following review explanations: @@ -236,7 +236,7 @@ Within the Cosmos SDK we have two forms of documenting decisions, Request For Co ## Dependencies -We use [Go Modules](https://github.com/golang/go/wiki/Modules) to manage +We use [Go Modules](https://go.dev/wiki/Modules) to manage dependency versions. The main branch of every Cosmos repository should just build with `go get`, @@ -300,7 +300,7 @@ For example, in vscode your `.vscode/settings.json` should look like: User-facing repos should adhere to the trunk based development branching model: https://trunkbaseddevelopment.com. User branches should start with a user name, example: `{moniker}/{issue#}-branch-name`. -The Cosmos SDK repository is a [multi Go module](https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository) repository. It means that we have more than one Go module in a single repository. +The Cosmos SDK repository is a [multi Go module](https://go.dev/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository) repository. It means that we have more than one Go module in a single repository. The Cosmos SDK utilizes [semantic versioning](https://semver.org/). diff --git a/Makefile b/Makefile index 067b5d4f6103..775dc0cd3d7c 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ include scripts/build/build.mk .DEFAULT_GOAL := help -#? go.sum: Run go mod tidy and ensure dependencies have not been modified +#? go.sum: Run go mod tidy and ensure dependencies have not been modified. go.sum: go.mod echo "Ensure dependencies have not been modified ..." >&2 go mod verify diff --git a/SECURITY.md b/SECURITY.md index 94da755d8f47..30ae0fe0eb74 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -57,13 +57,8 @@ If you follow these guidelines when reporting an issue to us, we commit to: ### More information -* See [TIMELINE.md] for an example timeline of a disclosure. -* See [DISCLOSURE.md] to see more into the inner workings of the disclosure - process. * See [EXAMPLES.md] for some of the examples that we are interested in for the bug bounty program. [h1]: https://hackerone.com/cosmos -[TIMELINE.md]: https://github.com/cosmos/security/blob/main/TIMELINE.md -[DISCLOSURE.md]: https://github.com/cosmos/security/blob/main/DISCLOSURE.md -[EXAMPLES.md]: https://github.com/cosmos/security/blob/main/EXAMPLES.md +[EXAMPLES.md]: https://github.com/interchainio/security/blob/main/resources/CLASSIFICATION_MATRIX.md#real-world-examples diff --git a/UPGRADING.md b/UPGRADING.md index 9c3f9ecd9f3b..812cab038576 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -638,7 +638,7 @@ simd config migrate v0.50 If you were using ` config [key]` or ` config [key] [value]` to set and get values from the `client.toml`, replace it with ` config get client [key]` and ` config set client [key] [value]`. The extra verbosity is due to the extra functionalities added in config. -More information about [confix](https://docs.cosmos.network/main/tooling/confix) and how to add it in your application binary in the [documentation](https://docs.cosmos.network/main/tooling/confix). +More information about [confix](https://docs.cosmos.network/main/build/tooling/confix) and how to add it in your application binary in the [documentation](https://docs.cosmos.network/main/build/tooling/confix). #### gRPC-Web diff --git a/api/cosmos/staking/v1beta1/staking.pulsar.go b/api/cosmos/staking/v1beta1/staking.pulsar.go index 3b0e5cb37861..c2f9457ca822 100644 --- a/api/cosmos/staking/v1beta1/staking.pulsar.go +++ b/api/cosmos/staking/v1beta1/staking.pulsar.go @@ -1663,6 +1663,7 @@ var ( fd_Description_website protoreflect.FieldDescriptor fd_Description_security_contact protoreflect.FieldDescriptor fd_Description_details protoreflect.FieldDescriptor + fd_Description_metadata protoreflect.FieldDescriptor ) func init() { @@ -1673,6 +1674,7 @@ func init() { fd_Description_website = md_Description.Fields().ByName("website") fd_Description_security_contact = md_Description.Fields().ByName("security_contact") fd_Description_details = md_Description.Fields().ByName("details") + fd_Description_metadata = md_Description.Fields().ByName("metadata") } var _ protoreflect.Message = (*fastReflection_Description)(nil) @@ -1770,6 +1772,12 @@ func (x *fastReflection_Description) Range(f func(protoreflect.FieldDescriptor, return } } + if x.Metadata != nil { + value := protoreflect.ValueOfMessage(x.Metadata.ProtoReflect()) + if !f(fd_Description_metadata, value) { + return + } + } } // Has reports whether a field is populated. @@ -1795,6 +1803,8 @@ func (x *fastReflection_Description) Has(fd protoreflect.FieldDescriptor) bool { return x.SecurityContact != "" case "cosmos.staking.v1beta1.Description.details": return x.Details != "" + case "cosmos.staking.v1beta1.Description.metadata": + return x.Metadata != nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -1821,6 +1831,8 @@ func (x *fastReflection_Description) Clear(fd protoreflect.FieldDescriptor) { x.SecurityContact = "" case "cosmos.staking.v1beta1.Description.details": x.Details = "" + case "cosmos.staking.v1beta1.Description.metadata": + x.Metadata = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -1852,6 +1864,9 @@ func (x *fastReflection_Description) Get(descriptor protoreflect.FieldDescriptor case "cosmos.staking.v1beta1.Description.details": value := x.Details return protoreflect.ValueOfString(value) + case "cosmos.staking.v1beta1.Description.metadata": + value := x.Metadata + return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -1882,6 +1897,8 @@ func (x *fastReflection_Description) Set(fd protoreflect.FieldDescriptor, value x.SecurityContact = value.Interface().(string) case "cosmos.staking.v1beta1.Description.details": x.Details = value.Interface().(string) + case "cosmos.staking.v1beta1.Description.metadata": + x.Metadata = value.Message().Interface().(*Metadata) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -1902,6 +1919,11 @@ func (x *fastReflection_Description) Set(fd protoreflect.FieldDescriptor, value // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Description) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "cosmos.staking.v1beta1.Description.metadata": + if x.Metadata == nil { + x.Metadata = new(Metadata) + } + return protoreflect.ValueOfMessage(x.Metadata.ProtoReflect()) case "cosmos.staking.v1beta1.Description.moniker": panic(fmt.Errorf("field moniker of message cosmos.staking.v1beta1.Description is not mutable")) case "cosmos.staking.v1beta1.Description.identity": @@ -1935,6 +1957,9 @@ func (x *fastReflection_Description) NewField(fd protoreflect.FieldDescriptor) p return protoreflect.ValueOfString("") case "cosmos.staking.v1beta1.Description.details": return protoreflect.ValueOfString("") + case "cosmos.staking.v1beta1.Description.metadata": + m := new(Metadata) + return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -2024,6 +2049,10 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + if x.Metadata != nil { + l = options.Size(x.Metadata) + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -2053,6 +2082,20 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if x.Metadata != nil { + encoded, err := options.Marshal(x.Metadata) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x32 + } if len(x.Details) > 0 { i -= len(x.Details) copy(dAtA[i:], x.Details) @@ -2228,14 +2271,594 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { if postIndex < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } - if postIndex > l { + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Website = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SecurityContact", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.SecurityContact = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Details = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Metadata == nil { + x.Metadata = &Metadata{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Metadata); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var _ protoreflect.List = (*_Metadata_2_list)(nil) + +type _Metadata_2_list struct { + list *[]string +} + +func (x *_Metadata_2_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Metadata_2_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Metadata_2_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Metadata_2_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Metadata_2_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Metadata at list field SocialHandleUris as it is not of Message kind")) +} + +func (x *_Metadata_2_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Metadata_2_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Metadata_2_list) IsValid() bool { + return x.list != nil +} + +var ( + md_Metadata protoreflect.MessageDescriptor + fd_Metadata_profile_pic_uri protoreflect.FieldDescriptor + fd_Metadata_social_handle_uris protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_staking_v1beta1_staking_proto_init() + md_Metadata = File_cosmos_staking_v1beta1_staking_proto.Messages().ByName("Metadata") + fd_Metadata_profile_pic_uri = md_Metadata.Fields().ByName("profile_pic_uri") + fd_Metadata_social_handle_uris = md_Metadata.Fields().ByName("social_handle_uris") +} + +var _ protoreflect.Message = (*fastReflection_Metadata)(nil) + +type fastReflection_Metadata Metadata + +func (x *Metadata) ProtoReflect() protoreflect.Message { + return (*fastReflection_Metadata)(x) +} + +func (x *Metadata) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Metadata_messageType fastReflection_Metadata_messageType +var _ protoreflect.MessageType = fastReflection_Metadata_messageType{} + +type fastReflection_Metadata_messageType struct{} + +func (x fastReflection_Metadata_messageType) Zero() protoreflect.Message { + return (*fastReflection_Metadata)(nil) +} +func (x fastReflection_Metadata_messageType) New() protoreflect.Message { + return new(fastReflection_Metadata) +} +func (x fastReflection_Metadata_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Metadata +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Metadata) Descriptor() protoreflect.MessageDescriptor { + return md_Metadata +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Metadata) Type() protoreflect.MessageType { + return _fastReflection_Metadata_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Metadata) New() protoreflect.Message { + return new(fastReflection_Metadata) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Metadata) Interface() protoreflect.ProtoMessage { + return (*Metadata)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Metadata) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.ProfilePicUri != "" { + value := protoreflect.ValueOfString(x.ProfilePicUri) + if !f(fd_Metadata_profile_pic_uri, value) { + return + } + } + if len(x.SocialHandleUris) != 0 { + value := protoreflect.ValueOfList(&_Metadata_2_list{list: &x.SocialHandleUris}) + if !f(fd_Metadata_social_handle_uris, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Metadata) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + return x.ProfilePicUri != "" + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + return len(x.SocialHandleUris) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + x.ProfilePicUri = "" + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + x.SocialHandleUris = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Metadata) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + value := x.ProfilePicUri + return protoreflect.ValueOfString(value) + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + if len(x.SocialHandleUris) == 0 { + return protoreflect.ValueOfList(&_Metadata_2_list{}) + } + listValue := &_Metadata_2_list{list: &x.SocialHandleUris} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + x.ProfilePicUri = value.Interface().(string) + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + lv := value.List() + clv := lv.(*_Metadata_2_list) + x.SocialHandleUris = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + if x.SocialHandleUris == nil { + x.SocialHandleUris = []string{} + } + value := &_Metadata_2_list{list: &x.SocialHandleUris} + return protoreflect.ValueOfList(value) + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + panic(fmt.Errorf("field profile_pic_uri of message cosmos.staking.v1beta1.Metadata is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Metadata) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + return protoreflect.ValueOfString("") + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + list := []string{} + return protoreflect.ValueOfList(&_Metadata_2_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Metadata) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.staking.v1beta1.Metadata", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Metadata) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Metadata) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Metadata) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.ProfilePicUri) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.SocialHandleUris) > 0 { + for _, s := range x.SocialHandleUris { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Metadata) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.SocialHandleUris) > 0 { + for iNdEx := len(x.SocialHandleUris) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.SocialHandleUris[iNdEx]) + copy(dAtA[i:], x.SocialHandleUris[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.SocialHandleUris[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(x.ProfilePicUri) > 0 { + i -= len(x.ProfilePicUri) + copy(dAtA[i:], x.ProfilePicUri) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ProfilePicUri))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Metadata) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Website = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SecurityContact", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ProfilePicUri", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2263,11 +2886,11 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.SecurityContact = string(dAtA[iNdEx:postIndex]) + x.ProfilePicUri = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SocialHandleUris", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2295,7 +2918,7 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Details = string(dAtA[iNdEx:postIndex]) + x.SocialHandleUris = append(x.SocialHandleUris, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -2422,7 +3045,7 @@ func (x *Validator) ProtoReflect() protoreflect.Message { } func (x *Validator) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[4] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3704,7 +4327,7 @@ func (x *ValAddresses) ProtoReflect() protoreflect.Message { } func (x *ValAddresses) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[5] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4140,7 +4763,7 @@ func (x *DVPair) ProtoReflect() protoreflect.Message { } func (x *DVPair) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[6] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4673,7 +5296,7 @@ func (x *DVPairs) ProtoReflect() protoreflect.Message { } func (x *DVPairs) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[7] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5120,7 +5743,7 @@ func (x *DVVTriplet) ProtoReflect() protoreflect.Message { } func (x *DVVTriplet) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[8] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5715,7 +6338,7 @@ func (x *DVVTriplets) ProtoReflect() protoreflect.Message { } func (x *DVVTriplets) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[9] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6162,7 +6785,7 @@ func (x *Delegation) ProtoReflect() protoreflect.Message { } func (x *Delegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[10] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6761,7 +7384,7 @@ func (x *UnbondingDelegation) ProtoReflect() protoreflect.Message { } func (x *UnbondingDelegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[11] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7338,7 +7961,7 @@ func (x *UnbondingDelegationEntry) ProtoReflect() protoreflect.Message { } func (x *UnbondingDelegationEntry) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[12] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8045,7 +8668,7 @@ func (x *RedelegationEntry) ProtoReflect() protoreflect.Message { } func (x *RedelegationEntry) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[13] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8799,7 +9422,7 @@ func (x *Redelegation) ProtoReflect() protoreflect.Message { } func (x *Redelegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[14] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9440,7 +10063,7 @@ func (x *Params) ProtoReflect() protoreflect.Message { } func (x *Params) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[15] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10216,7 +10839,7 @@ func (x *DelegationResponse) ProtoReflect() protoreflect.Message { } func (x *DelegationResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[16] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10730,7 +11353,7 @@ func (x *RedelegationEntryResponse) ProtoReflect() protoreflect.Message { } func (x *RedelegationEntryResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[17] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11280,7 +11903,7 @@ func (x *RedelegationResponse) ProtoReflect() protoreflect.Message { } func (x *RedelegationResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[18] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11802,7 +12425,7 @@ func (x *Pool) ProtoReflect() protoreflect.Message { } func (x *Pool) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[19] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12335,7 +12958,7 @@ func (x *ValidatorUpdates) ProtoReflect() protoreflect.Message { } func (x *ValidatorUpdates) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[20] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12786,7 +13409,7 @@ func (x *ConsPubKeyRotationHistory) ProtoReflect() protoreflect.Message { } func (x *ConsPubKeyRotationHistory) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[21] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13531,7 +14154,7 @@ func (x *ValAddrsOfRotatedConsKeys) ProtoReflect() protoreflect.Message { } func (x *ValAddrsOfRotatedConsKeys) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[22] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14235,6 +14858,8 @@ type Description struct { SecurityContact string `protobuf:"bytes,4,opt,name=security_contact,json=securityContact,proto3" json:"security_contact,omitempty"` // details define other optional details. Details string `protobuf:"bytes,5,opt,name=details,proto3" json:"details,omitempty"` + // metadata defines extra information about the validator. + Metadata *Metadata `protobuf:"bytes,6,opt,name=metadata,proto3" json:"metadata,omitempty"` } func (x *Description) Reset() { @@ -14292,6 +14917,59 @@ func (x *Description) GetDetails() string { return "" } +func (x *Description) GetMetadata() *Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +// Metadata defines extra information about the validator. +type Metadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // profile_pic_uri defines a link to the validator profile picture. + ProfilePicUri string `protobuf:"bytes,1,opt,name=profile_pic_uri,json=profilePicUri,proto3" json:"profile_pic_uri,omitempty"` + // social_handle_uris defines a string array of uris to the validator's social handles. + SocialHandleUris []string `protobuf:"bytes,2,rep,name=social_handle_uris,json=socialHandleUris,proto3" json:"social_handle_uris,omitempty"` +} + +func (x *Metadata) Reset() { + *x = Metadata{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Metadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Metadata) ProtoMessage() {} + +// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. +func (*Metadata) Descriptor() ([]byte, []int) { + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{4} +} + +func (x *Metadata) GetProfilePicUri() string { + if x != nil { + return x.ProfilePicUri + } + return "" +} + +func (x *Metadata) GetSocialHandleUris() []string { + if x != nil { + return x.SocialHandleUris + } + return nil +} + // Validator defines a validator, together with the total amount of the // Validator's bond shares and their exchange rate to coins. Slashing results in // a decrease in the exchange rate, allowing correct calculation of future @@ -14336,7 +15014,7 @@ type Validator struct { func (x *Validator) Reset() { *x = Validator{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[4] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14350,7 +15028,7 @@ func (*Validator) ProtoMessage() {} // Deprecated: Use Validator.ProtoReflect.Descriptor instead. func (*Validator) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{4} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{5} } func (x *Validator) GetOperatorAddress() string { @@ -14456,7 +15134,7 @@ type ValAddresses struct { func (x *ValAddresses) Reset() { *x = ValAddresses{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[5] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14470,7 +15148,7 @@ func (*ValAddresses) ProtoMessage() {} // Deprecated: Use ValAddresses.ProtoReflect.Descriptor instead. func (*ValAddresses) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{5} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{6} } func (x *ValAddresses) GetAddresses() []string { @@ -14495,7 +15173,7 @@ type DVPair struct { func (x *DVPair) Reset() { *x = DVPair{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[6] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14509,7 +15187,7 @@ func (*DVPair) ProtoMessage() {} // Deprecated: Use DVPair.ProtoReflect.Descriptor instead. func (*DVPair) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{6} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{7} } func (x *DVPair) GetDelegatorAddress() string { @@ -14538,7 +15216,7 @@ type DVPairs struct { func (x *DVPairs) Reset() { *x = DVPairs{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[7] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14552,7 +15230,7 @@ func (*DVPairs) ProtoMessage() {} // Deprecated: Use DVPairs.ProtoReflect.Descriptor instead. func (*DVPairs) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{7} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{8} } func (x *DVPairs) GetPairs() []*DVPair { @@ -14579,7 +15257,7 @@ type DVVTriplet struct { func (x *DVVTriplet) Reset() { *x = DVVTriplet{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[8] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14593,7 +15271,7 @@ func (*DVVTriplet) ProtoMessage() {} // Deprecated: Use DVVTriplet.ProtoReflect.Descriptor instead. func (*DVVTriplet) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{8} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{9} } func (x *DVVTriplet) GetDelegatorAddress() string { @@ -14629,7 +15307,7 @@ type DVVTriplets struct { func (x *DVVTriplets) Reset() { *x = DVVTriplets{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[9] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14643,7 +15321,7 @@ func (*DVVTriplets) ProtoMessage() {} // Deprecated: Use DVVTriplets.ProtoReflect.Descriptor instead. func (*DVVTriplets) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{9} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{10} } func (x *DVVTriplets) GetTriplets() []*DVVTriplet { @@ -14672,7 +15350,7 @@ type Delegation struct { func (x *Delegation) Reset() { *x = Delegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[10] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14686,7 +15364,7 @@ func (*Delegation) ProtoMessage() {} // Deprecated: Use Delegation.ProtoReflect.Descriptor instead. func (*Delegation) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{10} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{11} } func (x *Delegation) GetDelegatorAddress() string { @@ -14728,7 +15406,7 @@ type UnbondingDelegation struct { func (x *UnbondingDelegation) Reset() { *x = UnbondingDelegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[11] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14742,7 +15420,7 @@ func (*UnbondingDelegation) ProtoMessage() {} // Deprecated: Use UnbondingDelegation.ProtoReflect.Descriptor instead. func (*UnbondingDelegation) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{11} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{12} } func (x *UnbondingDelegation) GetDelegatorAddress() string { @@ -14789,7 +15467,7 @@ type UnbondingDelegationEntry struct { func (x *UnbondingDelegationEntry) Reset() { *x = UnbondingDelegationEntry{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[12] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14803,7 +15481,7 @@ func (*UnbondingDelegationEntry) ProtoMessage() {} // Deprecated: Use UnbondingDelegationEntry.ProtoReflect.Descriptor instead. func (*UnbondingDelegationEntry) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{12} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{13} } func (x *UnbondingDelegationEntry) GetCreationHeight() int64 { @@ -14871,7 +15549,7 @@ type RedelegationEntry struct { func (x *RedelegationEntry) Reset() { *x = RedelegationEntry{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[13] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14885,7 +15563,7 @@ func (*RedelegationEntry) ProtoMessage() {} // Deprecated: Use RedelegationEntry.ProtoReflect.Descriptor instead. func (*RedelegationEntry) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{13} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{14} } func (x *RedelegationEntry) GetCreationHeight() int64 { @@ -14950,7 +15628,7 @@ type Redelegation struct { func (x *Redelegation) Reset() { *x = Redelegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[14] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14964,7 +15642,7 @@ func (*Redelegation) ProtoMessage() {} // Deprecated: Use Redelegation.ProtoReflect.Descriptor instead. func (*Redelegation) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{14} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{15} } func (x *Redelegation) GetDelegatorAddress() string { @@ -15023,7 +15701,7 @@ type Params struct { func (x *Params) Reset() { *x = Params{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[15] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15037,7 +15715,7 @@ func (*Params) ProtoMessage() {} // Deprecated: Use Params.ProtoReflect.Descriptor instead. func (*Params) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{15} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{16} } func (x *Params) GetUnbondingTime() *durationpb.Duration { @@ -15104,7 +15782,7 @@ type DelegationResponse struct { func (x *DelegationResponse) Reset() { *x = DelegationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[16] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15118,7 +15796,7 @@ func (*DelegationResponse) ProtoMessage() {} // Deprecated: Use DelegationResponse.ProtoReflect.Descriptor instead. func (*DelegationResponse) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{16} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{17} } func (x *DelegationResponse) GetDelegation() *Delegation { @@ -15150,7 +15828,7 @@ type RedelegationEntryResponse struct { func (x *RedelegationEntryResponse) Reset() { *x = RedelegationEntryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[17] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15164,7 +15842,7 @@ func (*RedelegationEntryResponse) ProtoMessage() {} // Deprecated: Use RedelegationEntryResponse.ProtoReflect.Descriptor instead. func (*RedelegationEntryResponse) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{17} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{18} } func (x *RedelegationEntryResponse) GetRedelegationEntry() *RedelegationEntry { @@ -15196,7 +15874,7 @@ type RedelegationResponse struct { func (x *RedelegationResponse) Reset() { *x = RedelegationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[18] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15210,7 +15888,7 @@ func (*RedelegationResponse) ProtoMessage() {} // Deprecated: Use RedelegationResponse.ProtoReflect.Descriptor instead. func (*RedelegationResponse) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{18} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{19} } func (x *RedelegationResponse) GetRedelegation() *Redelegation { @@ -15241,7 +15919,7 @@ type Pool struct { func (x *Pool) Reset() { *x = Pool{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[19] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15255,7 +15933,7 @@ func (*Pool) ProtoMessage() {} // Deprecated: Use Pool.ProtoReflect.Descriptor instead. func (*Pool) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{19} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{20} } func (x *Pool) GetNotBondedTokens() string { @@ -15287,7 +15965,7 @@ type ValidatorUpdates struct { func (x *ValidatorUpdates) Reset() { *x = ValidatorUpdates{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[20] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15301,7 +15979,7 @@ func (*ValidatorUpdates) ProtoMessage() {} // Deprecated: Use ValidatorUpdates.ProtoReflect.Descriptor instead. func (*ValidatorUpdates) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{20} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{21} } func (x *ValidatorUpdates) GetUpdates() []*v11.ValidatorUpdate { @@ -15332,7 +16010,7 @@ type ConsPubKeyRotationHistory struct { func (x *ConsPubKeyRotationHistory) Reset() { *x = ConsPubKeyRotationHistory{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[21] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15346,7 +16024,7 @@ func (*ConsPubKeyRotationHistory) ProtoMessage() {} // Deprecated: Use ConsPubKeyRotationHistory.ProtoReflect.Descriptor instead. func (*ConsPubKeyRotationHistory) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{21} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{22} } func (x *ConsPubKeyRotationHistory) GetOperatorAddress() []byte { @@ -15397,7 +16075,7 @@ type ValAddrsOfRotatedConsKeys struct { func (x *ValAddrsOfRotatedConsKeys) Reset() { *x = ValAddrsOfRotatedConsKeys{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[22] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15411,7 +16089,7 @@ func (*ValAddrsOfRotatedConsKeys) ProtoMessage() {} // Deprecated: Use ValAddrsOfRotatedConsKeys.ProtoReflect.Descriptor instead. func (*ValAddrsOfRotatedConsKeys) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{22} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{23} } func (x *ValAddrsOfRotatedConsKeys) GetAddresses() [][]byte { @@ -15427,23 +16105,23 @@ var file_cosmos_staking_v1beta1_staking_proto_rawDesc = []byte{ 0x0a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x16, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, - 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x14, - 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x61, 0x6d, 0x69, - 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, - 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x76, - 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, - 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2f, 0x61, 0x62, 0x63, 0x69, 0x2f, 0x76, 0x31, 0x2f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x98, 0x01, 0x0a, 0x0e, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x11, + 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1c, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2f, 0x61, 0x62, 0x63, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1d, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, + 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x98, 0x01, 0x0a, 0x0e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, @@ -15483,7 +16161,7 @@ var file_cosmos_staking_v1beta1_staking_proto_rawDesc = []byte{ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x3a, 0x04, 0xe8, - 0xa0, 0x1f, 0x01, 0x22, 0xa8, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0xa0, 0x1f, 0x01, 0x22, 0xf1, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, @@ -15493,361 +16171,372 @@ var file_cosmos_staking_v1beta1_staking_proto_rawDesc = []byte{ 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0x9d, - 0x07, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x43, 0x0a, 0x10, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x12, 0x59, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x5f, 0x70, - 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, - 0x79, 0x42, 0x18, 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, - 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, - 0x6a, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6a, 0x61, - 0x69, 0x6c, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, - 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x6f, - 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x43, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, - 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x06, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x31, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, - 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, - 0x79, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, - 0x65, 0x63, 0x52, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x68, 0x61, - 0x72, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, - 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0f, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x12, 0x50, 0x0a, 0x0e, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, - 0xb0, 0x2a, 0x01, 0x52, 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, - 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x6e, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x5f, 0x64, 0x65, - 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3e, - 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, - 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, - 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xda, 0xb4, 0x2d, 0x0f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x30, 0x2e, 0x34, 0x37, 0x52, 0x11, - 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x3c, 0x0a, 0x1b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, - 0x6e, 0x5f, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x4f, 0x6e, 0x48, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x23, 0x0a, 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x73, - 0x18, 0x0d, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0c, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x49, 0x64, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x46, - 0x0a, 0x0c, 0x56, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x36, - 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x06, 0x44, 0x56, 0x50, 0x61, 0x69, - 0x72, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, - 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, - 0x1f, 0x00, 0x22, 0x4a, 0x0a, 0x07, 0x44, 0x56, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x3f, 0x0a, - 0x05, 0x70, 0x61, 0x69, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x56, 0x50, 0x61, 0x69, 0x72, 0x42, 0x09, 0xc8, 0xde, - 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x05, 0x70, 0x61, 0x69, 0x72, 0x73, 0x22, 0x8b, - 0x02, 0x0a, 0x0a, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x12, 0x45, 0x0a, - 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x5f, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x53, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x58, 0x0a, 0x0b, - 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x08, 0x74, - 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, - 0x74, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x74, 0x72, - 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xf8, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x11, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, 0x06, - 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x31, 0xc8, 0xde, - 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, - 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, - 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, - 0x00, 0x22, 0x8d, 0x02, 0x0a, 0x13, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, - 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, - 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x4e, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, - 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x55, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, - 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x62, 0x6f, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, - 0x00, 0x22, 0x9b, 0x03, 0x0a, 0x18, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x27, - 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, - 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, - 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, - 0x74, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x12, 0x45, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, - 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, - 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x62, 0x6f, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, - 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x75, - 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x6c, 0x64, - 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4f, 0x6e, 0x48, 0x6f, 0x6c, - 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, - 0x9f, 0x03, 0x0a, 0x11, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x52, - 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, - 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, - 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, - 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, - 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x50, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, - 0x65, 0x73, 0x5f, 0x64, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x31, 0xc8, 0xde, - 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, - 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, - 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x44, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, - 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x0b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x3c, 0x0a, - 0x1b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, - 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4f, 0x6e, 0x48, - 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, - 0x01, 0x22, 0xdd, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x09, 0xc8, 0xde, + 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0x66, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, + 0x69, 0x63, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x69, 0x63, 0x55, 0x72, 0x69, 0x12, 0x2c, 0x0a, 0x12, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x75, 0x72, 0x69, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x55, 0x72, 0x69, 0x73, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, + 0x9d, 0x07, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x43, 0x0a, + 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x59, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x5f, + 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, + 0x6e, 0x79, 0x42, 0x18, 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x0f, 0x63, 0x6f, + 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, + 0x06, 0x6a, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6a, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, + 0x6f, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x43, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, + 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x06, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x31, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, + 0x63, 0x79, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x44, 0x65, 0x63, 0x52, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x68, + 0x61, 0x72, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, + 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0f, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x12, 0x50, 0x0a, 0x0e, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, + 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, + 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x6e, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x5f, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x3e, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, + 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, + 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xda, 0xb4, 0x2d, 0x0f, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x30, 0x2e, 0x34, 0x37, 0x52, + 0x11, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x1b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, + 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x4f, 0x6e, 0x48, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0c, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x49, 0x64, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, + 0x46, 0x0a, 0x0c, 0x56, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, + 0x36, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x06, 0x44, 0x56, 0x50, 0x61, + 0x69, 0x72, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x11, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, + 0xa0, 0x1f, 0x00, 0x22, 0x4a, 0x0a, 0x07, 0x44, 0x56, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x3f, + 0x0a, 0x05, 0x70, 0x61, 0x69, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x56, 0x50, 0x61, 0x69, 0x72, 0x42, 0x09, 0xc8, + 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x05, 0x70, 0x61, 0x69, 0x72, 0x73, 0x22, + 0x8b, 0x02, 0x0a, 0x0a, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x12, 0x45, + 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x5f, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x53, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x73, 0x74, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, + 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x58, 0x0a, + 0x0b, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x08, + 0x74, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, + 0x65, 0x74, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x74, + 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xf8, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, + 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x73, - 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x73, 0x74, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, - 0x00, 0x22, 0xeb, 0x03, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x4f, 0x0a, 0x0e, - 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, - 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x98, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0d, - 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a, - 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x6e, 0x74, 0x72, - 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x45, 0x6e, - 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x12, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, - 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0d, 0x42, 0x02, 0x18, 0x01, 0x52, 0x11, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, - 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x6e, 0x64, - 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6f, - 0x6e, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x84, 0x01, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x54, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, + 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x31, 0xc8, + 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, + 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, + 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, + 0x1f, 0x00, 0x22, 0x8d, 0x02, 0x0a, 0x13, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, + 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x4e, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, + 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, + 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x55, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, + 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x62, 0x6f, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, + 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, + 0x1f, 0x00, 0x22, 0x9b, 0x03, 0x0a, 0x18, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, + 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0f, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, - 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0xf2, 0xde, 0x1f, 0x1a, 0x79, 0x61, - 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x22, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x11, 0x6d, 0x69, 0x6e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x12, 0x49, - 0x0a, 0x10, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, - 0x65, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x0e, 0x6b, 0x65, 0x79, 0x52, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x65, 0x3a, 0x24, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, - 0xe7, 0xb0, 0x2a, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x78, - 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, - 0xa9, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, - 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, - 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0xcd, 0x01, 0x0a, 0x19, + 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, + 0x6e, 0x74, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x12, 0x45, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, + 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, + 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x62, + 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1b, + 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x6c, + 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4f, 0x6e, 0x48, 0x6f, + 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, + 0x22, 0x9f, 0x03, 0x0a, 0x11, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, + 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, + 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, + 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x50, 0x0a, 0x0a, 0x73, 0x68, 0x61, + 0x72, 0x65, 0x73, 0x5f, 0x64, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x31, 0xc8, + 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, + 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, + 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x44, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x75, + 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x3c, + 0x0a, 0x1b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, + 0x6f, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4f, 0x6e, + 0x48, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x04, 0xe8, 0xa0, + 0x1f, 0x01, 0x22, 0xdd, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, + 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, + 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x73, + 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, + 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, + 0x1f, 0x00, 0x22, 0xeb, 0x03, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x4f, 0x0a, + 0x0e, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x98, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, + 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, + 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x45, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x12, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0d, 0x42, 0x02, 0x18, 0x01, 0x52, 0x11, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, + 0x61, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x6e, + 0x64, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, + 0x6f, 0x6e, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x84, 0x01, 0x0a, 0x13, 0x6d, 0x69, 0x6e, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x54, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, + 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0xf2, 0xde, 0x1f, 0x1a, 0x79, + 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x22, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x11, 0x6d, 0x69, + 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x12, + 0x49, 0x0a, 0x10, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x66, 0x65, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x0e, 0x6b, 0x65, 0x79, 0x52, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x65, 0x3a, 0x24, 0xe8, 0xa0, 0x1f, 0x01, + 0x8a, 0xe7, 0xb0, 0x2a, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, + 0x78, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x22, 0xa9, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, + 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0xcd, 0x01, 0x0a, + 0x19, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x12, 0x72, 0x65, + 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x12, 0x72, 0x65, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, - 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, - 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x11, 0x72, 0x65, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x45, - 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, - 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, - 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x07, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0xc9, 0x01, 0x0a, 0x14, - 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0c, 0x72, 0x65, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x0a, 0x07, 0x65, 0x6e, 0x74, - 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0xc8, - 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0xeb, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x6f, 0x6c, - 0x12, 0x71, 0x0a, 0x11, 0x6e, 0x6f, 0x74, 0x5f, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x45, 0xc8, 0xde, 0x1f, - 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, - 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xea, 0xde, 0x1f, 0x11, 0x6e, 0x6f, - 0x74, 0x5f, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0xd2, - 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xa8, 0xe7, 0xb0, - 0x2a, 0x01, 0x52, 0x0f, 0x6e, 0x6f, 0x74, 0x42, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x73, 0x12, 0x66, 0x0a, 0x0d, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x41, 0xc8, 0xde, 0x1f, 0x00, - 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, - 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xea, 0xde, 0x1f, 0x0d, 0x62, 0x6f, 0x6e, - 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0c, 0x62, - 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x08, 0xe8, 0xa0, 0x1f, - 0x01, 0xf0, 0xa0, 0x1f, 0x01, 0x22, 0x5e, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x07, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x6d, - 0x65, 0x74, 0x62, 0x66, 0x74, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x09, 0xc8, - 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x73, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xd0, 0x02, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x73, 0x50, 0x75, - 0x62, 0x4b, 0x65, 0x79, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x56, - 0x0a, 0x0f, 0x6f, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x42, 0x18, 0xca, - 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, - 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x0d, 0x6f, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x73, - 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x56, 0x0a, 0x0f, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, - 0x6e, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x42, 0x18, 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, - 0x0d, 0x6e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x16, - 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x36, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, - 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, - 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, 0x08, - 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x53, 0x0a, 0x19, 0x56, 0x61, 0x6c, 0x41, - 0x64, 0x64, 0x72, 0x73, 0x4f, 0x66, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, - 0x73, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x2a, 0xb6, 0x01, - 0x0a, 0x0a, 0x42, 0x6f, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x17, - 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x1a, 0x0f, 0x8a, 0x9d, 0x20, 0x0b, 0x55, - 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x14, 0x42, 0x4f, - 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x42, 0x4f, 0x4e, 0x44, - 0x45, 0x44, 0x10, 0x01, 0x1a, 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, - 0x65, 0x64, 0x12, 0x28, 0x0a, 0x15, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x55, 0x4e, 0x42, 0x4f, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x1a, 0x0d, 0x8a, - 0x9d, 0x20, 0x09, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x22, 0x0a, 0x12, - 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x42, 0x4f, 0x4e, 0x44, - 0x45, 0x44, 0x10, 0x03, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x42, 0x6f, 0x6e, 0x64, 0x65, 0x64, - 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, 0x2a, 0x5d, 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, - 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, - 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x54, - 0x49, 0x4d, 0x45, 0x10, 0x02, 0x42, 0xdc, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, + 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x11, 0x72, 0x65, + 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x45, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, + 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x07, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0xc9, 0x01, 0x0a, + 0x14, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0c, 0x72, 0x65, + 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x0a, 0x07, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x42, 0x0c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x73, 0x74, - 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x73, 0x74, - 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, - 0x53, 0x58, 0xaa, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x6b, - 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x43, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, - 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x43, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, + 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0xeb, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x6f, + 0x6c, 0x12, 0x71, 0x0a, 0x11, 0x6e, 0x6f, 0x74, 0x5f, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x45, 0xc8, 0xde, + 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, + 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xea, 0xde, 0x1f, 0x11, 0x6e, + 0x6f, 0x74, 0x5f, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xa8, 0xe7, + 0xb0, 0x2a, 0x01, 0x52, 0x0f, 0x6e, 0x6f, 0x74, 0x42, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x66, 0x0a, 0x0d, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x41, 0xc8, 0xde, 0x1f, + 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, + 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xea, 0xde, 0x1f, 0x0d, 0x62, 0x6f, + 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0c, + 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x08, 0xe8, 0xa0, + 0x1f, 0x01, 0xf0, 0xa0, 0x1f, 0x01, 0x22, 0x5e, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x07, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, + 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x09, + 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x73, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xd0, 0x02, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x73, 0x50, + 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x56, 0x0a, 0x0f, 0x6f, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6b, + 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x42, 0x18, + 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x0d, 0x6f, 0x6c, 0x64, 0x43, 0x6f, 0x6e, + 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x56, 0x0a, 0x0f, 0x6e, 0x65, 0x77, 0x5f, 0x63, + 0x6f, 0x6e, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x42, 0x18, 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, + 0x52, 0x0d, 0x6e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, + 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x36, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, + 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, + 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x53, 0x0a, 0x19, 0x56, 0x61, 0x6c, + 0x41, 0x64, 0x64, 0x72, 0x73, 0x4f, 0x66, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, + 0x6e, 0x73, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x2a, 0xb6, + 0x01, 0x0a, 0x0a, 0x42, 0x6f, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, + 0x17, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x1a, 0x0f, 0x8a, 0x9d, 0x20, 0x0b, + 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x14, 0x42, + 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x42, 0x4f, 0x4e, + 0x44, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x55, 0x6e, 0x62, 0x6f, 0x6e, + 0x64, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x15, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x42, 0x4f, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x1a, 0x0d, + 0x8a, 0x9d, 0x20, 0x09, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x22, 0x0a, + 0x12, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x42, 0x4f, 0x4e, + 0x44, 0x45, 0x44, 0x10, 0x03, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x42, 0x6f, 0x6e, 0x64, 0x65, + 0x64, 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, 0x2a, 0x5d, 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x72, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x10, 0x01, 0x12, 0x17, 0x0a, + 0x13, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x4f, 0x57, 0x4e, + 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x42, 0xdc, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x73, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x73, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, + 0x43, 0x53, 0x58, 0xaa, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x61, + 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x43, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -15863,7 +16552,7 @@ func file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP() []byte { } var file_cosmos_staking_v1beta1_staking_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_cosmos_staking_v1beta1_staking_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_cosmos_staking_v1beta1_staking_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_cosmos_staking_v1beta1_staking_proto_goTypes = []interface{}{ (BondStatus)(0), // 0: cosmos.staking.v1beta1.BondStatus (Infraction)(0), // 1: cosmos.staking.v1beta1.Infraction @@ -15871,64 +16560,66 @@ var file_cosmos_staking_v1beta1_staking_proto_goTypes = []interface{}{ (*CommissionRates)(nil), // 3: cosmos.staking.v1beta1.CommissionRates (*Commission)(nil), // 4: cosmos.staking.v1beta1.Commission (*Description)(nil), // 5: cosmos.staking.v1beta1.Description - (*Validator)(nil), // 6: cosmos.staking.v1beta1.Validator - (*ValAddresses)(nil), // 7: cosmos.staking.v1beta1.ValAddresses - (*DVPair)(nil), // 8: cosmos.staking.v1beta1.DVPair - (*DVPairs)(nil), // 9: cosmos.staking.v1beta1.DVPairs - (*DVVTriplet)(nil), // 10: cosmos.staking.v1beta1.DVVTriplet - (*DVVTriplets)(nil), // 11: cosmos.staking.v1beta1.DVVTriplets - (*Delegation)(nil), // 12: cosmos.staking.v1beta1.Delegation - (*UnbondingDelegation)(nil), // 13: cosmos.staking.v1beta1.UnbondingDelegation - (*UnbondingDelegationEntry)(nil), // 14: cosmos.staking.v1beta1.UnbondingDelegationEntry - (*RedelegationEntry)(nil), // 15: cosmos.staking.v1beta1.RedelegationEntry - (*Redelegation)(nil), // 16: cosmos.staking.v1beta1.Redelegation - (*Params)(nil), // 17: cosmos.staking.v1beta1.Params - (*DelegationResponse)(nil), // 18: cosmos.staking.v1beta1.DelegationResponse - (*RedelegationEntryResponse)(nil), // 19: cosmos.staking.v1beta1.RedelegationEntryResponse - (*RedelegationResponse)(nil), // 20: cosmos.staking.v1beta1.RedelegationResponse - (*Pool)(nil), // 21: cosmos.staking.v1beta1.Pool - (*ValidatorUpdates)(nil), // 22: cosmos.staking.v1beta1.ValidatorUpdates - (*ConsPubKeyRotationHistory)(nil), // 23: cosmos.staking.v1beta1.ConsPubKeyRotationHistory - (*ValAddrsOfRotatedConsKeys)(nil), // 24: cosmos.staking.v1beta1.ValAddrsOfRotatedConsKeys - (*v1.Header)(nil), // 25: cometbft.types.v1.Header - (*timestamppb.Timestamp)(nil), // 26: google.protobuf.Timestamp - (*anypb.Any)(nil), // 27: google.protobuf.Any - (*durationpb.Duration)(nil), // 28: google.protobuf.Duration - (*v1beta1.Coin)(nil), // 29: cosmos.base.v1beta1.Coin - (*v11.ValidatorUpdate)(nil), // 30: cometbft.abci.v1.ValidatorUpdate + (*Metadata)(nil), // 6: cosmos.staking.v1beta1.Metadata + (*Validator)(nil), // 7: cosmos.staking.v1beta1.Validator + (*ValAddresses)(nil), // 8: cosmos.staking.v1beta1.ValAddresses + (*DVPair)(nil), // 9: cosmos.staking.v1beta1.DVPair + (*DVPairs)(nil), // 10: cosmos.staking.v1beta1.DVPairs + (*DVVTriplet)(nil), // 11: cosmos.staking.v1beta1.DVVTriplet + (*DVVTriplets)(nil), // 12: cosmos.staking.v1beta1.DVVTriplets + (*Delegation)(nil), // 13: cosmos.staking.v1beta1.Delegation + (*UnbondingDelegation)(nil), // 14: cosmos.staking.v1beta1.UnbondingDelegation + (*UnbondingDelegationEntry)(nil), // 15: cosmos.staking.v1beta1.UnbondingDelegationEntry + (*RedelegationEntry)(nil), // 16: cosmos.staking.v1beta1.RedelegationEntry + (*Redelegation)(nil), // 17: cosmos.staking.v1beta1.Redelegation + (*Params)(nil), // 18: cosmos.staking.v1beta1.Params + (*DelegationResponse)(nil), // 19: cosmos.staking.v1beta1.DelegationResponse + (*RedelegationEntryResponse)(nil), // 20: cosmos.staking.v1beta1.RedelegationEntryResponse + (*RedelegationResponse)(nil), // 21: cosmos.staking.v1beta1.RedelegationResponse + (*Pool)(nil), // 22: cosmos.staking.v1beta1.Pool + (*ValidatorUpdates)(nil), // 23: cosmos.staking.v1beta1.ValidatorUpdates + (*ConsPubKeyRotationHistory)(nil), // 24: cosmos.staking.v1beta1.ConsPubKeyRotationHistory + (*ValAddrsOfRotatedConsKeys)(nil), // 25: cosmos.staking.v1beta1.ValAddrsOfRotatedConsKeys + (*v1.Header)(nil), // 26: cometbft.types.v1.Header + (*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp + (*anypb.Any)(nil), // 28: google.protobuf.Any + (*durationpb.Duration)(nil), // 29: google.protobuf.Duration + (*v1beta1.Coin)(nil), // 30: cosmos.base.v1beta1.Coin + (*v11.ValidatorUpdate)(nil), // 31: cometbft.abci.v1.ValidatorUpdate } var file_cosmos_staking_v1beta1_staking_proto_depIdxs = []int32{ - 25, // 0: cosmos.staking.v1beta1.HistoricalInfo.header:type_name -> cometbft.types.v1.Header - 6, // 1: cosmos.staking.v1beta1.HistoricalInfo.valset:type_name -> cosmos.staking.v1beta1.Validator + 26, // 0: cosmos.staking.v1beta1.HistoricalInfo.header:type_name -> cometbft.types.v1.Header + 7, // 1: cosmos.staking.v1beta1.HistoricalInfo.valset:type_name -> cosmos.staking.v1beta1.Validator 3, // 2: cosmos.staking.v1beta1.Commission.commission_rates:type_name -> cosmos.staking.v1beta1.CommissionRates - 26, // 3: cosmos.staking.v1beta1.Commission.update_time:type_name -> google.protobuf.Timestamp - 27, // 4: cosmos.staking.v1beta1.Validator.consensus_pubkey:type_name -> google.protobuf.Any - 0, // 5: cosmos.staking.v1beta1.Validator.status:type_name -> cosmos.staking.v1beta1.BondStatus - 5, // 6: cosmos.staking.v1beta1.Validator.description:type_name -> cosmos.staking.v1beta1.Description - 26, // 7: cosmos.staking.v1beta1.Validator.unbonding_time:type_name -> google.protobuf.Timestamp - 4, // 8: cosmos.staking.v1beta1.Validator.commission:type_name -> cosmos.staking.v1beta1.Commission - 8, // 9: cosmos.staking.v1beta1.DVPairs.pairs:type_name -> cosmos.staking.v1beta1.DVPair - 10, // 10: cosmos.staking.v1beta1.DVVTriplets.triplets:type_name -> cosmos.staking.v1beta1.DVVTriplet - 14, // 11: cosmos.staking.v1beta1.UnbondingDelegation.entries:type_name -> cosmos.staking.v1beta1.UnbondingDelegationEntry - 26, // 12: cosmos.staking.v1beta1.UnbondingDelegationEntry.completion_time:type_name -> google.protobuf.Timestamp - 26, // 13: cosmos.staking.v1beta1.RedelegationEntry.completion_time:type_name -> google.protobuf.Timestamp - 15, // 14: cosmos.staking.v1beta1.Redelegation.entries:type_name -> cosmos.staking.v1beta1.RedelegationEntry - 28, // 15: cosmos.staking.v1beta1.Params.unbonding_time:type_name -> google.protobuf.Duration - 29, // 16: cosmos.staking.v1beta1.Params.key_rotation_fee:type_name -> cosmos.base.v1beta1.Coin - 12, // 17: cosmos.staking.v1beta1.DelegationResponse.delegation:type_name -> cosmos.staking.v1beta1.Delegation - 29, // 18: cosmos.staking.v1beta1.DelegationResponse.balance:type_name -> cosmos.base.v1beta1.Coin - 15, // 19: cosmos.staking.v1beta1.RedelegationEntryResponse.redelegation_entry:type_name -> cosmos.staking.v1beta1.RedelegationEntry - 16, // 20: cosmos.staking.v1beta1.RedelegationResponse.redelegation:type_name -> cosmos.staking.v1beta1.Redelegation - 19, // 21: cosmos.staking.v1beta1.RedelegationResponse.entries:type_name -> cosmos.staking.v1beta1.RedelegationEntryResponse - 30, // 22: cosmos.staking.v1beta1.ValidatorUpdates.updates:type_name -> cometbft.abci.v1.ValidatorUpdate - 27, // 23: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.old_cons_pubkey:type_name -> google.protobuf.Any - 27, // 24: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.new_cons_pubkey:type_name -> google.protobuf.Any - 29, // 25: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.fee:type_name -> cosmos.base.v1beta1.Coin - 26, // [26:26] is the sub-list for method output_type - 26, // [26:26] is the sub-list for method input_type - 26, // [26:26] is the sub-list for extension type_name - 26, // [26:26] is the sub-list for extension extendee - 0, // [0:26] is the sub-list for field type_name + 27, // 3: cosmos.staking.v1beta1.Commission.update_time:type_name -> google.protobuf.Timestamp + 6, // 4: cosmos.staking.v1beta1.Description.metadata:type_name -> cosmos.staking.v1beta1.Metadata + 28, // 5: cosmos.staking.v1beta1.Validator.consensus_pubkey:type_name -> google.protobuf.Any + 0, // 6: cosmos.staking.v1beta1.Validator.status:type_name -> cosmos.staking.v1beta1.BondStatus + 5, // 7: cosmos.staking.v1beta1.Validator.description:type_name -> cosmos.staking.v1beta1.Description + 27, // 8: cosmos.staking.v1beta1.Validator.unbonding_time:type_name -> google.protobuf.Timestamp + 4, // 9: cosmos.staking.v1beta1.Validator.commission:type_name -> cosmos.staking.v1beta1.Commission + 9, // 10: cosmos.staking.v1beta1.DVPairs.pairs:type_name -> cosmos.staking.v1beta1.DVPair + 11, // 11: cosmos.staking.v1beta1.DVVTriplets.triplets:type_name -> cosmos.staking.v1beta1.DVVTriplet + 15, // 12: cosmos.staking.v1beta1.UnbondingDelegation.entries:type_name -> cosmos.staking.v1beta1.UnbondingDelegationEntry + 27, // 13: cosmos.staking.v1beta1.UnbondingDelegationEntry.completion_time:type_name -> google.protobuf.Timestamp + 27, // 14: cosmos.staking.v1beta1.RedelegationEntry.completion_time:type_name -> google.protobuf.Timestamp + 16, // 15: cosmos.staking.v1beta1.Redelegation.entries:type_name -> cosmos.staking.v1beta1.RedelegationEntry + 29, // 16: cosmos.staking.v1beta1.Params.unbonding_time:type_name -> google.protobuf.Duration + 30, // 17: cosmos.staking.v1beta1.Params.key_rotation_fee:type_name -> cosmos.base.v1beta1.Coin + 13, // 18: cosmos.staking.v1beta1.DelegationResponse.delegation:type_name -> cosmos.staking.v1beta1.Delegation + 30, // 19: cosmos.staking.v1beta1.DelegationResponse.balance:type_name -> cosmos.base.v1beta1.Coin + 16, // 20: cosmos.staking.v1beta1.RedelegationEntryResponse.redelegation_entry:type_name -> cosmos.staking.v1beta1.RedelegationEntry + 17, // 21: cosmos.staking.v1beta1.RedelegationResponse.redelegation:type_name -> cosmos.staking.v1beta1.Redelegation + 20, // 22: cosmos.staking.v1beta1.RedelegationResponse.entries:type_name -> cosmos.staking.v1beta1.RedelegationEntryResponse + 31, // 23: cosmos.staking.v1beta1.ValidatorUpdates.updates:type_name -> cometbft.abci.v1.ValidatorUpdate + 28, // 24: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.old_cons_pubkey:type_name -> google.protobuf.Any + 28, // 25: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.new_cons_pubkey:type_name -> google.protobuf.Any + 30, // 26: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.fee:type_name -> cosmos.base.v1beta1.Coin + 27, // [27:27] is the sub-list for method output_type + 27, // [27:27] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name } func init() { file_cosmos_staking_v1beta1_staking_proto_init() } @@ -15986,7 +16677,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Validator); i { + switch v := v.(*Metadata); i { case 0: return &v.state case 1: @@ -15998,7 +16689,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValAddresses); i { + switch v := v.(*Validator); i { case 0: return &v.state case 1: @@ -16010,7 +16701,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DVPair); i { + switch v := v.(*ValAddresses); i { case 0: return &v.state case 1: @@ -16022,7 +16713,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DVPairs); i { + switch v := v.(*DVPair); i { case 0: return &v.state case 1: @@ -16034,7 +16725,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DVVTriplet); i { + switch v := v.(*DVPairs); i { case 0: return &v.state case 1: @@ -16046,7 +16737,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DVVTriplets); i { + switch v := v.(*DVVTriplet); i { case 0: return &v.state case 1: @@ -16058,7 +16749,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Delegation); i { + switch v := v.(*DVVTriplets); i { case 0: return &v.state case 1: @@ -16070,7 +16761,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnbondingDelegation); i { + switch v := v.(*Delegation); i { case 0: return &v.state case 1: @@ -16082,7 +16773,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnbondingDelegationEntry); i { + switch v := v.(*UnbondingDelegation); i { case 0: return &v.state case 1: @@ -16094,7 +16785,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RedelegationEntry); i { + switch v := v.(*UnbondingDelegationEntry); i { case 0: return &v.state case 1: @@ -16106,7 +16797,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Redelegation); i { + switch v := v.(*RedelegationEntry); i { case 0: return &v.state case 1: @@ -16118,7 +16809,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Params); i { + switch v := v.(*Redelegation); i { case 0: return &v.state case 1: @@ -16130,7 +16821,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DelegationResponse); i { + switch v := v.(*Params); i { case 0: return &v.state case 1: @@ -16142,7 +16833,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RedelegationEntryResponse); i { + switch v := v.(*DelegationResponse); i { case 0: return &v.state case 1: @@ -16154,7 +16845,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RedelegationResponse); i { + switch v := v.(*RedelegationEntryResponse); i { case 0: return &v.state case 1: @@ -16166,7 +16857,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Pool); i { + switch v := v.(*RedelegationResponse); i { case 0: return &v.state case 1: @@ -16178,7 +16869,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidatorUpdates); i { + switch v := v.(*Pool); i { case 0: return &v.state case 1: @@ -16190,7 +16881,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ConsPubKeyRotationHistory); i { + switch v := v.(*ValidatorUpdates); i { case 0: return &v.state case 1: @@ -16202,6 +16893,18 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConsPubKeyRotationHistory); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_staking_v1beta1_staking_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValAddrsOfRotatedConsKeys); i { case 0: return &v.state @@ -16220,7 +16923,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cosmos_staking_v1beta1_staking_proto_rawDesc, NumEnums: 2, - NumMessages: 23, + NumMessages: 24, NumExtensions: 0, NumServices: 0, }, diff --git a/api/go.mod b/api/go.mod index 6a43804136a3..c6e040103a8b 100644 --- a/api/go.mod +++ b/api/go.mod @@ -7,7 +7,7 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/gogoproto v1.7.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -17,5 +17,5 @@ require ( golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect ) diff --git a/api/go.sum b/api/go.sum index 4f8f19c6a8f8..d1fd43b81060 100644 --- a/api/go.sum +++ b/api/go.sum @@ -18,9 +18,9 @@ golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= diff --git a/baseapp/abci.go b/baseapp/abci.go index 05b9e61794a7..27118f0f3b10 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -180,7 +180,8 @@ func (app *BaseApp) Query(_ context.Context, req *abci.QueryRequest) (resp *abci telemetry.IncrCounter(1, "query", "count") telemetry.IncrCounter(1, "query", req.Path) - defer telemetry.MeasureSince(telemetry.Now(), req.Path) + start := telemetry.Now() + defer telemetry.MeasureSince(start, req.Path) if req.Path == QueryPathBroadcastTx { return queryResult(errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "can't route a broadcast tx message"), app.trace), nil @@ -366,18 +367,27 @@ func (app *BaseApp) CheckTx(req *abci.CheckTxRequest) (*abci.CheckTxResponse, er return nil, fmt.Errorf("unknown RequestCheckTx type: %s", req.Type) } - gInfo, result, anteEvents, err := app.runTx(mode, req.Tx) - if err != nil { - return responseCheckTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, anteEvents, app.trace), nil + if app.checkTxHandler == nil { + gInfo, result, anteEvents, err := app.runTx(mode, req.Tx, nil) + if err != nil { + return responseCheckTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, anteEvents, app.trace), nil + } + + return &abci.CheckTxResponse{ + GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? + GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints? + Log: result.Log, + Data: result.Data, + Events: sdk.MarkEventsToIndex(result.Events, app.indexEvents), + }, nil } - return &abci.CheckTxResponse{ - GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? - GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints? - Log: result.Log, - Data: result.Data, - Events: sdk.MarkEventsToIndex(result.Events, app.indexEvents), - }, nil + // Create wrapper to avoid users overriding the execution mode + runTx := func(txBytes []byte, tx sdk.Tx) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, err error) { + return app.runTx(mode, txBytes, tx) + } + + return app.checkTxHandler(runTx, req) } // PrepareProposal implements the PrepareProposal ABCI method and returns a diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 89748eadf053..b5d100d263a9 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -91,6 +91,7 @@ type BaseApp struct { prepareCheckStater sdk.PrepareCheckStater // logic to run during commit using the checkState precommiter sdk.Precommiter // logic to run during commit using the deliverState versionModifier server.VersionModifier // interface to get and set the app version + checkTxHandler sdk.CheckTxHandler addrPeerFilter sdk.PeerFilter // filter peers by address and port idPeerFilter sdk.PeerFilter // filter peers by node ID @@ -688,7 +689,6 @@ func (app *BaseApp) getContextForTx(mode execMode, txBytes []byte) sdk.Context { // a branched multi-store. func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context, storetypes.CacheMultiStore) { ms := ctx.MultiStore() - // TODO: https://github.com/cosmos/cosmos-sdk/issues/2824 msCache := ms.CacheMultiStore() if msCache.TracingEnabled() { msCache = msCache.SetTracingContext( @@ -761,7 +761,7 @@ func (app *BaseApp) deliverTx(tx []byte) *abci.ExecTxResult { telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, err := app.runTx(execModeFinalize, tx) + gInfo, result, anteEvents, err := app.runTx(execModeFinalize, tx, nil) if err != nil { resultStr = "failed" resp = responseExecTxResultWithEvents( @@ -822,7 +822,9 @@ type HasNestedMsgs interface { // Note, gas execution info is always returned. A reference to a Result is // returned if the tx does not run out of gas and if all the messages are valid // and execute successfully. An error is returned otherwise. -func (app *BaseApp) runTx(mode execMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, err error) { +// both txbytes and the decoded tx are passed to runTx to avoid the state machine encoding the tx and decoding the transaction twice +// passing the decoded tx to runTX is optional, it will be decoded if the tx is nil +func (app *BaseApp) runTx(mode execMode, txBytes []byte, tx sdk.Tx) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, err error) { // NOTE: GasWanted should be returned by the AnteHandler. GasUsed is // determined by the GasMeter. We need access to the context to get the gas // meter, so we initialize upfront. @@ -870,9 +872,12 @@ func (app *BaseApp) runTx(mode execMode, txBytes []byte) (gInfo sdk.GasInfo, res defer consumeBlockGas() } - tx, err := app.txDecoder(txBytes) - if err != nil { - return sdk.GasInfo{GasUsed: 0, GasWanted: 0}, nil, nil, sdkerrors.ErrTxDecode.Wrap(err.Error()) + // if the transaction is not decoded, decode it here + if tx == nil { + tx, err = app.txDecoder(txBytes) + if err != nil { + return sdk.GasInfo{GasUsed: 0, GasWanted: 0}, nil, nil, sdkerrors.ErrTxDecode.Wrap(err.Error()) + } } msgs := tx.GetMsgs() @@ -1160,7 +1165,7 @@ func (app *BaseApp) PrepareProposalVerifyTx(tx sdk.Tx) ([]byte, error) { return nil, err } - _, _, _, err = app.runTx(execModePrepareProposal, bz) + _, _, _, err = app.runTx(execModePrepareProposal, bz, tx) if err != nil { return nil, err } @@ -1179,7 +1184,7 @@ func (app *BaseApp) ProcessProposalVerifyTx(txBz []byte) (sdk.Tx, error) { return nil, err } - _, _, _, err = app.runTx(execModeProcessProposal, txBz) + _, _, _, err = app.runTx(execModeProcessProposal, txBz, tx) if err != nil { return nil, err } diff --git a/baseapp/options.go b/baseapp/options.go index 53286b2540b9..743d04c5543c 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -367,6 +367,15 @@ func (app *BaseApp) SetPrepareProposal(handler sdk.PrepareProposalHandler) { app.prepareProposal = handler } +// SetCheckTxHandler sets the checkTx function for the BaseApp. +func (app *BaseApp) SetCheckTxHandler(handler sdk.CheckTxHandler) { + if app.sealed { + panic("SetCheckTx() on sealed BaseApp") + } + + app.checkTxHandler = handler +} + func (app *BaseApp) SetExtendVoteHandler(handler sdk.ExtendVoteHandler) { if app.sealed { panic("SetExtendVoteHandler() on sealed BaseApp") diff --git a/baseapp/streaming.go b/baseapp/streaming.go index 6eeb8e37b449..b6f40cb87fff 100644 --- a/baseapp/streaming.go +++ b/baseapp/streaming.go @@ -33,7 +33,7 @@ const ( // kv-store keys, and app modules. Using the built-in indexer framework is mutually exclusive from using other // types of streaming listeners. func (app *BaseApp) EnableIndexer(indexerOpts interface{}, keys map[string]*storetypes.KVStoreKey, appModules map[string]any) error { - listener, err := indexer.StartManager(indexer.ManagerOptions{ + listener, err := indexer.StartIndexing(indexer.IndexingOptions{ Config: indexerOpts, Resolver: decoding.ModuleSetDecoderResolver(appModules), SyncSource: nil, @@ -47,7 +47,7 @@ func (app *BaseApp) EnableIndexer(indexerOpts interface{}, keys map[string]*stor app.cms.AddListeners(exposedKeys) app.streamingManager = storetypes.StreamingManager{ - ABCIListeners: []storetypes.ABCIListener{listenerWrapper{listener}}, + ABCIListeners: []storetypes.ABCIListener{listenerWrapper{listener.Listener}}, StopNodeOnErr: true, } diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index fcd0e55c8447..7cae8e541b7d 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -19,13 +19,13 @@ func (app *BaseApp) SimCheck(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, * return sdk.GasInfo{}, nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } - gasInfo, result, _, err := app.runTx(execModeCheck, bz) + gasInfo, result, _, err := app.runTx(execModeCheck, bz, tx) return gasInfo, result, err } // Simulate executes a tx in simulate mode to get result and gas info. func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { - gasInfo, result, _, err := app.runTx(execModeSimulate, txBytes) + gasInfo, result, _, err := app.runTx(execModeSimulate, txBytes, nil) return gasInfo, result, err } @@ -36,7 +36,7 @@ func (app *BaseApp) SimDeliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, return sdk.GasInfo{}, nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } - gasInfo, result, _, err := app.runTx(execModeFinalize, bz) + gasInfo, result, _, err := app.runTx(execModeFinalize, bz, tx) return gasInfo, result, err } diff --git a/buf.work.yaml b/buf.work.yaml index 5a070acabfd2..afd7c4ea0d8e 100644 --- a/buf.work.yaml +++ b/buf.work.yaml @@ -2,7 +2,6 @@ version: v1 directories: - proto - x/accounts/proto - - x/auth/proto - x/authz/proto - x/bank/proto - x/circuit/proto diff --git a/client/grpc/cmtservice/status_test.go b/client/grpc/cmtservice/status_test.go index 9f7ab9567921..d7bfa6bdc192 100644 --- a/client/grpc/cmtservice/status_test.go +++ b/client/grpc/cmtservice/status_test.go @@ -14,7 +14,7 @@ import ( ) func TestStatusCommand(t *testing.T) { - t.Skip() // https://github.com/cosmos/cosmos-sdk/issues/17446 + t.Skip() // Rewrite as system test cfg, err := network.DefaultConfigWithAppConfig(depinject.Configs() /* TODO, test skipped anyway */) require.NoError(t, err) diff --git a/client/keys/migrate.go b/client/keys/migrate.go index 0a9fc78e2143..b2e192dffb93 100644 --- a/client/keys/migrate.go +++ b/client/keys/migrate.go @@ -18,8 +18,6 @@ Otherwise, we try to deserialize it using Amino into LegacyInfo. If this attempt LegacyInfo to Protobuf serialization format and overwrite the keyring entry. If any error occurred, it will be outputted in CLI and migration will be continued until all keys in the keyring DB are exhausted. See https://github.com/cosmos/cosmos-sdk/pull/9695 for more details. - -It is recommended to run in 'dry-run' mode first to verify all key migration material. `, Args: cobra.NoArgs, RunE: runMigrateCmd, diff --git a/client/v2/CHANGELOG.md b/client/v2/CHANGELOG.md index a7e8105b134b..dfd4b8cfb213 100644 --- a/client/v2/CHANGELOG.md +++ b/client/v2/CHANGELOG.md @@ -43,6 +43,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#18626](https://github.com/cosmos/cosmos-sdk/pull/18626) Support for off-chain signing and verification of a file. * [#18461](https://github.com/cosmos/cosmos-sdk/pull/18461) Support governance proposals. +### Improvements + +* [#21936](https://github.com/cosmos/cosmos-sdk/pull/21936) Print possible enum values in error message after an invalid input was provided. + ### API Breaking Changes * [#17709](https://github.com/cosmos/cosmos-sdk/pull/17709) Address codecs have been removed from `autocli.AppOptions` and `flag.Builder`. Instead client/v2 uses the address codecs present in the context (introduced in [#17503](https://github.com/cosmos/cosmos-sdk/pull/17503)). diff --git a/client/v2/README.md b/client/v2/README.md index 9efc241748af..b4c2666850ee 100644 --- a/client/v2/README.md +++ b/client/v2/README.md @@ -2,7 +2,9 @@ sidebar_position: 1 --- -# AutoCLI +# Client/v2 + +## AutoCLI :::note Synopsis This document details how to build CLI and REST interfaces for a module. Examples from various Cosmos SDK modules are included. @@ -14,9 +16,9 @@ This document details how to build CLI and REST interfaces for a module. Example ::: -The `autocli` (also known as `client/v2`) package is a [Go library](https://pkg.go.dev/cosmossdk.io/client/v2/autocli) for generating CLI (command line interface) interfaces for Cosmos SDK-based applications. It provides a simple way to add CLI commands to your application by generating them automatically based on your gRPC service definitions. Autocli generates CLI commands and flags directly from your protobuf messages, including options, input parameters, and output parameters. This means that you can easily add a CLI interface to your application without having to manually create and manage commands. +The `autocli` (also known as `client/v2/autocli`) package is a [Go library](https://pkg.go.dev/cosmossdk.io/client/v2/autocli) for generating CLI (command line interface) interfaces for Cosmos SDK-based applications. It provides a simple way to add CLI commands to your application by generating them automatically based on your gRPC service definitions. Autocli generates CLI commands and flags directly from your protobuf messages, including options, input parameters, and output parameters. This means that you can easily add a CLI interface to your application without having to manually create and manage commands. -## Overview +### Overview `autocli` generates CLI commands and flags for each method defined in your gRPC service. By default, it generates commands for each gRPC services. The commands are named based on the name of the service method. @@ -32,7 +34,7 @@ For instance, `autocli` would generate a command named `my-method` for the `MyMe It is possible to customize the generation of transactions and queries by defining options for each service. -## Application Wiring +### Application Wiring Here are the steps to use AutoCLI: @@ -73,7 +75,7 @@ if err := rootCmd.Execute(); err != nil { } ``` -### Keyring +#### Keyring `autocli` uses a keyring for key name resolving names and signing transactions. @@ -100,7 +102,7 @@ keyring.NewAutoCLIKeyring(kb) ::: -## Signing +### Signing `autocli` supports signing transactions with the keyring. The [`cosmos.msg.v1.signer` protobuf annotation](https://docs.cosmos.network/main/build/building-modules/protobuf-annotations) defines the signer field of the message. @@ -110,7 +112,7 @@ This field is automatically filled when using the `--from` flag or defining the AutoCLI currently supports only one signer per transaction. ::: -## Module wiring & Customization +### Module wiring & Customization The `AutoCLIOptions()` method on your module allows to specify custom commands, sub-commands or flags for each service, as it was a `cobra.Command` instance, within the `RpcCommandOptions` struct. Defining such options will customize the behavior of the `autocli` command generation, which by default generates a command for each method in your gRPC service. @@ -131,31 +133,7 @@ AutoCLI can create a gov proposal of any tx by simply setting the `GovProposal` Users can however use the `--no-proposal` flag to disable the proposal creation (which is useful if the authority isn't the gov module on a chain). ::: -### Conventions for the `Use` field in Cobra - -According to the [Cobra documentation](https://pkg.go.dev/github.com/spf13/cobra#Command) the following conventions should be followed for the `Use` field in Cobra commands: - -1. **Required arguments**: - * Should not be enclosed in brackets. They can be enclosed in angle brackets `< >` for clarity. - * Example: `command ` - -2. **Optional arguments**: - * Should be enclosed in square brackets `[ ]`. - * Example: `command [optional_argument]` - -3. **Alternative (mutually exclusive) arguments**: - * Should be enclosed in curly braces `{ }`. - * Example: `command {-a | -b}` for required alternatives. - * Example: `command [-a | -b]` for optional alternatives. - -4. **Multiple arguments**: - * Indicated with `...` after the argument. - * Example: `command argument...` - -5. **Combination of options**: - * Example: `command [-F file | -D dir]... [-f format] profile` - -### Specifying Subcommands +#### Specifying Subcommands By default, `autocli` generates a command for each method in your gRPC service. However, you can specify subcommands to group related commands together. To specify subcommands, use the `autocliv1.ServiceCommandDescriptor` struct. @@ -165,7 +143,7 @@ This example shows how to use the `autocliv1.ServiceCommandDescriptor` struct to https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-beta.0/x/gov/autocli.go#L94-L97 ``` -### Positional Arguments +#### Positional Arguments By default `autocli` generates a flag for each field in your protobuf message. However, you can choose to use positional arguments instead of flags for certain fields. @@ -183,7 +161,7 @@ Then the command can be used as follows, instead of having to specify the `--add query auth account cosmos1abcd...xyz ``` -### Customising Flag Names +#### Customising Flag Names By default, `autocli` generates flag names based on the names of the fields in your protobuf message. However, you can customise the flag names by providing a `FlagOptions`. This parameter allows you to specify custom names for flags based on the names of the message fields. @@ -200,7 +178,7 @@ autocliv1.RpcCommandOptions{ `FlagsOptions` is defined like sub commands in the `AutoCLIOptions()` method on your module. -### Combining AutoCLI with Other Commands Within A Module +#### Combining AutoCLI with Other Commands Within A Module AutoCLI can be used alongside other commands within a module. For example, the `gov` module uses AutoCLI to generate commands for the `query` subcommand, but also defines custom commands for the `proposer` subcommands. @@ -212,7 +190,7 @@ https://github.com/cosmos/cosmos-sdk/blob/fa4d87ef7e6d87aaccc94c337ffd2fe90fcb7a If not set to true, `AutoCLI` will not generate commands for the module if there are already commands registered for the module (when `GetTxCmd()` or `GetQueryCmd()` are defined). -### Skip a command +#### Skip a command AutoCLI automatically skips unsupported commands when [`cosmos_proto.method_added_in` protobuf annotation](https://docs.cosmos.network/main/build/building-modules/protobuf-annotations) is present. @@ -225,7 +203,7 @@ Additionally, a command can be manually skipped using the `autocliv1.RpcCommandO } ``` -### Use AutoCLI for non module commands +#### Use AutoCLI for non module commands It is possible to use `AutoCLI` for non module commands. The trick is still to implement the `appmodule.Module` interface and append it to the `appOptions.ModuleOptions` map. @@ -235,17 +213,41 @@ For example, here is how the SDK does it for `cometbft` gRPC commands: https://github.com/cosmos/cosmos-sdk/blob/main/client/grpc/cmtservice/autocli.go#L52-L71 ``` -## Summary +#### Conventions for the `Use` field in Cobra + +According to the [Cobra documentation](https://pkg.go.dev/github.com/spf13/cobra#Command) the following conventions should be followed for the `Use` field in Cobra commands: + +1. **Required arguments**: + * Should not be enclosed in brackets. They can be enclosed in angle brackets `< >` for clarity. + * Example: `command ` + +2. **Optional arguments**: + * Should be enclosed in square brackets `[ ]`. + * Example: `command [optional_argument]` + +3. **Alternative (mutually exclusive) arguments**: + * Should be enclosed in curly braces `{ }`. + * Example: `command {-a | -b}` for required alternatives. + * Example: `command [-a | -b]` for optional alternatives. + +4. **Multiple arguments**: + * Indicated with `...` after the argument. + * Example: `command argument...` + +5. **Combination of options**: + * Example: `command [-F file | -D dir]... [-f format] profile` + +### Summary `autocli` lets you generate CLI to your Cosmos SDK-based applications without any cobra boilerplate. It allows you to easily generate CLI commands and flags from your protobuf messages, and provides many options for customising the behavior of your CLI application. To further enhance your CLI experience with Cosmos SDK-based blockchains, you can use `hubl`. `hubl` is a tool that allows you to query any Cosmos SDK-based blockchain using the new AutoCLI feature of the Cosmos SDK. With `hubl`, you can easily configure a new chain and query modules with just a few simple commands. -For more information on `hubl`, including how to configure a new chain and query a module, see the [Hubl documentation](https://docs.cosmos.network/main/tooling/hubl). +For more information on `hubl`, including how to configure a new chain and query a module, see the [Hubl documentation](https://docs.cosmos.network/main/build/tooling/hubl). # Off-Chain -Off-chain functionalities allow you to sign and verify files with two commands: +Off-chain is a `client/v2` package providing functionalities for allowing to sign and verify files with two commands: * `sign-file` for signing a file. * `verify-file` for verifying a previously signed file. @@ -275,6 +277,7 @@ The `encoding` flag lets you choose how the contents of the file should be encod "signer": "cosmos1x33fy6rusfprkntvjsfregss7rvsvyy4lkwrqu", "data": "Hello World!\n" } + ``` * `simd off-chain sign-file alice myFile.json --encoding base64` @@ -286,6 +289,7 @@ The `encoding` flag lets you choose how the contents of the file should be encod "signer": "cosmos1x33fy6rusfprkntvjsfregss7rvsvyy4lkwrqu", "data": "SGVsbG8gV29ybGQhCg==" } + ``` * `simd off-chain sign-file alice myFile.json --encoding hex` diff --git a/client/v2/autocli/flag/enum.go b/client/v2/autocli/flag/enum.go index 72b27528a9a5..db3f57627511 100644 --- a/client/v2/autocli/flag/enum.go +++ b/client/v2/autocli/flag/enum.go @@ -58,7 +58,12 @@ func (e enumValue) String() string { func (e *enumValue) Set(s string) error { valDesc, ok := e.valMap[s] if !ok { - return fmt.Errorf("%s is not a valid value for enum %s", s, e.enum.FullName()) + var validValues []string + for k := range e.valMap { + validValues = append(validValues, k) + } + + return fmt.Errorf("%s is not a valid value for enum %s. Valid values are: %s", s, e.enum.FullName(), strings.Join(validValues, ", ")) } e.value = valDesc.Number() return nil diff --git a/client/v2/autocli/msg.go b/client/v2/autocli/msg.go index b19aabc95ba0..9eb4f0444bba 100644 --- a/client/v2/autocli/msg.go +++ b/client/v2/autocli/msg.go @@ -58,7 +58,9 @@ func (b *Builder) AddMsgServiceCommands(cmd *cobra.Command, cmdDescriptor *autoc return err } - cmd.AddCommand(subCmd) + if !subCmdDescriptor.EnhanceCustomCommand { + cmd.AddCommand(subCmd) + } } if cmdDescriptor.Service == "" { diff --git a/client/v2/autocli/query.go b/client/v2/autocli/query.go index 166be5efebdc..d308bcd7633a 100644 --- a/client/v2/autocli/query.go +++ b/client/v2/autocli/query.go @@ -53,7 +53,9 @@ func (b *Builder) AddQueryServiceCommands(cmd *cobra.Command, cmdDescriptor *aut return err } - cmd.AddCommand(subCmd) + if !subCmdDesc.EnhanceCustomCommand { + cmd.AddCommand(subCmd) + } } // skip empty command descriptors diff --git a/client/v2/autocli/query_test.go b/client/v2/autocli/query_test.go index f5db25c40b36..1cbca64fb951 100644 --- a/client/v2/autocli/query_test.go +++ b/client/v2/autocli/query_test.go @@ -575,8 +575,6 @@ func TestBinaryFlag(t *testing.T) { } func TestAddressValidation(t *testing.T) { - t.Skip() // TODO(@julienrbrt) re-able with better keyring instiantiation - fixture := initFixture(t) _, err := runCmd(fixture, buildModuleQueryCommand, diff --git a/client/v2/go.mod b/client/v2/go.mod index b6d34fd22af1..8a9d7bd03c11 100644 --- a/client/v2/go.mod +++ b/client/v2/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 cosmossdk.io/x/gov v0.0.0-20231113122742-912390d5fc4a @@ -13,7 +13,7 @@ require ( github.com/cosmos/cosmos-sdk v0.53.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 gotest.tools/v3 v3.5.1 sigs.k8s.io/yaml v1.4.0 @@ -27,7 +27,7 @@ require ( cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.4.1 // indirect cosmossdk.io/math v1.3.0 - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -127,7 +127,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -164,7 +164,7 @@ require ( golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect pgregory.net/rapid v1.1.0 // indirect diff --git a/client/v2/go.sum b/client/v2/go.sum index 4ed3d699b8e8..1a32ea6bc6f2 100644 --- a/client/v2/go.sum +++ b/client/v2/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o= cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190/go.mod h1:7WUGupOvmlHJoIMBz1JbObQxeo6/TDiuDBxmtod8HRg= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= @@ -424,8 +424,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -652,8 +652,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -664,8 +664,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/core/appmodule/v2/handlers.go b/core/appmodule/v2/handlers.go index b42698b7e86f..aa11ff58a70c 100644 --- a/core/appmodule/v2/handlers.go +++ b/core/appmodule/v2/handlers.go @@ -10,8 +10,8 @@ import ( type ( // PreMsgHandler is a handler that is executed before Handler. If it errors the execution reverts. PreMsgHandler = func(ctx context.Context, msg transaction.Msg) error - // Handler handles the state transition of the provided message. - Handler = func(ctx context.Context, msg transaction.Msg) (msgResp transaction.Msg, err error) + // HandlerFunc handles the state transition of the provided message. + HandlerFunc = func(ctx context.Context, msg transaction.Msg) (msgResp transaction.Msg, err error) // PostMsgHandler runs after Handler, only if Handler does not error. If PostMsgHandler errors // then the execution is reverted. PostMsgHandler = func(ctx context.Context, msg, msgResp transaction.Msg) error @@ -19,10 +19,10 @@ type ( // PreMsgRouter is a router that allows you to register PreMsgHandlers for specific message types. type PreMsgRouter interface { - // RegisterPreHandler will register a specific message handler hooking into the message with + // RegisterPreMsgHandler will register a specific message handler hooking into the message with // the provided name. RegisterPreMsgHandler(msgName string, handler PreMsgHandler) - // RegisterGlobalPreHandler will register a global message handler hooking into any message + // RegisterGlobalPreMsgHandler will register a global message handler hooking into any message // being executed. RegisterGlobalPreMsgHandler(handler PreMsgHandler) } @@ -64,10 +64,10 @@ func RegisterMsgPreHandler[Req transaction.Msg]( // PostMsgRouter is a router that allows you to register PostMsgHandlers for specific message types. type PostMsgRouter interface { - // RegisterPostHandler will register a specific message handler hooking after the execution of message with + // RegisterPostMsgHandler will register a specific message handler hooking after the execution of message with // the provided name. RegisterPostMsgHandler(msgName string, handler PostMsgHandler) - // RegisterGlobalPostHandler will register a global message handler hooking after the execution of any message. + // RegisterGlobalPostMsgHandler will register a global message handler hooking after the execution of any message. RegisterGlobalPostMsgHandler(handler PostMsgHandler) } @@ -76,7 +76,7 @@ type HasPostMsgHandlers interface { RegisterPostMsgHandlers(router PostMsgRouter) } -// RegisterPostHandler is a helper function that modules can use to not lose type safety when registering handlers to the +// RegisterPostMsgHandler is a helper function that modules can use to not lose type safety when registering handlers to the // PostMsgRouter. Example usage: // ```go // @@ -110,9 +110,20 @@ func RegisterPostMsgHandler[Req, Resp transaction.Msg]( router.RegisterPostMsgHandler(msgName, untypedHandler) } +// Handler defines a handler descriptor. +type Handler struct { + // Func defines the actual handler, the function that runs a request and returns a response. + // Can be query handler or msg handler. + Func HandlerFunc + // MakeMsg instantiates the type of the request, can be used in decoding contexts. + MakeMsg func() transaction.Msg + // MakeMsgResp instantiates a new response, can be used in decoding contexts. + MakeMsgResp func() transaction.Msg +} + // MsgRouter is a router that allows you to register Handlers for specific message types. type MsgRouter = interface { - RegisterHandler(msgName string, handler Handler) error + RegisterHandler(handler Handler) } // HasMsgHandlers is an interface that modules must implement if they want to register Handlers. @@ -142,27 +153,34 @@ type HasQueryHandlers interface { // // func (m Module) RegisterMsgHandlers(router appmodule.MsgRouter) { // handlers := keeper.NewHandlers(m.keeper) -// err := appmodule.RegisterHandler(router, gogoproto.MessageName(types.MsgMint{}), handlers.MsgMint) +// err := appmodule.RegisterHandler(router, handlers.MsgMint) // } // // func (m Module) RegisterQueryHandlers(router appmodule.QueryRouter) { // handlers := keeper.NewHandlers(m.keeper) -// err := appmodule.RegisterHandler(router, gogoproto.MessageName(types.QueryBalanceRequest{}), handlers.QueryBalance) +// err := appmodule.RegisterHandler(router, handlers.QueryBalance) // } // // ``` -func RegisterHandler[Req, Resp transaction.Msg]( +func RegisterMsgHandler[Req, Resp any, PReq transaction.GenericMsg[Req], PResp transaction.GenericMsg[Resp]]( router MsgRouter, - msgName string, - handler func(ctx context.Context, msg Req) (msgResp Resp, err error), -) error { + handler func(ctx context.Context, msg PReq) (msgResp PResp, err error), +) { untypedHandler := func(ctx context.Context, m transaction.Msg) (transaction.Msg, error) { - typed, ok := m.(Req) + typed, ok := m.(PReq) if !ok { return nil, fmt.Errorf("unexpected type %T, wanted: %T", m, *new(Req)) } return handler(ctx, typed) } - return router.RegisterHandler(msgName, untypedHandler) + router.RegisterHandler(Handler{ + Func: untypedHandler, + MakeMsg: func() transaction.Msg { + return PReq(new(Req)) + }, + MakeMsgResp: func() transaction.Msg { + return PResp(new(Resp)) + }, + }) } diff --git a/core/server/app.go b/core/server/app.go index 9576fa8825f8..56a0c0862777 100644 --- a/core/server/app.go +++ b/core/server/app.go @@ -39,10 +39,6 @@ type TxResult struct { Resp []transaction.Msg // Error produced by the transaction. Error error - // Code produced by the transaction. - // A non-zero code is an error that is either define by the module via the cosmossdk.io/errors/v2 package - // or injected through the antehandler along the execution of the transaction. - Code uint32 // GasWanted is the maximum units of work we allow this tx to perform. GasWanted uint64 // GasUsed is the amount of gas actually consumed. diff --git a/core/testing/go.mod b/core/testing/go.mod index 8c20811c6c90..95f3b6a38c59 100644 --- a/core/testing/go.mod +++ b/core/testing/go.mod @@ -3,7 +3,7 @@ module cosmossdk.io/core/testing go 1.23 require ( - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 github.com/golang/mock v1.6.0 github.com/tidwall/btree v1.7.0 ) diff --git a/core/testing/go.sum b/core/testing/go.sum index d1db25cac6fa..9fc6d98fad48 100644 --- a/core/testing/go.sum +++ b/core/testing/go.sum @@ -1,5 +1,5 @@ -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= diff --git a/core/transaction/transaction.go b/core/transaction/transaction.go index 5211c54c66e2..3efd88b5aa29 100644 --- a/core/transaction/transaction.go +++ b/core/transaction/transaction.go @@ -10,6 +10,14 @@ type ( Identity = []byte ) +// GenericMsg defines a generic version of a Msg. +// The GenericMsg refers to the non pointer version of Msg, +// and is required to allow its instantiations in generic contexts. +type GenericMsg[T any] interface { + *T + Msg +} + // Codec defines the TX codec, which converts a TX from bytes to its concrete representation. type Codec[T Tx] interface { // Decode decodes the tx bytes into a DecodedTx, containing diff --git a/depinject/go.mod b/depinject/go.mod index 362d94e19d92..12e18e6a5c56 100644 --- a/depinject/go.mod +++ b/depinject/go.mod @@ -7,7 +7,7 @@ require ( github.com/cosmos/gogoproto v1.7.0 github.com/stretchr/testify v1.9.0 golang.org/x/exp v0.0.0-20231006140011-7918f672742d - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 gotest.tools/v3 v3.5.1 sigs.k8s.io/yaml v1.4.0 @@ -23,7 +23,7 @@ require ( golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/depinject/go.sum b/depinject/go.sum index 9cfb0b1f2115..252c8bd7d025 100644 --- a/depinject/go.sum +++ b/depinject/go.sum @@ -46,8 +46,8 @@ golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/docs/Introduction.md b/docs/Introduction.md index 80c5a7a0a9c4..5f87480aaced 100644 --- a/docs/Introduction.md +++ b/docs/Introduction.md @@ -21,7 +21,7 @@ Get familiar with the SDK and explore its main concepts. * [**Core Concepts**](learn/advanced/00-baseapp.md) - Read about the core concepts like baseapp, the store, or the server. * [**Building Modules**](build/building-modules/00-intro.md) - Discover how to build modules for the Cosmos SDK. * [**Running a Node**](https://docs.cosmos.network/main/user/run-node/keyring) - Running and interacting with nodes using the CLI and API. -* [**Modules**](./build/modules/README.md) - Explore existing modules to build your application with. +* [**Modules**](./build/building-modules/00-intro.md) - Explore existing modules to build your application with. ## Explore the Stack diff --git a/docs/architecture/PROCESS.md b/docs/architecture/PROCESS.md index bca4cdf51b15..15e11639c409 100644 --- a/docs/architecture/PROCESS.md +++ b/docs/architecture/PROCESS.md @@ -1,8 +1,8 @@ # ADR Creation Process 1. Copy the `adr-template.md` file. Use the following filename pattern: `adr-next_number-title.md` -2. Create a draft Pull Request if you want to get an early feedback. -3. Make sure the context and solution is clear and well documented. +2. Create a draft Pull Request if you want to get early feedback. +3. Make sure the context and solution are clear and well documented. 4. Add an entry to a list in the [README](./README.md) file. 5. Create a Pull Request to propose a new ADR. @@ -14,7 +14,7 @@ An ADR is a document to document an implementation and design that may or may no ADR creation is an **iterative** process. Instead of having a high amount of communication overhead, an ADR is used when there is already a decision made and implementation details need to be added. The ADR should document what the collective consensus for the specific issue is and how to solve it. -1. Every ADR should start with either an RFC or discussion where consensus has been met. +1. Every ADR should start with either an RFC or a discussion where consensus has been met. 2. Once consensus is met, a GitHub Pull Request (PR) is created with a new document based on the `adr-template.md`. @@ -44,9 +44,9 @@ DRAFT -> PROPOSED -> LAST CALL yyyy-mm-dd -> ACCEPTED | REJECTED -> SUPERSEDED b ABANDONED ``` -* `DRAFT`: [optional] an ADR which is work in progress, not being ready for a general review. This is to present an early work and get an early feedback in a Draft Pull Request form. -* `PROPOSED`: an ADR covering a full solution architecture and still in the review - project stakeholders haven't reached an agreed yet. -* `LAST CALL `: [optional] clear notify that we are close to accept updates. Changing a status to `LAST CALL` means that social consensus (of Cosmos SDK maintainers) has been reached and we still want to give it a time to let the community react or analyze. +* `DRAFT`: [optional] an ADR which is a work in progress, not being ready for a general review. This is to present an early work and get early feedback in a Draft Pull Request form. +* `PROPOSED`: an ADR covering a full solution architecture and still in the review - project stakeholders haven't reached an agreement yet. +* `LAST CALL `: [optional] Notify that we are close to accepting updates. Changing a status to `LAST CALL` means that social consensus (of Cosmos SDK maintainers) has been reached and we still want to give it a time to let the community react or analyze. * `ACCEPTED`: ADR which will represent a currently implemented or to be implemented architecture design. * `REJECTED`: ADR can go from PROPOSED or ACCEPTED to rejected if the consensus among project stakeholders will decide so. * `SUPERSEDED by ADR-xxx`: ADR which has been superseded by a new ADR. diff --git a/docs/architecture/adr-043-nft-module.md b/docs/architecture/adr-043-nft-module.md index 5968eb1305aa..40c21cd3c6d9 100644 --- a/docs/architecture/adr-043-nft-module.md +++ b/docs/architecture/adr-043-nft-module.md @@ -17,9 +17,9 @@ This ADR defines the `x/nft` module which is a generic implementation of NFTs, r * `MsgNewClass` - Receive the user's request to create a class, and call the `NewClass` of the `x/nft` module. * `MsgUpdateClass` - Receive the user's request to update a class, and call the `UpdateClass` of the `x/nft` module. -* `MsgMintNFT` - Receive the user's request to mint a nft, and call the `MintNFT` of the `x/nft` module. -* `BurnNFT` - Receive the user's request to burn a nft, and call the `BurnNFT` of the `x/nft` module. -* `UpdateNFT` - Receive the user's request to update a nft, and call the `UpdateNFT` of the `x/nft` module. +* `MsgMintNFT` - Receive the user's request to mint an NFT, and call the `MintNFT` of the `x/nft` module. +* `BurnNFT` - Receive the user's request to burn an NFT, and call the `BurnNFT` of the `x/nft` module. +* `UpdateNFT` - Receive the user's request to update an NFT, and call the `UpdateNFT` of the `x/nft` module. ## Context @@ -48,7 +48,7 @@ We create a `x/nft` module, which contains the following functionality: * Expose external `Message` interface for users to transfer ownership of their NFTs. * Query NFTs and their supply information. -The proposed module is a base module for NFT app logic. It's goal it to provide a common layer for storage, basic transfer functionality and IBC. The module should not be used as a standalone. +The proposed module is a base module for NFT app logic. Its goal is to provide a common layer for storage, basic transfer functionality and IBC. The module should not be used as a standalone. Instead an app should create a specialized module to handle app specific logic (eg: NFT ID construction, royalty), user level minting and burning. Moreover an app specialized module should handle auxiliary data to support the app logic (eg indexes, ORM, business data). All data carried over IBC must be part of the `NFT` or `Class` type described below. The app specific NFT data should be encoded in `NFT.data` for cross-chain integrity. Other objects related to NFT, which are not important for integrity can be part of the app specific module. @@ -58,7 +58,7 @@ All data carried over IBC must be part of the `NFT` or `Class` type described be We propose two main types: * `Class` -- describes NFT class. We can think about it as a smart contract address. -* `NFT` -- object representing unique, non fungible asset. Each NFT is associated with a Class. +* `NFT` -- object representing unique, non-fungible asset. Each NFT is associated with a class. #### Class @@ -81,7 +81,7 @@ message Class { * `symbol` is the symbol usually shown on exchanges for the NFT class; _optional_ * `description` is a detailed description of the NFT class; _optional_ * `uri` is a URI for the class metadata stored off chain. It should be a JSON file that contains metadata about the NFT class and NFT data schema ([OpenSea example](https://docs.opensea.io/docs/contract-level-metadata)); _optional_ -* `uri_hash` is a hash of the document pointed by uri; _optional_ +* `uri_hash` is a hash of the document pointed by URI; _optional_ * `data` is app specific metadata of the class; _optional_ #### NFT @@ -107,7 +107,7 @@ message NFT { * `uri` is a URI for the NFT metadata stored off chain. Should point to a JSON file that contains metadata about this NFT (Ref: [ERC721 standard and OpenSea extension](https://docs.opensea.io/docs/metadata-standards)); _required_ * `uri_hash` is a hash of the document pointed by uri; _optional_ -* `data` is an app specific data of the NFT. CAN be used by composing modules to specify additional properties of the NFT; _optional_ +* `data` is an app specific data of the NFT. Can be used by composing modules to specify additional properties of the NFT; _optional_ This ADR doesn't specify values that `data` can take; however, best practices recommend upper-level NFT modules clearly specify their contents. Although the value of this field doesn't provide the additional context required to manage NFT records, which means that the field can technically be removed from the specification, the field's existence allows basic informational/UI functionality. diff --git a/docs/architecture/adr-053-go-module-refactoring.md b/docs/architecture/adr-053-go-module-refactoring.md index d15c390191cc..a58d9ce021bc 100644 --- a/docs/architecture/adr-053-go-module-refactoring.md +++ b/docs/architecture/adr-053-go-module-refactoring.md @@ -70,7 +70,7 @@ clear improvements to be made or to remove legacy dependencies (for instance on amino or gogo proto), as long the old package attempts to avoid API breakage with aliases and wrappers * care should be taken when simply trying to turn an existing package into a -new go module: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. +new go module: https://go.dev/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository. In general, it seems safer to just create a new module path (appending v2, v3, etc. if necessary), rather than trying to make an old package a new module. diff --git a/docs/architecture/adr-069-gov-improvements.md b/docs/architecture/adr-069-gov-improvements.md index af5b12645205..1ef6971c713d 100644 --- a/docs/architecture/adr-069-gov-improvements.md +++ b/docs/architecture/adr-069-gov-improvements.md @@ -6,7 +6,7 @@ ## Status -ACCEPTED +ACCEPTED - Implemented ## Abstract diff --git a/docs/build/abci/00-introduction.md b/docs/build/abci/00-introduction.md index 6b7cd8ec3c89..7d955d41d956 100644 --- a/docs/build/abci/00-introduction.md +++ b/docs/build/abci/00-introduction.md @@ -19,7 +19,7 @@ The 5 methods introduced during ABCI 2.0 (compared to ABCI v0) are: Based on validator voting power, CometBFT chooses a block proposer and calls `PrepareProposal` on the block proposer's application (Cosmos SDK). The selected block proposer is responsible for collecting outstanding transactions from the mempool, adhering to the application's specifications. The application can enforce custom transaction ordering and incorporate additional transactions, potentially generated from vote extensions in the previous block. -To perform this manipulation on the application side, a custom handler must be implemented. By default, the Cosmos SDK provides `PrepareProposalHandler`, used in conjunction with an application specific mempool. A custom handler can be written by application developer, if a noop handler provided, all transactions are considered valid. Please see [this](https://github.com/fatal-fruit/abci-workshop) tutorial for more information on custom handlers. +To perform this manipulation on the application side, a custom handler must be implemented. By default, the Cosmos SDK provides `PrepareProposalHandler`, used in conjunction with an application specific mempool. A custom handler can be written by application developer, if a noop handler provided, all transactions are considered valid. Please note that vote extensions will only be available on the following height in which vote extensions are enabled. More information about vote extensions can be found [here](https://docs.cosmos.network/main/build/abci/vote-extensions). diff --git a/docs/build/abci/01-prepare-proposal.md b/docs/build/abci/01-prepare-proposal.md index c77c9094d450..eaa5473d8f1b 100644 --- a/docs/build/abci/01-prepare-proposal.md +++ b/docs/build/abci/01-prepare-proposal.md @@ -29,7 +29,7 @@ selected DO NOT exceed the maximum block gas (if set) and the maximum bytes prov by `req.MaxBytes`. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/abci_utils.go +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/baseapp/abci_utils.go ``` This default implementation can be overridden by the application developer in @@ -38,7 +38,7 @@ favor of a custom implementation in [`app_di.go`](https://docs.cosmos.network/ma ```go prepareOpt := func(app *baseapp.BaseApp) { abciPropHandler := baseapp.NewDefaultProposalHandler(mempool, app) - app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())) + app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler()) } baseAppOptions = append(baseAppOptions, prepareOpt) diff --git a/docs/build/abci/02-process-proposal.md b/docs/build/abci/02-process-proposal.md index 834ba3b90c48..7768890bdae9 100644 --- a/docs/build/abci/02-process-proposal.md +++ b/docs/build/abci/02-process-proposal.md @@ -14,12 +14,12 @@ and `ProcessProposal` for the new proposal. Here is the implementation of the default implementation: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/abci_utils.go#L153-L159 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/baseapp/abci_utils.go#L224-L231 ``` Like `PrepareProposal` this implementation is the default and can be modified by the application developer in [`app_di.go`](https://docs.cosmos.network/main/build/building-apps/app-go-di). If you decide to implement -your own `ProcessProposal` handler, you must be sure to ensure that the transactions +your own `ProcessProposal` handler, you must ensure that the transactions provided in the proposal DO NOT exceed the maximum block gas and `maxtxbytes` (if set). ```go diff --git a/docs/build/abci/03-vote-extensions.md b/docs/build/abci/03-vote-extensions.md index 59b00c89854a..26cbfd1a296d 100644 --- a/docs/build/abci/03-vote-extensions.md +++ b/docs/build/abci/03-vote-extensions.md @@ -8,7 +8,7 @@ defined in ABCI++. ## Extend Vote ABCI2.0 (colloquially called ABCI++) allows an application to extend a pre-commit vote with arbitrary data. This process does NOT have to be deterministic, and the data returned can be unique to the -validator process. The Cosmos SDK defines [`baseapp.ExtendVoteHandler`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.1/types/abci.go#L26-L27): +validator process. The Cosmos SDK defines [`baseapp.ExtendVoteHandler`](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/types/abci.go#L26-L27): ```go type ExtendVoteHandler func(Context, *abci.ExtendVoteRequest) (*abci.ExtendVoteResponse, error) @@ -35,7 +35,7 @@ Click [here](https://docs.cosmos.network/main/build/abci/vote-extensions) if you Similar to extending a vote, an application can also verify vote extensions from other validators when validating their pre-commits. For a given vote extension, -this process MUST be deterministic. The Cosmos SDK defines [`sdk.VerifyVoteExtensionHandler`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.1/types/abci.go#L29-L31): +this process MUST be deterministic. The Cosmos SDK defines [`sdk.VerifyVoteExtensionHandler`](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/types/abci.go#L29-L31): ```go type VerifyVoteExtensionHandler func(Context, *abci.VerifyVoteExtensionRequest) (*abci.VerifyVoteExtensionResponse, error) diff --git a/docs/build/abci/04-checktx.md b/docs/build/abci/04-checktx.md new file mode 100644 index 000000000000..a2c5f2d707d6 --- /dev/null +++ b/docs/build/abci/04-checktx.md @@ -0,0 +1,50 @@ +# CheckTx + +CheckTx is called by the `BaseApp` when comet receives a transaction from a client, over the p2p network or RPC. The CheckTx method is responsible for validating the transaction and returning an error if the transaction is invalid. + +```mermaid +graph TD + subgraph SDK[Cosmos SDK] + B[Baseapp] + A[AnteHandlers] + B <-->|Validate TX| A + end + C[CometBFT] <-->|CheckTx|SDK + U((User)) -->|Submit TX| C + N[P2P] -->|Receive TX| C +``` + +```go reference +https://github.com/cosmos/cosmos-sdk/blob/31c604762a434c7b676b6a89897ecbd7c4653a23/baseapp/abci.go#L350-L390 +``` + +## CheckTx Handler + +`CheckTxHandler` allows users to extend the logic of `CheckTx`. `CheckTxHandler` is called by pasding context and the transaction bytes received through ABCI. It is required that the handler returns deterministic results given the same transaction bytes. + +:::note +we return the raw decoded transaction here to avoid decoding it twice. +::: + +```go +type CheckTxHandler func(ctx sdk.Context, tx []byte) (Tx, error) +``` + +Setting a custom `CheckTxHandler` is optional. It can be done from your app.go file: + +```go +func NewSimApp( + logger log.Logger, + db corestore.KVStoreWithBatch, + traceStore io.Writer, + loadLatest bool, + appOpts servertypes.AppOptions, + baseAppOptions ...func(*baseapp.BaseApp), +) *SimApp { + ... + // Create ChecktxHandler + checktxHandler := abci.NewCustomCheckTxHandler(...) + app.SetCheckTxHandler(checktxHandler) + ... +} +``` diff --git a/docs/build/building-apps/02-app-mempool.md b/docs/build/building-apps/02-app-mempool.md index 45719af4824d..d22832b3f166 100644 --- a/docs/build/building-apps/02-app-mempool.md +++ b/docs/build/building-apps/02-app-mempool.md @@ -22,7 +22,7 @@ Notably it introduces the `PrepareProposal` and `ProcessProposal` steps of ABCI+ ## Mempool -+ Before we delve into `PrepareProposal` and `ProcessProposal`, let's first walk through the mempool concepts. +* Before we delve into `PrepareProposal` and `ProcessProposal`, let's first walk through the mempool concepts. There are countless designs that an application developer can write for a mempool, the SDK opted to provide only simple mempool implementations. Namely, the SDK provides the following mempools: diff --git a/docs/build/building-apps/03-app-upgrade.md b/docs/build/building-apps/03-app-upgrade.md index a26cdcce0fb7..b9c487534dea 100644 --- a/docs/build/building-apps/03-app-upgrade.md +++ b/docs/build/building-apps/03-app-upgrade.md @@ -41,7 +41,7 @@ and gracefully exit. Generally the application binary will restart on exit, but then will execute this BeginBlocker again and exit, causing a restart loop. Either the operator can manually install the new software, or you can make use of an external watcher daemon to possibly download and then switch binaries, -also potentially doing a backup. The SDK tool for doing such, is called [Cosmovisor](https://docs.cosmos.network/main/tooling/cosmovisor). +also potentially doing a backup. The SDK tool for doing such, is called [Cosmovisor](https://docs.cosmos.network/main/build/tooling/cosmovisor). When the binary restarts with the upgraded version (here v0.40.0), it will detect we have registered the "testnet-v2" upgrade handler in the code, and realize it is the new version. It then will run the upgrade handler @@ -131,7 +131,7 @@ to lose connectivity with the exiting nodes, thus this module prefers to just ha ## Automation -Read more about [Cosmovisor](https://docs.cosmos.network/main/tooling/cosmovisor), the tool for automating upgrades. +Read more about [Cosmovisor](https://docs.cosmos.network/main/build/tooling/cosmovisor), the tool for automating upgrades. ## Canceling Upgrades diff --git a/docs/build/building-apps/06-app-go-genesis.md b/docs/build/building-apps/06-app-go-genesis.md new file mode 100644 index 000000000000..b9902858d7fe --- /dev/null +++ b/docs/build/building-apps/06-app-go-genesis.md @@ -0,0 +1,47 @@ +--- +sidebar_position: 1 +--- + +### Modifying the `DefaultGenesis` + +It is possible to modify the DefaultGenesis parameters for modules by wrapping the module, providing it to the `*module.Manager` and injecting it with `depinject`. + +Example ( staking ) : + +```go +type CustomStakingModule struct { + staking.AppModule + cdc codec.Codec +} + +// DefaultGenesis will override the Staking module DefaultGenesis AppModuleBasic method. +func (cm CustomStakingModule) DefaultGenesis() json.RawMessage { + params := stakingtypes.DefaultParams() + params.BondDenom = "mydenom" + + return cm.cdc.MustMarshalJSON(&stakingtypes.GenesisState{ + Params: params, + }) +} + +// option 1 ( for depinject users ): override previous module manager +depinject.Inject( +// ... provider/invoker/supplier +&moduleManager, +) + +oldStakingModule,_ := moduleManager.Modules()[stakingtypes.ModuleName].(staking.AppModule) +moduleManager.Modules()[stakingtypes.ModuleName] = CustomStakingModule{ + AppModule: oldStakingModule, + cdc: appCodec, +} + +// option 2 ( for non depinject users ): use new module manager +moduleManager := module.NewManagerFromMap(map[string]appmodule.AppModule{ +stakingtypes.ModuleName: CustomStakingModule{cdc: appCodec, AppModule: staking.NewAppModule(...)}, +// other modules ... +}) + +// set the module manager +app.ModuleManager = moduleManager +``` diff --git a/docs/build/building-apps/06-system-tests.md b/docs/build/building-apps/06-system-tests.md new file mode 100644 index 000000000000..eb6d61ffea46 --- /dev/null +++ b/docs/build/building-apps/06-system-tests.md @@ -0,0 +1,58 @@ +--- +sidebar_position: 1 +--- + +# System Tests + +System tests provide a framework to write and execute black box tests against a running chain. This adds another level +of confidence on top of unit, integration, and simulations tests, ensuring that business-critical scenarios +(like double signing prevention) or scenarios that can't be tested otherwise (like a chain upgrade) are covered. + +## Vanilla Go for Flow Control + +System tests are vanilla Go tests that interact with the compiled chain binary. The `test runner` component starts a +local testnet of 4 nodes (by default) and provides convenient helper methods for accessing the +`system under test (SUT)`. +A `CLI wrapper` makes it easy to access keys, submit transactions, or execute operations. Together, these components +enable the replication and validation of complex business scenarios. + +Here's an example of a double signing test, where a new node is added with the same key as the first validator: +[double signing test example](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/tests/systemtests/fraud_test.go) + +The [getting started tutorial](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/tests/systemtests/getting_started.md) +contains a step-by-step guide to building and running your first system test. It covers setting chain state via genesis +or +transactions and validation via transaction response or queries. + +## Design Principles and Guidelines + +System tests are slower compared to unit or integration tests as they interact with a running chain. Therefore, certain +principles can guide their usage: + +- **Perspective:** Tests should mimic a human interacting with the chain from the outside. Initial states can be set via + genesis or transactions to support a test scenario. +- **Roles:** The user can have multiple roles such as validator, delegator, granter, or group admin. +- **Focus:** Tests should concentrate on happy paths or business-critical workflows. Unit and integration tests are + better suited for more fine-grained testing. +- **Workflows:** Test workflows and scenarios, not individual units. Given the high setup costs, it is reasonable to + combine multiple steps and assertions in a single test method. +- **Genesis Mods:** Genesis modifications can incur additional time costs for resetting dirty states. Reuse existing + accounts (node0..n) whenever possible. +- **Framework:** Continuously improve the framework for better readability and reusability. + +## Errors and Debugging + +All output is logged to `systemtests/testnet/node{0..n}.out`. Usually, `node0.out` is very noisy as it receives the CLI +connections. Prefer any other node's log to find stack traces or error messages. + +Using system tests for state setup during debugging has become very handy: + +- Start the test with one node only and verbose output: + + ```sh + go test -v -tags=system_test ./ --run TestAccountCreation --verbose --nodes-count=1 + ``` + +- Copy the CLI command for the transaction and modify the test to stop before the command +- Start the node with `--home=/tests/systemtests/testnet/node0//` in debug mode +- Execute CLI command from shell and enter breakpoints diff --git a/docs/build/building-modules/06-beginblock-endblock.md b/docs/build/building-modules/06-beginblock-endblock.md index 51b72b7f056c..21c1a3303d3f 100644 --- a/docs/build/building-modules/06-beginblock-endblock.md +++ b/docs/build/building-modules/06-beginblock-endblock.md @@ -24,7 +24,7 @@ When needed, `BeginBlocker` and `EndBlocker` are implemented as part of the [`Ha The actual implementation of `BeginBlocker` and `EndBlocker` in `abci.go` are very similar to that of a [`Msg` service](./03-msg-services.md): -* They generally use the [`keeper`](./06-keeper.md) and [`ctx`](../../learn/advanced/02-context.md) to retrieve information about the latest state. +* They generally use the [`keeper`](./06-keeper.md) and [`ctx`](https://pkg.go.dev/context) to retrieve information about the latest state. * If needed, they use the `keeper` and `ctx` to trigger state-transitions. * If needed, they can emit [`events`](../../learn/advanced/08-events.md) via the `environments`'s `EventManager`. @@ -35,13 +35,20 @@ It is possible for developers to define the order of execution between the `Begi See an example implementation of `BeginBlocker` from the `distribution` module: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/distribution/abci.go#L14-L38 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/distribution/keeper/abci.go#L13-L40 ``` -and an example implementation of `EndBlocker` from the `staking` module: +and an example of `EndBlocker` from the `gov` module: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/abci.go#L22-L27 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/keeper/abci.go#L22 ``` +and an example implementation of `EndBlocker` with validator updates from the `staking` module: + +```go reference +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/staking/keeper/abci.go#L12-L17 +``` + + diff --git a/docs/build/building-modules/06-keeper.md b/docs/build/building-modules/06-keeper.md index 1302a46d6324..0bd776ff9b9d 100644 --- a/docs/build/building-modules/06-keeper.md +++ b/docs/build/building-modules/06-keeper.md @@ -41,14 +41,14 @@ type Keeper struct { For example, here is the type definition of the `keeper` from the `staking` module: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/keeper.go#L23-L31 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/staking/keeper/keeper.go#L54-L115 ``` Let us go through the different parameters: * An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in an `expected_keepers.go` file in the root of the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself. * `KVStoreService`s grant access to the store(s) of the [multistore](../../learn/advanced/04-store.md) managed by the module. They should always remain unexposed to external modules. -* `cdc` is the [codec](../../learn/advanced/05-encoding.md) used to marshall and unmarshall structs to/from `[]byte`. The `cdc` can be any of `codec.BinaryCodec`, `codec.JSONCodec` or `codec.Codec` based on your requirements. It can be either a proto or amino codec as long as they implement these interfaces. +* `cdc` is the [codec](../../learn/advanced/05-encoding.md) used to marshal and unmarshal structs to/from `[]byte`. The `cdc` can be any of `codec.BinaryCodec`, `codec.JSONCodec` or `codec.Codec` based on your requirements. It can be either a proto or amino codec as long as they implement these interfaces. * The authority listed is a module account or user account that has the right to change module level parameters. Previously this was handled by the param module, which has been deprecated. Of course, it is possible to define different types of internal `keeper`s for the same module (e.g. a read-only `keeper`). Each type of `keeper` comes with its own constructor function, which is called from the [application's constructor function](../../learn/beginner/00-app-anatomy.md). This is where `keeper`s are instantiated, and where developers make sure to pass correct instances of modules' `keeper`s to other modules that require them. @@ -60,3 +60,10 @@ Of course, it is possible to define different types of internal `keeper`s for th State management is recommended to be done via [Collections](../packages/collections) + +## State Management + +In the Cosmos SDK, it is crucial to be methodical and selective when managing state within a module, as improper state management can lead to inefficiency, security risks, and scalability issues. Not all data belongs in the on-chain state; it's important to store only essential blockchain data that needs to be verified by consensus. Storing unnecessary information, especially client-side data, can bloat the state and slow down performance. Instead, developers should focus on using an off-chain database to handle supplementary data, extending the API as needed. This approach minimizes on-chain complexity, optimizes resource usage, and keeps the blockchain state lean and efficient, ensuring scalability and smooth operations. + + +The Cosmos SDK leverages Protocol Buffers (protobuf) for efficient state management, providing a well-structured, binary encoding format that ensures compatibility and performance across different modules. The SDK’s recommended approach for managing state is through the [collections package](../pacakges/02-collections.md), which simplifies state handling by offering predefined data structures like maps and indexed sets, reducing the complexity of managing raw state data. While users can opt for custom encoding schemes if they need more flexibility or have specialized requirements, they should be aware that such custom implementations may not integrate seamlessly with indexers that decode state data on the fly. This could lead to challenges in data retrieval, querying, and interoperability, making protobuf a safer and more future-proof choice for most use cases. diff --git a/docs/build/building-modules/12-errors.md b/docs/build/building-modules/12-errors.md index b6935e62666e..20c7c512173d 100644 --- a/docs/build/building-modules/12-errors.md +++ b/docs/build/building-modules/12-errors.md @@ -14,6 +14,10 @@ common or general errors which can be further wrapped to provide additional spec There are two ways to return errors. You can register custom errors with a codespace that is meant to provide more information to clients and normal go errors. The Cosmos SDK uses a mixture of both. +:::Note +Errors v2 has been created as a zero dependency errors package. GRPC errors and tracing support is removed natively from the errors package. Users are required to wrap stack traces and add tracing information to their errors. +::: + :::Warning If errors are registered they are part of consensus and cannot be changed in a minor release ::: diff --git a/docs/build/building-modules/16-testing.md b/docs/build/building-modules/16-testing.md index f2fafa36fd9d..65ed52a8a142 100644 --- a/docs/build/building-modules/16-testing.md +++ b/docs/build/building-modules/16-testing.md @@ -86,38 +86,26 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/tests/integration/bank ## Simulations -Simulations uses as well a minimal application, built with [`depinject`](../packages/01-depinject.md): +Simulations fuzz tests for deterministic message execution. They use a minimal application, built with [`depinject`](../packages/01-depinject.md): :::note -You can as well use the `AppConfig` `configurator` for creating an `AppConfig` [inline](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/slashing/app_test.go#L54-L62). There is no difference between those two ways, use whichever you prefer. +Simulations have been refactored to message factories ::: -Following is an example for `x/gov/` simulations: +An example for `x/bank/` simulations: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/gov/simulation/operations_test.go#L406-L430 +https://github.com/cosmos/cosmos-sdk/blob/release/v0.52.x/x/bank/simulation/msg_factory.go#L13-L20 ``` -```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/gov/simulation/operations_test.go#L90-L132 -``` - -## End-to-end Tests +## System Tests -End-to-end tests are at the top of the [test pyramid](https://martinfowler.com/articles/practical-test-pyramid.html). -They must test the whole application flow, from the user perspective (for instance, CLI tests). They are located under [`/tests/e2e`](https://github.com/cosmos/cosmos-sdk/tree/main/tests/e2e). +System tests are at the top of the [test pyramid](https://martinfowler.com/articles/practical-test-pyramid.html). +They test the whole application flow as black box, from the user perspective. They are located under [`/tests/systemtests`](https://github.com/cosmos/cosmos-sdk/tree/main/tests/systemtests). - -For that, the SDK is using `simapp` but you should use your own application (`appd`). -Here are some examples: +For that, the SDK is using the `simapp` binary, but you should use your own binary. +More details about system test can be found in [building-apps](https://docs.cosmos.network/main/build/building-apps/06-system-tests.md) -* SDK E2E tests: . -* Cosmos Hub E2E tests: . -* Osmosis E2E tests: . - -:::note warning -The SDK is in the process of creating its E2E tests, as defined in [ADR-59](https://docs.cosmos.network/main/build/architecture/adr-059-test-scopes). This page will eventually be updated with better examples. -::: ## Learn More diff --git a/docs/build/packages/README.md b/docs/build/packages/README.md index d7a115b263de..cbb150f501b3 100644 --- a/docs/build/packages/README.md +++ b/docs/build/packages/README.md @@ -9,31 +9,45 @@ It lists all standalone Go modules that are part of the Cosmos SDK. :::tip For more information on SDK modules, see the [SDK Modules](https://docs.cosmos.network/main/modules) section. -For more information on SDK tooling, see the [Tooling](https://docs.cosmos.network/main/tooling) section. +For more information on SDK tooling, see the [Tooling](https://docs.cosmos.network/main/build/tooling) section. ::: ## Core -* [Core](https://pkg.go.dev/cosmossdk.io/core) - Core library defining SDK interfaces ([ADR-063](https://docs.cosmos.network/main/architecture/adr-063-core-module-api)) +* [Core](https://pkg.go.dev/cosmossdk.io/core) - Core library defining SDK modules and Server core interfaces ([ADR-063](https://docs.cosmos.network/main/architecture/adr-063-core-module-api)) * [API](https://pkg.go.dev/cosmossdk.io/api) - API library containing generated SDK Pulsar API * [Store](https://pkg.go.dev/cosmossdk.io/store) - Implementation of the Cosmos SDK store +* [Store/v2](https://pkg.go.dev/cosmossdk.io/store/v2) - Implementation of the Cosmos SDK store + +## V2 + +* [Server/v2/stf](https://pkg.go.dev/cosmossdk.io/server/v2/stf) - State Transition Function (STF) library for Cosmos SDK v2 +* [Server/v2/appmanager](https://pkg.go.dev/cosmossdk.io/server/v2/appmanager) - App coordinator for Cosmos SDK v2 +* [runtime/v2](https://pkg.go.dev/cosmossdk.io/runtime/v2) - Runtime library for Cosmos SDK v2 +* [Server/v2](https://pkg.go.dev/cosmossdk.io/server/v2) - Global server library for Cosmos SDK v2 +* [Server/v2/cometbft](https://pkg.go.dev/cosmossdk.io/server/v2/cometbft) - CometBFT Server implementation for Cosmos SDK v2 ## State Management * [Collections](./02-collections.md) - State management library * [ORM](./03-orm.md) - State management library +* [Schema](https://pkg.go.dev/cosmossdk.io/schema) - Logical representation of module state schemas +* [PostgreSQL indexer](https://pkg.go.dev/cosmossdk.io/indexer/postgres) - PostgreSQL indexer for Cosmos SDK modules -## Automation +## UX * [Depinject](./01-depinject.md) - Dependency injection framework * [Client/v2](https://pkg.go.dev/cosmossdk.io/client/v2) - Library powering [AutoCLI](https://docs.cosmos.network/main/core/autocli) ## Utilities +* [Core/Testing](https://pkg.go.dev/cosmossdk.io/core/testing) - Mocking library for SDK modules * [Log](https://pkg.go.dev/cosmossdk.io/log) - Logging library * [Errors](https://pkg.go.dev/cosmossdk.io/errors) - Error handling library +* [Errors/v2](https://pkg.go.dev/cosmossdk.io/errors/v2) - Error handling library * [Math](https://pkg.go.dev/cosmossdk.io/math) - Math library for SDK arithmetic operations ## Example +* [SimApp v2](https://pkg.go.dev/cosmossdk.io/simapp/v2) - SimApp/v2 is **the** sample Cosmos SDK v2 chain. This package should not be imported in your application. * [SimApp](https://pkg.go.dev/cosmossdk.io/simapp) - SimApp is **the** sample Cosmos SDK chain. This package should not be imported in your application. diff --git a/docs/build/tooling/00-protobuf.md b/docs/build/tooling/00-protobuf.md index d9a210a78577..849a7974eab7 100644 --- a/docs/build/tooling/00-protobuf.md +++ b/docs/build/tooling/00-protobuf.md @@ -4,21 +4,17 @@ sidebar_position: 1 # Protocol Buffers -It is known that Cosmos SDK uses protocol buffers extensively, this document is meant to provide a guide on how it is used in the cosmos-sdk. +Cosmos SDK uses protocol buffers extensively, this document is meant to provide a guide on how it is used in the cosmos-sdk. -To generate the proto file, the Cosmos SDK uses a docker image, this image is provided to all to use as well. The latest version is `ghcr.io/cosmos/proto-builder:0.12.x` +To generate the proto file, the Cosmos SDK uses a docker image, this image is provided to all to use as well. The latest version is `ghcr.io/cosmos/proto-builder:0.15.x` Below is the example of the Cosmos SDK's commands for generating, linting, and formatting protobuf files that can be reused in any applications makefile. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/Makefile#L411-L432 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/scripts/build/protobuf.mk#L1-L10 ``` -The script used to generate the protobuf files can be found in the `scripts/` directory. - -```shell reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/scripts/protocgen.sh -``` +The [`protocgen.sh`](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/scripts/protocgen.sh) script used to generate the protobuf files via buf can be found in the `scripts/` directory. ## Buf @@ -36,7 +32,9 @@ https://github.com/cosmos/cosmos-sdk/blob/main/buf.work.yaml#L6-L9 ### Proto Directory -Next is the `proto/` directory where all of our protobuf files live. In here there are many different buf files defined each serving a different purpose. +The `proto/` directory where all of global protobuf files live. +In here there are many different buf files defined each serving a different purpose. +Modules proto files are defined in their respective module directories (in the SDK `x/{moduleName}/proto`). ```bash ├── README.md @@ -50,8 +48,6 @@ Next is the `proto/` directory where all of our protobuf files live. In here the └── tendermint ``` -The above diagram all the files and directories within the Cosmos SDK `proto/` directory. - #### `buf.gen.gogo.yaml` `buf.gen.gogo.yaml` defines how the protobuf files should be generated for use with in the module. This file uses [gogoproto](https://github.com/gogo/protobuf), a separate generator from the google go-proto generator that makes working with various objects more ergonomic, and it has more performant encode and decode steps @@ -60,10 +56,6 @@ The above diagram all the files and directories within the Cosmos SDK `proto/` d https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.gen.gogo.yaml#L1-L9 ``` -:::tip -Example of how to define `gen` files can be found [here](https://docs.buf.build/tour/generate-go-code) -::: - #### `buf.gen.pulsar.yaml` `buf.gen.pulsar.yaml` defines how protobuf files should be generated using the [new golang apiv2 of protobuf](https://go.dev/blog/protobuf-apiv2). This generator is used instead of the google go-proto generator because it has some extra helpers for Cosmos SDK applications and will have more performant encode and decode than the google go-proto generator. You can follow the development of this generator [here](https://github.com/cosmos/cosmos-proto). @@ -72,10 +64,6 @@ Example of how to define `gen` files can be found [here](https://docs.buf.build/ https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.gen.pulsar.yaml#L1-L18 ``` -:::tip -Example of how to define `gen` files can be found [here](https://docs.buf.build/tour/generate-go-code) -::: - #### `buf.gen.swagger.yaml` `buf.gen.swagger.yaml` generates the swagger documentation for the query and messages of the chain. This will only define the REST API end points that were defined in the query and msg servers. You can find examples of this [here](https://github.com/cosmos/cosmos-sdk/blob/main/x/bank/proto/cosmos/bank/v1beta1/query.proto) @@ -84,10 +72,6 @@ Example of how to define `gen` files can be found [here](https://docs.buf.build/ https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.gen.swagger.yaml#L1-L6 ``` -:::tip -Example of how to define `gen` files can be found [here](https://docs.buf.build/tour/generate-go-code) -::: - #### `buf.lock` This is an autogenerated file based off the dependencies required by the `.gen` files. There is no need to copy the current one. If you depend on cosmos-sdk proto definitions a new entry for the Cosmos SDK will need to be provided. The dependency you will need to use is `buf.build/cosmos/cosmos-sdk`. @@ -100,14 +84,11 @@ https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.lock#L1-L16 `buf.yaml` defines the [name of your package](https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.yaml#L3), which [breakage checker](https://buf.build/docs/tutorials/getting-started-with-buf-cli#detect-breaking-changes) to use and how to [lint your protobuf files](https://buf.build/docs/tutorials/getting-started-with-buf-cli#lint-your-api). +It is advised to use a tagged version of the buf modules corresponding to the version of the Cosmos SDK being are used. + ```go reference https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.yaml#L1-L24 ``` We use a variety of linters for the Cosmos SDK protobuf files. The repo also checks this in ci. - A reference to the github actions can be found [here](https://github.com/cosmos/cosmos-sdk/blob/main/.github/workflows/proto.yml#L1-L32) - -```go reference -https://github.com/cosmos/cosmos-sdk/blob/main/.github/workflows/proto.yml#L1-L32 -``` diff --git a/docs/learn/advanced/05-encoding.md b/docs/learn/advanced/05-encoding.md index 6df0dda2ec14..4a3af677d61d 100644 --- a/docs/learn/advanced/05-encoding.md +++ b/docs/learn/advanced/05-encoding.md @@ -47,7 +47,7 @@ via Protobuf. This means that modules may use Protobuf encoding, but the types m implement `ProtoMarshaler`. If modules wish to avoid implementing this interface for their types, this is autogenerated via [buf](https://buf.build/) -If modules use [Collections](../../build/packages/02-collections.md) or [ORM](../../build/packages/03-orm.md), encoding and decoding are handled, marshal and unmarshal should not be handled manually unless for specific cases identified by the developer. +Modules are recommended to use [collections](../../build/packages/02-collections.md) for handling encoding and decoding of state. Usage of collections handles marshal and unmarshal for you. By default protobuf is used but other encodings can be used if preferred. ### Gogoproto @@ -78,15 +78,15 @@ the consensus engine accepts only transactions in the form of raw bytes. * The `TxDecoder` object performs the decoding. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/tx_msg.go#L91-L95 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/types/tx_msg.go#L91-L95 ``` A standard implementation of both these objects can be found in the [`auth/tx` module](https://docs.cosmos.network/main/build/modules/auth#transactions): -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/tx/decoder.go +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/auth/tx/decoder.go ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/tx/encoder.go +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/auth/tx/encoder.go ``` See [ADR-020](../../architecture/adr-020-protobuf-transaction-encoding.md) for details of how a transaction is encoded. @@ -245,39 +245,3 @@ Protobuf types can be defined to encode: We encourage developers to follow industry guidelines: [Protocol Buffers style guide](https://developers.google.com/protocol-buffers/docs/style) and [Buf](https://buf.build/docs/style-guide), see more details in [ADR 023](../../architecture/adr-023-protobuf-naming.md) - -### How to update modules to protobuf encoding - -If modules do not contain any interfaces (e.g. `Account` or `Content`), then they -may simply migrate any existing types that -are encoded and persisted via their concrete Amino codec to Protobuf (see 1. for further guidelines) and accept a `Marshaler` as the codec which is implemented via the `ProtoCodec` -without any further customization. - -However, if a module type composes an interface, it must wrap it in the `sdk.Any` (from `/types` package) type. To do that, a module-level .proto file must use [`google.protobuf.Any`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto) for respective message type interface types. - -For example, in the `x/evidence` module defines an `Evidence` interface, which is used by the `MsgSubmitEvidence`. The structure definition must use `sdk.Any` to wrap the evidence file. In the proto file we define it as follows: - -```protobuf -// proto/cosmos/evidence/v1beta1/tx.proto - -message MsgSubmitEvidence { - string submitter = 1; - google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "cosmos.evidence.v1beta1.Evidence"]; -} -``` - -The Cosmos SDK `codec.Codec` interface provides support methods `MarshalInterface` and `UnmarshalInterface` to easy encoding of state to `Any`. - -Module should register interfaces using `InterfaceRegistry` which provides a mechanism for registering interfaces: `RegisterInterface(protoName string, iface interface{}, impls ...proto.Message)` and implementations: `RegisterImplementations(iface interface{}, impls ...proto.Message)` that can be safely unpacked from Any, similarly to type registration with Amino: - -```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/codec/types/interface_registry.go#L28-L75 -``` - -In addition, an `UnpackInterfaces` phase should be introduced to deserialization to unpack interfaces before they're needed. Protobuf types that contain a protobuf `Any` either directly or via one of their members should implement the `UnpackInterfacesMessage` interface: - -```go -type UnpackInterfacesMessage interface { - UnpackInterfaces(InterfaceUnpacker) error -} -``` diff --git a/docs/learn/advanced/09-telemetry.md b/docs/learn/advanced/09-telemetry.md index c5916544f111..9690d9b590ea 100644 --- a/docs/learn/advanced/09-telemetry.md +++ b/docs/learn/advanced/09-telemetry.md @@ -13,17 +13,18 @@ their application through the use of the `telemetry` package. To enable telemetr The Cosmos SDK currently supports enabling in-memory and prometheus as telemetry sinks. In-memory sink is always attached (when the telemetry is enabled) with 10 second interval and 1 minute retention. This means that metrics will be aggregated over 10 seconds, and metrics will be kept alive for 1 minute. -To query active metrics (see retention note above) you have to enable API server (`api.enabled = true` in the app.toml). Single API endpoint is exposed: `http://localhost:1317/metrics?format={text|prometheus}`, the default being `text`. +To query active metrics (see retention note above) you have to enable API server (`api.enabled = true` in the app.toml). Single API endpoint is exposed: `http://localhost:1317/metrics?format={text|prometheus}` (or port `1318` in v2) , the default being `text`. ## Emitting metrics If telemetry is enabled via configuration, a single global metrics collector is registered via the [go-metrics](https://github.com/hashicorp/go-metrics) library. This allows emitting and collecting -metrics through simple [API](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/telemetry/wrapper.go). Example: +metrics through simple [API](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/telemetry/wrapper.go). Example: ```go func EndBlocker(ctx sdk.Context, k keeper.Keeper) { - defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker) + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyEndBlocker) // ... } @@ -69,60 +70,32 @@ Consider the following examples with enough granularity and adequate cardinality * begin/end blocker time * tx gas used * block gas used -* amount of tokens minted -* amount of accounts created The following examples expose too much cardinality and may not even prove to be useful: * transfers between accounts with amount * voting/deposit amount from unique addresses +## Idempotency + +Metrics aren't idempotent, so if a metric is emitted twice, it will be counted twice. +This is important to keep in mind when collecting metrics. If a module is called twice, the metrics will be emitted twice (for instance in `CheckTx`, `SimulateTx` or `DeliverTx`). + ## Supported Metrics -| Metric | Description | Unit | Type | -|:--------------------------------|:------------------------------------------------------------------------------------------|:----------------|:--------| -| `tx_count` | Total number of txs processed via `DeliverTx` | tx | counter | -| `tx_successful` | Total number of successful txs processed via `DeliverTx` | tx | counter | -| `tx_failed` | Total number of failed txs processed via `DeliverTx` | tx | counter | -| `tx_gas_used` | The total amount of gas used by a tx | gas | gauge | -| `tx_gas_wanted` | The total amount of gas requested by a tx | gas | gauge | -| `tx_msg_send` | The total amount of tokens sent in a `MsgSend` (per denom) | token | gauge | -| `tx_msg_withdraw_reward` | The total amount of tokens withdrawn in a `MsgWithdrawDelegatorReward` (per denom) | token | gauge | -| `tx_msg_withdraw_commission` | The total amount of tokens withdrawn in a `MsgWithdrawValidatorCommission` (per denom) | token | gauge | -| `tx_msg_delegate` | The total amount of tokens delegated in a `MsgDelegate` | token | gauge | -| `tx_msg_begin_unbonding` | The total amount of tokens undelegated in a `MsgUndelegate` | token | gauge | -| `tx_msg_begin_begin_redelegate` | The total amount of tokens redelegated in a `MsgBeginRedelegate` | token | gauge | -| `tx_msg_ibc_transfer` | The total amount of tokens transferred via IBC in a `MsgTransfer` (source or sink chain) | token | gauge | -| `ibc_transfer_packet_receive` | The total amount of tokens received in a `FungibleTokenPacketData` (source or sink chain) | token | gauge | -| `new_account` | Total number of new accounts created | account | counter | -| `gov_proposal` | Total number of governance proposals | proposal | counter | -| `gov_vote` | Total number of governance votes for a proposal | vote | counter | -| `gov_deposit` | Total number of governance deposits for a proposal | deposit | counter | -| `staking_delegate` | Total number of delegations | delegation | counter | -| `staking_undelegate` | Total number of undelegations | undelegation | counter | -| `staking_redelegate` | Total number of redelegations | redelegation | counter | -| `ibc_transfer_send` | Total number of IBC transfers sent from a chain (source or sink) | transfer | counter | -| `ibc_transfer_receive` | Total number of IBC transfers received to a chain (source or sink) | transfer | counter | -| `ibc_client_create` | Total number of clients created | create | counter | -| `ibc_client_update` | Total number of client updates | update | counter | -| `ibc_client_upgrade` | Total number of client upgrades | upgrade | counter | -| `ibc_client_misbehaviour` | Total number of client misbehaviours | misbehaviour | counter | -| `ibc_connection_open-init` | Total number of connection `OpenInit` handshakes | handshake | counter | -| `ibc_connection_open-try` | Total number of connection `OpenTry` handshakes | handshake | counter | -| `ibc_connection_open-ack` | Total number of connection `OpenAck` handshakes | handshake | counter | -| `ibc_connection_open-confirm` | Total number of connection `OpenConfirm` handshakes | handshake | counter | -| `ibc_channel_open-init` | Total number of channel `OpenInit` handshakes | handshake | counter | -| `ibc_channel_open-try` | Total number of channel `OpenTry` handshakes | handshake | counter | -| `ibc_channel_open-ack` | Total number of channel `OpenAck` handshakes | handshake | counter | -| `ibc_channel_open-confirm` | Total number of channel `OpenConfirm` handshakes | handshake | counter | -| `ibc_channel_close-init` | Total number of channel `CloseInit` handshakes | handshake | counter | -| `ibc_channel_close-confirm` | Total number of channel `CloseConfirm` handshakes | handshake | counter | -| `tx_msg_ibc_recv_packet` | Total number of IBC packets received | packet | counter | -| `tx_msg_ibc_acknowledge_packet` | Total number of IBC packets acknowledged | acknowledgement | counter | -| `ibc_timeout_packet` | Total number of IBC timeout packets | timeout | counter | -| `store_iavl_get` | Duration of an IAVL `Store#Get` call | ms | summary | -| `store_iavl_set` | Duration of an IAVL `Store#Set` call | ms | summary | -| `store_iavl_has` | Duration of an IAVL `Store#Has` call | ms | summary | -| `store_iavl_delete` | Duration of an IAVL `Store#Delete` call | ms | summary | -| `store_iavl_commit` | Duration of an IAVL `Store#Commit` call | ms | summary | -| `store_iavl_query` | Duration of an IAVL `Store#Query` call | ms | summary | +| Metric | Description | Unit | Type | +| ------------------- | ------------------------------------------------------------------------------ | ---- | ------- | +| `tx_count` | Total number of txs processed via `DeliverTx` | tx | counter | +| `tx_successful` | Total number of successful txs processed via `DeliverTx` | tx | counter | +| `tx_failed` | Total number of failed txs processed via `DeliverTx` | tx | counter | +| `tx_gas_used` | The total amount of gas used by a tx | gas | gauge | +| `tx_gas_wanted` | The total amount of gas requested by a tx | gas | gauge | +| `store_iavl_get` | Duration of an IAVL `Store#Get` call | ms | summary | +| `store_iavl_set` | Duration of an IAVL `Store#Set` call | ms | summary | +| `store_iavl_has` | Duration of an IAVL `Store#Has` call | ms | summary | +| `store_iavl_delete` | Duration of an IAVL `Store#Delete` call | ms | summary | +| `store_iavl_commit` | Duration of an IAVL `Store#Commit` call | ms | summary | +| `store_iavl_query` | Duration of an IAVL `Store#Query` call | ms | summary | +| `begin_blocker` | Duration of the `BeginBlock` call per module | ms | summary | +| `end_blocker` | Duration of the `EndBlock` call per module | ms | summary | +| `server_info` | Information about the server, such as version, commit, and build date, upgrade | - | gauge | diff --git a/docs/learn/beginner/00-app-anatomy.md b/docs/learn/beginner/00-app-anatomy.md index ae5a20062053..9757e7e95af3 100644 --- a/docs/learn/beginner/00-app-anatomy.md +++ b/docs/learn/beginner/00-app-anatomy.md @@ -275,7 +275,7 @@ https://github.com/cosmos/gaia/blob/26ae7c2/cmd/gaiad/cmd/root.go#L39-L80 ## Dependencies and Makefile -This section is optional, as developers are free to choose their dependency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. +This section is optional, as developers are free to choose their dependency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://go.dev/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. The following is the `go.mod` of the [Cosmos Hub](https://github.com/cosmos/gaia), provided as an example. diff --git a/docs/learn/intro/00-overview.md b/docs/learn/intro/00-overview.md index bb32d84a962f..7b0a3da037b5 100644 --- a/docs/learn/intro/00-overview.md +++ b/docs/learn/intro/00-overview.md @@ -9,13 +9,13 @@ sidebar_position: 1 The [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) is an open-source toolkit for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. -We further this modular approach by allowing developers to plug and play with different consensus engines this can range from the [CometBFT](https://github.com/cometbft/cometbft) or [Rollkit](https://rollkit.dev/). +We further this modular approach by allowing developers to plug and play with different consensus engines this can range from [CometBFT](https://cometbft.com/) or [Rollkit](https://rollkit.dev/). SDK-based blockchains have the choice to use the predefined modules or to build their own modules. What this means is that developers can build a blockchain that is tailored to their specific use case, without having to worry about the low-level details of building a blockchain from scratch. Predefined modules include staking, governance, and token issuance, among others. What's more, the Cosmos SDK is a capabilities-based system that allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [Object-Capability Model](../advanced/10-ocap.md). -How you can look at this is if we imagine that the SDK is like a lego kit. You can choose to build the basic house from the instructions or you can choose to modify your house and add more floors, more doors, more windows. The choice is yours. +You can think of the SDK as a lego kit. You can choose to build the basic house from the instructions, or you can choose to modify your house and add more floors, more doors, more windows. The choice is yours. ## What are Application-Specific Blockchains @@ -27,17 +27,17 @@ Learn more about [application-specific blockchains](./01-why-app-specific.md). ## What is Modularity -Today there is a lot of talk around modularity and discussions between monolithic and modular. Originally the Cosmos SDK was built with a vision of modularity in mind. Modularity is derived from splitting a blockchain into customizable layers of execution, consensus, settlement and data availability, which is what the Cosmos SDK enables. This means that developers can plug and play, making their blockchain customisable by using different software for different layers. For example you can choose to build a vanilla chain and use the Cosmos SDK with CometBFT. CometBFT will be your consensus layer and the chain itself would be the settlement and execution layer. Another route could be to use the SDK with Rollkit and Celestia as your consensus and data availability layer. The benefit of modularity is that you can customize your chain to your specific use case. +Today, there is a lot of talk around modularity and discussions between monolithic and modular. Originally, the Cosmos SDK was built with a vision of modularity in mind. Modularity is derived from splitting a blockchain into customizable layers of execution, consensus, settlement and data availability, which is what the Cosmos SDK enables. This means that developers can plug and play, making their blockchain customizable by using different software for different layers. For example, you can choose to build a vanilla chain and use the Cosmos SDK with CometBFT. CometBFT will be your consensus layer and the chain itself would be the settlement and execution layer. Another route could be to use the SDK with Rollkit and [Celestia](https://celestia.org/) as your consensus and data availability layer. The benefit of modularity is that you can customize your chain to your specific use case. ## Why the Cosmos SDK The Cosmos SDK is the most advanced framework for building custom modular application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralized application with the Cosmos SDK: -* It allows you to plug and play and customize your consensus layer. As above you can use Rollkit and Celestia as your consensus and data availability layer. This offers a lot of flexibility and customisation. -* Previously the default consensus engine available within the Cosmos SDK is [CometBFT](https://github.com/cometbft/cometbft). CometBFT is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +* It allows you to plug and play and customize your consensus layer. As mentioned above, you can use Rollkit and Celestia as your consensus and data availability layer. This offers a lot of flexibility and customization. +* Previously the default consensus engine available within the Cosmos SDK is [CometBFT](https://cometbft.com/). CometBFT is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. * The Cosmos SDK is open-source and designed to make it easy to build blockchains out of composable [modules](../../build/modules). As the ecosystem of open-source Cosmos SDK modules grows, it will become increasingly easier to build complex decentralized platforms with it. * The Cosmos SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -* Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Kava](https://www.kava.io/). [Many more](https://cosmos.network/ecosystem) are building on the Cosmos SDK. +* Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Osmosis](https://osmosis.zone/), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Dydx](https://dydx.exchange/). [Many more](https://cosmos.network/ecosystem) are building on the Cosmos SDK. ## Getting started with the Cosmos SDK diff --git a/docs/learn/intro/02-sdk-app-architecture.md b/docs/learn/intro/02-sdk-app-architecture.md index 6ace65e57abc..1f6d9df78d2d 100644 --- a/docs/learn/intro/02-sdk-app-architecture.md +++ b/docs/learn/intro/02-sdk-app-architecture.md @@ -54,7 +54,7 @@ flowchart LR A -->|"For each T in B: apply(T)"| B ``` -In a blockchain context, the state machine is deterministic. This means that if a node is started at a given state and replays the same sequence of transactions, it will always end up with the same final state. +In a blockchain context, the state machine is [deterministic](https://en.wikipedia.org/wiki/Deterministic_system). This means that if a node is started at a given state and replays the same sequence of transactions, it will always end up with the same final state. The Cosmos SDK gives developers maximum flexibility to define the state of their application, transaction types and state transition functions. The process of building state machines with the Cosmos SDK will be described more in-depth in the following sections. But first, let us see how the state machine is replicated using various consensus engines, such as CometBFT. @@ -117,7 +117,7 @@ Note that **CometBFT only handles transaction bytes**. It has no knowledge of wh Here are the most important messages of the ABCI: -* `CheckTx`: When a transaction is received by CometBFT, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam transactions. . A special handler called the [`AnteHandler`](../beginner/04-gas-fees.md#antehandler) is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the checks are valid, the transaction is added to the [mempool](https://docs.cometbft.com/v1.0/explanation/core/mempool) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +* `CheckTx`: When a transaction is received by CometBFT, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam transactions. A special handler called the [`AnteHandler`](../beginner/04-gas-fees.md#antehandler) is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the checks are valid, the transaction is added to the [mempool](https://docs.cometbft.com/v1.0/explanation/core/mempool) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. * `DeliverTx`: When a [valid block](https://docs.cometbft.com/v1.0/spec/core/data_structures#block) is received by CometBFT, each transaction in the block is passed to the application via `DeliverTx` in order to be processed. It is during this stage that the state transitions occur. The `AnteHandler` executes again, along with the actual [`Msg` service](../../build/building-modules/03-msg-services.md) RPC for each message in the transaction. * `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transactions or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. @@ -136,4 +136,4 @@ If we use the example of Rollkit, a user initiates a transaction, which is then The Interoperability Layer enables communication and interaction between different blockchains. This layer facilitates cross-chain transactions and data sharing, allowing various blockchain networks to interoperate seamlessly. Interoperability is key for building a connected ecosystem of blockchains, enhancing their functionality and reach. -In this case we have separated the layers even further to really illustrate the components that make-up the blockchain architecture and it is important to note that the Cosmos SDK is designed to be interoperable with other blockchains. This is achieved through the use of the Inter-Blockchain Communication (IBC) protocol, which allows different blockchains to communicate and transfer assets between each other. +In this case we have separated the layers even further to really illustrate the components that make-up the blockchain architecture and it is important to note that the Cosmos SDK is designed to be interoperable with other blockchains. This is achieved through the use of the [Inter-Blockchain Communication (IBC) protocol](https://www.ibcprotocol.dev/), which allows different blockchains to communicate and transfer assets between each other. diff --git a/docs/learn/intro/03-sdk-design.md b/docs/learn/intro/03-sdk-design.md index e2edcd4efb02..9ae17b73bb16 100644 --- a/docs/learn/intro/03-sdk-design.md +++ b/docs/learn/intro/03-sdk-design.md @@ -22,7 +22,7 @@ Here is a simplified view of how transactions are handled by an application buil Here is an example of this from `simapp`, the Cosmos SDK demonstration app: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app.go#L170-L212 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/simapp/app.go#L145-L186 ``` The goal of `baseapp` is to provide a secure interface between the store and the extensible state machine while defining as little about the state machine as possible (staying true to the ABCI). @@ -33,7 +33,7 @@ For more on `baseapp`, please click [here](../advanced/00-baseapp.md). The Cosmos SDK provides a [`multistore`](../advanced/04-store.md#multistore) for persisting state. The multistore allows developers to declare any number of [`KVStores`](../advanced/04-store.md#base-layer-kvstores). These `KVStores` only accept the `[]byte` type as value and therefore any custom structure needs to be marshalled using [a codec](../advanced/05-encoding.md) before being stored. -The multistore abstraction is used to divide the state in distinct compartments, each managed by its own module. For more on the multistore, click [here](../advanced/04-store.md#multistore) +The multistore abstraction is used to divide the state in distinct compartments, each managed by its own module. For more on the multistore, click [here](../advanced/04-store.md#multistore). ## Modules @@ -61,6 +61,6 @@ Cosmos SDK modules are defined in the `x/` folder of the Cosmos SDK. Some core m * `x/auth`: Used to manage accounts and signatures. * `x/bank`: Used to enable tokens and token transfers. -* `x/staking` + `x/slashing`: Used to build Proof-Of-Stake blockchains. +* `x/staking` + `x/slashing`: Used to build Proof-of-Stake blockchains. -In addition to the already existing modules in `x/`, that anyone can use in their app, the Cosmos SDK lets you build your own custom modules. You can check an [example of that in the tutorial](https://tutorials.cosmos.network/). +In addition to the already existing modules in `x/`, which anyone can use in their app, the Cosmos SDK lets you build your own custom modules. You can check an [example of that in the tutorial](https://tutorials.cosmos.network/). diff --git a/docs/learn/learn.md b/docs/learn/learn.md index b8f64821a906..3414fa1a2039 100644 --- a/docs/learn/learn.md +++ b/docs/learn/learn.md @@ -3,8 +3,8 @@ sidebar_position: 0 --- # Learn -* [Introduction](./intro/00-overview.md) - Dive into the fundamentals of Cosmos SDK with an insightful introduction, -laying the groundwork for understanding blockchain development. In this section we provide a High-Level Overview of the SDK, then dive deeper into Core concepts such as Application-Specific Blockchains, Blockchain Architecture, and finally we begin to explore what are the main components of the SDK. +* [Introduction](./intro/00-overview.md) - Dive into the fundamentals of Cosmos SDK with an insightful introduction, +laying the groundwork for understanding blockchain development. In this section, we provide a High-Level Overview of the SDK, then dive deeper into Core concepts such as Application-Specific Blockchains, Blockchain Architecture, and finally, we begin to explore the main components of the SDK. * [Beginner](./beginner/00-app-anatomy.md) - Start your journey with beginner-friendly resources in the Cosmos SDK's "Learn" section, providing a gentle entry point for newcomers to blockchain development. Here we focus on a little more detail, covering the Anatomy of a Cosmos SDK Application, Transaction Lifecycles, Accounts and lastly, Gas and Fees. * [Advanced](./advanced/00-baseapp.md) - Level up your Cosmos SDK expertise with advanced topics, tailored for experienced diff --git a/fuzz/fuzz.patch b/fuzz/fuzz.patch new file mode 100644 index 000000000000..995b0d5b53e5 --- /dev/null +++ b/fuzz/fuzz.patch @@ -0,0 +1,81 @@ +diff --git a/types/address_test.go b/types/address_test.go +index 014a48b73..99f9a1a86 100644 +--- a/types/address_test.go ++++ b/types/address_test.go +@@ -26,10 +26,6 @@ type addressTestSuite struct { + suite.Suite + } + +-func TestAddressTestSuite(t *testing.T) { +- suite.Run(t, new(addressTestSuite)) +-} +- + func (s *addressTestSuite) SetupSuite() { + s.T().Parallel() + } +@@ -403,65 +399,6 @@ func (s *addressTestSuite) TestAddressInterface() { + } + } + +-func (s *addressTestSuite) TestBech32ifyAddressBytes() { +- type args struct { +- prefix string +- bs []byte +- } +- tests := []struct { +- name string +- args args +- want string +- wantErr bool +- }{ +- {"empty address", args{"prefixa", []byte{}}, "", false}, +- {"empty prefix", args{"", addr20byte}, "", true}, +- {"10-byte address", args{"prefixa", addr10byte}, "prefixa1qqqsyqcyq5rqwzqf3953cc", false}, +- {"10-byte address", args{"prefixb", addr10byte}, "prefixb1qqqsyqcyq5rqwzqf20xxpc", false}, +- {"20-byte address", args{"prefixa", addr20byte}, "prefixa1qqqsyqcyq5rqwzqfpg9scrgwpugpzysn7hzdtn", false}, +- {"20-byte address", args{"prefixb", addr20byte}, "prefixb1qqqsyqcyq5rqwzqfpg9scrgwpugpzysnrujsuw", false}, +- } +- for _, tt := range tests { +- s.T().Run(tt.name, func(t *testing.T) { +- got, err := types.Bech32ifyAddressBytes(tt.args.prefix, tt.args.bs) +- if (err != nil) != tt.wantErr { +- t.Errorf("Bech32ifyBytes() error = %v, wantErr %v", err, tt.wantErr) +- return +- } +- require.Equal(t, tt.want, got) +- }) +- } +-} +- +-func (s *addressTestSuite) TestMustBech32ifyAddressBytes() { +- type args struct { +- prefix string +- bs []byte +- } +- tests := []struct { +- name string +- args args +- want string +- wantPanic bool +- }{ +- {"empty address", args{"prefixa", []byte{}}, "", false}, +- {"empty prefix", args{"", addr20byte}, "", true}, +- {"10-byte address", args{"prefixa", addr10byte}, "prefixa1qqqsyqcyq5rqwzqf3953cc", false}, +- {"10-byte address", args{"prefixb", addr10byte}, "prefixb1qqqsyqcyq5rqwzqf20xxpc", false}, +- {"20-byte address", args{"prefixa", addr20byte}, "prefixa1qqqsyqcyq5rqwzqfpg9scrgwpugpzysn7hzdtn", false}, +- {"20-byte address", args{"prefixb", addr20byte}, "prefixb1qqqsyqcyq5rqwzqfpg9scrgwpugpzysnrujsuw", false}, +- } +- for _, tt := range tests { +- s.T().Run(tt.name, func(t *testing.T) { +- if tt.wantPanic { +- require.Panics(t, func() { types.MustBech32ifyAddressBytes(tt.args.prefix, tt.args.bs) }) +- return +- } +- require.Equal(t, tt.want, types.MustBech32ifyAddressBytes(tt.args.prefix, tt.args.bs)) +- }) +- } +-} +- + func (s *addressTestSuite) TestAddressTypesEquals() { + addr1 := secp256k1.GenPrivKey().PubKey().Address() + accAddr1 := types.AccAddress(addr1) diff --git a/fuzz/oss-fuzz-build.sh b/fuzz/oss-fuzz-build.sh index faa7c76b5d7b..c829194dc2e4 100644 --- a/fuzz/oss-fuzz-build.sh +++ b/fuzz/oss-fuzz-build.sh @@ -1,5 +1,34 @@ #!/bin/bash +set -o nounset +set -o pipefail +set -o errexit +set -x + +cd $SRC +wget https://go.dev/dl/go1.23.1.linux-amd64.tar.gz +mkdir $SRC/new-go +rm -rf /root/.go && tar -C $SRC/new-go/ -xzf go1.23.1.linux-amd64.tar.gz +mv $SRC/new-go/go /root/.go +ls /root/.go + +cd $SRC/go-118-fuzz-build +go build . +mv go-118-fuzz-build /root/go/bin/ +cd $SRC/cosmos-sdk +git apply ./fuzz/fuzz.patch + +mkdir $SRC/cosmos-sdk/types/fuzzing +mv $SRC/cosmos-sdk/types/address*_test.go $SRC/cosmos-sdk/types/fuzzing/ +sed 's/package types_test/package fuzzing/g' -i "$SRC"/cosmos-sdk/types/fuzzing/* + +rm $SRC/cosmos-sdk/math/dec_internal_test.go +rm $SRC/cosmos-sdk/math/int_internal_test.go +rm $SRC/cosmos-sdk/math/uint_internal_test.go +mv $SRC/cosmos-sdk/types/fuzz_test.go $SRC/cosmos-sdk/types/fuzz.go +rm $SRC/cosmos-sdk/types/*_test.go +mv $SRC/cosmos-sdk/types/fuzz.go $SRC/cosmos-sdk/types/fuzz_test.go + set -euo pipefail export FUZZ_ROOT="github.com/cosmos/cosmos-sdk" @@ -18,25 +47,22 @@ build_go_fuzzer() { compile_native_go_fuzzer cosmossdk.io/math FuzzLegacyNewDecFromStr fuzz_math_legacy_new_dec_from_str ) -go get github.com/AdamKorcz/go-118-fuzz-build/testing +printf "package types \nimport _ \"github.com/AdamKorcz/go-118-fuzz-build/testing\"\n" > ./types/fuzz-register.go +go mod edit -replace github.com/AdamKorcz/go-118-fuzz-build=$SRC/go-118-fuzz-build +go mod tidy # TODO: fails to build with # main.413864645.go:12:2: found packages query (collections_pagination.go) and query_test (fuzz_test.go_fuzz.go) in /src/cosmos-sdk/types/query # because of the separate query_test package. # compile_native_go_fuzzer "$FUZZ_ROOT"/types/query FuzzPagination fuzz_types_query_pagination compile_native_go_fuzzer "$FUZZ_ROOT"/types FuzzCoinUnmarshalJSON fuzz_types_coin_unmarshal_json -compile_native_go_fuzzer "$FUZZ_ROOT"/types FuzzBech32AccAddrConsistencyYAML fuzz_types_bech32_acc_addr_consistency_yaml - +compile_native_go_fuzzer "$FUZZ_ROOT"/types/fuzzing FuzzBech32AccAddrConsistencyYAML fuzz_types_bech32_acc_addr_consistency_yaml build_go_fuzzer FuzzCryptoHDDerivePrivateKeyForPath fuzz_crypto_hd_deriveprivatekeyforpath build_go_fuzzer FuzzCryptoHDNewParamsFromPath fuzz_crypto_hd_newparamsfrompath - build_go_fuzzer FuzzCryptoTypesCompactbitarrayMarshalUnmarshal fuzz_crypto_types_compactbitarray_marshalunmarshal - build_go_fuzzer FuzzTendermintAminoDecodeTime fuzz_tendermint_amino_decodetime - build_go_fuzzer FuzzTypesParseCoin fuzz_types_parsecoin build_go_fuzzer FuzzTypesParseDecCoin fuzz_types_parsedeccoin build_go_fuzzer FuzzTypesParseTimeBytes fuzz_types_parsetimebytes build_go_fuzzer FuzzTypesDecSetString fuzz_types_dec_setstring - build_go_fuzzer FuzzUnknownProto fuzz_unknownproto diff --git a/go.mod b/go.mod index 0c54a37dd9d4..316ed8448cf6 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,13 @@ module github.com/cosmos/cosmos-sdk require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.4.1 cosmossdk.io/math v1.3.0 - cosmossdk.io/schema v0.3.0 + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 @@ -45,7 +45,7 @@ require ( github.com/mdp/qrterminal/v3 v3.2.0 github.com/muesli/termenv v0.15.2 github.com/prometheus/client_golang v1.20.4 - github.com/prometheus/common v0.59.1 + github.com/prometheus/common v0.60.0 github.com/rs/zerolog v1.33.0 github.com/spf13/cast v1.7.0 github.com/spf13/cobra v1.8.1 @@ -57,7 +57,7 @@ require ( golang.org/x/crypto v0.27.0 golang.org/x/sync v0.8.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 gotest.tools/v3 v3.5.1 pgregory.net/rapid v1.1.0 @@ -168,7 +168,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/qr v0.2.0 // indirect diff --git a/go.sum b/go.sum index 4508c5975094..5aff95150b03 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -411,8 +411,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -633,8 +633,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -645,8 +645,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/orm/go.mod b/orm/go.mod index f6bcffee4ee2..8bd1d5f47d99 100644 --- a/orm/go.mod +++ b/orm/go.mod @@ -16,7 +16,7 @@ require ( github.com/regen-network/gocuke v1.1.1 github.com/stretchr/testify v1.9.0 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 gotest.tools/v3 v3.5.1 pgregory.net/rapid v1.1.0 @@ -50,14 +50,14 @@ require ( github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/linxGnu/grocksdb v1.8.12 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/onsi/gomega v1.20.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.12.0 // indirect - github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect + github.com/prometheus/client_golang v1.20.4 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.60.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect @@ -67,7 +67,7 @@ require ( golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/yaml.v3 v3.0.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/orm/go.sum b/orm/go.sum index ac6d914680db..0635f05e49b4 100644 --- a/orm/go.sum +++ b/orm/go.sum @@ -1,35 +1,3 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cosmossdk.io/api v0.7.6 h1:PC20PcXy1xYKH2KU4RMurVoFjjKkCgYRbVAD4PdqUuY= cosmossdk.io/api v0.7.6/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= @@ -42,32 +10,17 @@ cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg= github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= @@ -99,10 +52,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -114,133 +63,58 @@ github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkN github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/linxGnu/grocksdb v1.8.12 h1:1/pCztQUOa3BX/1gR3jSZDoaKFpeHFvQ1XrqZpSvZVo= github.com/linxGnu/grocksdb v1.8.12/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -259,52 +133,28 @@ github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeR github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= -github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= -github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= +github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/regen-network/gocuke v1.1.1 h1:13D3n5xLbpzA/J2ELHC9jXYq0+XyEr64A3ehjvfmBbE= github.com/regen-network/gocuke v1.1.1/go.mod h1:Nl9EbhLmTzdLqb52fr/Fvf8LcoVuTjjf8FlLmXz1zHo= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= @@ -315,158 +165,53 @@ github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2l github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -474,59 +219,15 @@ golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -535,121 +236,38 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/runtime/v2/app.go b/runtime/v2/app.go index b7104f9e4774..caf55b92ce01 100644 --- a/runtime/v2/app.go +++ b/runtime/v2/app.go @@ -5,9 +5,8 @@ import ( "errors" "slices" - gogoproto "github.com/cosmos/gogoproto/proto" - runtimev2 "cosmossdk.io/api/cosmos/app/runtime/v2" + appmodulev2 "cosmossdk.io/core/appmodule/v2" "cosmossdk.io/core/registry" "cosmossdk.io/core/transaction" "cosmossdk.io/log" @@ -43,9 +42,8 @@ type App[T transaction.Tx] struct { amino registry.AminoRegistrar moduleManager *MM[T] - // GRPCMethodsToMessageMap maps gRPC method name to a function that decodes the request - // bytes into a gogoproto.Message, which then can be passed to appmanager. - GRPCMethodsToMessageMap map[string]func() gogoproto.Message + // QueryHandlers defines the query handlers + QueryHandlers map[string]appmodulev2.Handler storeLoader StoreLoader } @@ -120,6 +118,6 @@ func (a *App[T]) GetAppManager() *appmanager.AppManager[T] { return a.AppManager } -func (a *App[T]) GetGPRCMethodsToMessageMap() map[string]func() gogoproto.Message { - return a.GRPCMethodsToMessageMap +func (a *App[T]) GetQueryHandlers() map[string]appmodulev2.Handler { + return a.QueryHandlers } diff --git a/runtime/v2/builder.go b/runtime/v2/builder.go index c6fad39f41aa..b28ddbc741b4 100644 --- a/runtime/v2/builder.go +++ b/runtime/v2/builder.go @@ -6,28 +6,22 @@ import ( "errors" "fmt" "io" - "path/filepath" "cosmossdk.io/core/appmodule" appmodulev2 "cosmossdk.io/core/appmodule/v2" - "cosmossdk.io/core/server" "cosmossdk.io/core/store" "cosmossdk.io/core/transaction" "cosmossdk.io/runtime/v2/services" "cosmossdk.io/server/v2/appmanager" "cosmossdk.io/server/v2/stf" "cosmossdk.io/server/v2/stf/branch" - "cosmossdk.io/store/v2/db" - rootstore "cosmossdk.io/store/v2/root" ) // AppBuilder is a type that is injected into a container by the runtime/v2 module // (as *AppBuilder) which can be used to create an app which is compatible with // the existing app.go initialization conventions. type AppBuilder[T transaction.Tx] struct { - app *App[T] - config server.DynamicConfig - storeOptions *rootstore.Options + app *App[T] // the following fields are used to overwrite the default branch func(state store.ReaderMap) store.WriterMap @@ -99,6 +93,10 @@ func (a *AppBuilder[T]) Build(opts ...AppBuilderOption[T]) (*App[T], error) { } } + if a.app.db == nil { + return nil, fmt.Errorf("app.db is not set, it is required to build the app") + } + if err := a.app.moduleManager.RegisterServices(a.app); err != nil { return nil, err } @@ -122,37 +120,6 @@ func (a *AppBuilder[T]) Build(opts ...AppBuilderOption[T]) (*App[T], error) { } a.app.stf = stf - home := a.config.GetString(FlagHome) - scRawDb, err := db.NewDB( - db.DBType(a.config.GetString("store.app-db-backend")), - "application", - filepath.Join(home, "data"), - nil, - ) - if err != nil { - panic(err) - } - - var storeOptions rootstore.Options - if a.storeOptions != nil { - storeOptions = *a.storeOptions - } else { - storeOptions = rootstore.DefaultStoreOptions() - } - factoryOptions := &rootstore.FactoryOptions{ - Logger: a.app.logger, - RootDir: home, - Options: storeOptions, - StoreKeys: append(a.app.storeKeys, "stf"), - SCRawDB: scRawDb, - } - - rs, err := rootstore.CreateRootStore(factoryOptions) - if err != nil { - return nil, fmt.Errorf("failed to create root store: %w", err) - } - a.app.db = rs - appManagerBuilder := appmanager.Builder[T]{ STF: a.app.stf, DB: a.app.db, @@ -251,9 +218,3 @@ func AppBuilderWithPostTxExec[T transaction.Tx](postTxExec func(ctx context.Cont a.postTxExec = postTxExec } } - -func AppBuilderWithStoreOptions[T transaction.Tx](opts *rootstore.Options) AppBuilderOption[T] { - return func(a *AppBuilder[T]) { - a.storeOptions = opts - } -} diff --git a/runtime/v2/go.mod b/runtime/v2/go.mod index ce6c55b50cc2..1bd24cd1e26c 100644 --- a/runtime/v2/go.mod +++ b/runtime/v2/go.mod @@ -5,7 +5,6 @@ go 1.23 // server v2 integration replace ( cosmossdk.io/api => ../../api - cosmossdk.io/core => ../../core cosmossdk.io/server/v2/appmanager => ../../server/v2/appmanager cosmossdk.io/server/v2/stf => ../../server/v2/stf cosmossdk.io/store/v2 => ../../store/v2 @@ -14,7 +13,7 @@ replace ( require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 cosmossdk.io/log v1.4.1 cosmossdk.io/server/v2/appmanager v0.0.0-00010101000000-000000000000 @@ -22,7 +21,7 @@ require ( cosmossdk.io/store/v2 v2.0.0-00010101000000-000000000000 cosmossdk.io/x/tx v0.13.3 github.com/cosmos/gogoproto v1.7.0 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -66,7 +65,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/zerolog v1.33.0 // indirect @@ -82,7 +81,7 @@ require ( golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/yaml.v3 v3.0.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/runtime/v2/go.sum b/runtime/v2/go.sum index bd09e3bf2626..b273f05e2e32 100644 --- a/runtime/v2/go.sum +++ b/runtime/v2/go.sum @@ -2,6 +2,8 @@ buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fed buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2/go.mod h1:1+3gJj2NvZ1mTLAtHu+lMhOjGgQPiCKCeo+9MBww0Eo= buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 h1:b7EEYTUHmWSBEyISHlHvXbJPqtKiHRuUignL1tsHnNQ= buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -200,8 +202,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -315,10 +317,10 @@ golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNq google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/runtime/v2/manager.go b/runtime/v2/manager.go index 1f05b1014620..01b0c93971ab 100644 --- a/runtime/v2/manager.go +++ b/runtime/v2/manager.go @@ -615,45 +615,46 @@ func (m *MM[T]) assertNoForgottenModules( } func registerServices[T transaction.Tx](s appmodulev2.AppModule, app *App[T], registry *protoregistry.Files) error { - c := &configurator{ - grpcQueryDecoders: map[string]func() gogoproto.Message{}, - stfQueryRouter: app.queryRouterBuilder, - stfMsgRouter: app.msgRouterBuilder, - registry: registry, - err: nil, - } - + // case module with services if services, ok := s.(hasServicesV1); ok { + c := &configurator{ + queryHandlers: map[string]appmodulev2.Handler{}, + stfQueryRouter: app.queryRouterBuilder, + stfMsgRouter: app.msgRouterBuilder, + registry: registry, + err: nil, + } if err := services.RegisterServices(c); err != nil { return fmt.Errorf("unable to register services: %w", err) } - } else { - // If module not implement RegisterServices, register msg & query handler. - if module, ok := s.(appmodulev2.HasMsgHandlers); ok { - module.RegisterMsgHandlers(app.msgRouterBuilder) - } - - if module, ok := s.(appmodulev2.HasQueryHandlers); ok { - module.RegisterQueryHandlers(app.queryRouterBuilder) - // TODO: query regist by RegisterQueryHandlers not in grpcQueryDecoders - if module, ok := s.(interface { - GetQueryDecoders() map[string]func() gogoproto.Message - }); ok { - decoderMap := module.GetQueryDecoders() - for path, decoder := range decoderMap { - app.GRPCMethodsToMessageMap[path] = decoder - } - } + + if c.err != nil { + app.logger.Warn("error registering services", "error", c.err) + } + + // merge maps + for path, decoder := range c.queryHandlers { + app.QueryHandlers[path] = decoder } } - if c.err != nil { - app.logger.Warn("error registering services", "error", c.err) + // if module implements register msg handlers + if module, ok := s.(appmodulev2.HasMsgHandlers); ok { + wrapper := stfRouterWrapper{stfRouter: app.msgRouterBuilder} + module.RegisterMsgHandlers(&wrapper) + if wrapper.error != nil { + return fmt.Errorf("unable to register handlers: %w", wrapper.error) + } } - // merge maps - for path, decoder := range c.grpcQueryDecoders { - app.GRPCMethodsToMessageMap[path] = decoder + // if module implements register query handlers + if module, ok := s.(appmodulev2.HasQueryHandlers); ok { + wrapper := stfRouterWrapper{stfRouter: app.queryRouterBuilder} + module.RegisterQueryHandlers(&wrapper) + + for path, handler := range wrapper.handlers { + app.QueryHandlers[path] = handler + } } return nil @@ -662,9 +663,7 @@ func registerServices[T transaction.Tx](s appmodulev2.AppModule, app *App[T], re var _ grpc.ServiceRegistrar = (*configurator)(nil) type configurator struct { - // grpcQueryDecoders is required because module expose queries through gRPC - // this provides a way to route to modules using gRPC. - grpcQueryDecoders map[string]func() gogoproto.Message + queryHandlers map[string]appmodulev2.Handler stfQueryRouter *stf.MsgRouterBuilder stfMsgRouter *stf.MsgRouterBuilder @@ -696,28 +695,31 @@ func (c *configurator) RegisterService(sd *grpc.ServiceDesc, ss interface{}) { func (c *configurator) registerQueryHandlers(sd *grpc.ServiceDesc, ss interface{}) error { for _, md := range sd.Methods { // TODO(tip): what if a query is not deterministic? - requestFullName, err := registerMethod(c.stfQueryRouter, sd, md, ss) + + handler, err := grpcHandlerToAppModuleHandler(sd, md, ss) if err != nil { - return fmt.Errorf("unable to register query handler %s.%s: %w", sd.ServiceName, md.MethodName, err) + return fmt.Errorf("unable to make a appmodulev2.HandlerFunc from gRPC handler (%s, %s): %w", sd.ServiceName, md.MethodName, err) } - // register gRPC query method. - typ := gogoproto.MessageType(requestFullName) - if typ == nil { - return fmt.Errorf("unable to find message in gogotype registry: %w", err) - } - decoderFunc := func() gogoproto.Message { - return reflect.New(typ.Elem()).Interface().(gogoproto.Message) + // register to stf query router. + err = c.stfQueryRouter.RegisterHandler(gogoproto.MessageName(handler.MakeMsg()), handler.Func) + if err != nil { + return fmt.Errorf("unable to register handler to stf router (%s, %s): %w", sd.ServiceName, md.MethodName, err) } - methodName := fmt.Sprintf("/%s/%s", sd.ServiceName, md.MethodName) - c.grpcQueryDecoders[methodName] = decoderFunc + + // register query handler using the same mapping used in stf + c.queryHandlers[gogoproto.MessageName(handler.MakeMsg())] = handler } return nil } func (c *configurator) registerMsgHandlers(sd *grpc.ServiceDesc, ss interface{}) error { for _, md := range sd.Methods { - _, err := registerMethod(c.stfMsgRouter, sd, md, ss) + handler, err := grpcHandlerToAppModuleHandler(sd, md, ss) + if err != nil { + return err + } + err = c.stfMsgRouter.RegisterHandler(gogoproto.MessageName(handler.MakeMsg()), handler.Func) if err != nil { return fmt.Errorf("unable to register msg handler %s.%s: %w", sd.ServiceName, md.MethodName, err) } @@ -725,32 +727,27 @@ func (c *configurator) registerMsgHandlers(sd *grpc.ServiceDesc, ss interface{}) return nil } -// requestFullNameFromMethodDesc returns the fully-qualified name of the request message of the provided service's method. -func requestFullNameFromMethodDesc(sd *grpc.ServiceDesc, method grpc.MethodDesc) (protoreflect.FullName, error) { - methodFullName := protoreflect.FullName(fmt.Sprintf("%s.%s", sd.ServiceName, method.MethodName)) - desc, err := gogoproto.HybridResolver.FindDescriptorByName(methodFullName) - if err != nil { - return "", fmt.Errorf("cannot find method descriptor %s", methodFullName) - } - methodDesc, ok := desc.(protoreflect.MethodDescriptor) - if !ok { - return "", fmt.Errorf("invalid method descriptor %s", methodFullName) - } - return methodDesc.Input().FullName(), nil -} - -func registerMethod( - stfRouter *stf.MsgRouterBuilder, +// grpcHandlerToAppModuleHandler converts a gRPC handler into an appmodulev2.HandlerFunc. +func grpcHandlerToAppModuleHandler( sd *grpc.ServiceDesc, md grpc.MethodDesc, ss interface{}, -) (string, error) { - requestName, err := requestFullNameFromMethodDesc(sd, md) +) (appmodulev2.Handler, error) { + requestName, responseName, err := requestFullNameFromMethodDesc(sd, md) if err != nil { - return "", err + return appmodulev2.Handler{}, err + } + + requestTyp := gogoproto.MessageType(string(requestName)) + if requestTyp == nil { + return appmodulev2.Handler{}, fmt.Errorf("no proto message found for %s", requestName) + } + responseTyp := gogoproto.MessageType(string(responseName)) + if responseTyp == nil { + return appmodulev2.Handler{}, fmt.Errorf("no proto message found for %s", responseName) } - return string(requestName), stfRouter.RegisterHandler(string(requestName), func( + handlerFunc := func( ctx context.Context, msg transaction.Msg, ) (resp transaction.Msg, err error) { @@ -759,7 +756,17 @@ func registerMethod( return nil, err } return res.(transaction.Msg), nil - }) + } + + return appmodulev2.Handler{ + Func: handlerFunc, + MakeMsg: func() transaction.Msg { + return reflect.New(requestTyp.Elem()).Interface().(transaction.Msg) + }, + MakeMsgResp: func() transaction.Msg { + return reflect.New(responseTyp.Elem()).Interface().(transaction.Msg) + }, + }, nil } func noopDecoder(_ interface{}) error { return nil } @@ -775,6 +782,20 @@ func messagePassingInterceptor(msg transaction.Msg) grpc.UnaryServerInterceptor } } +// requestFullNameFromMethodDesc returns the fully-qualified name of the request message and response of the provided service's method. +func requestFullNameFromMethodDesc(sd *grpc.ServiceDesc, method grpc.MethodDesc) (protoreflect.FullName, protoreflect.FullName, error) { + methodFullName := protoreflect.FullName(fmt.Sprintf("%s.%s", sd.ServiceName, method.MethodName)) + desc, err := gogoproto.HybridResolver.FindDescriptorByName(methodFullName) + if err != nil { + return "", "", fmt.Errorf("cannot find method descriptor %s", methodFullName) + } + methodDesc, ok := desc.(protoreflect.MethodDescriptor) + if !ok { + return "", "", fmt.Errorf("invalid method descriptor %s", methodFullName) + } + return methodDesc.Input().FullName(), methodDesc.Output().FullName(), nil +} + // defaultMigrationsOrder returns a default migrations order: ascending alphabetical by module name, // except x/auth which will run last, see: // https://github.com/cosmos/cosmos-sdk/issues/10591 @@ -801,3 +822,36 @@ func defaultMigrationsOrder(modules []string) []string { type hasServicesV1 interface { RegisterServices(grpc.ServiceRegistrar) error } + +var _ appmodulev2.MsgRouter = (*stfRouterWrapper)(nil) + +// stfRouterWrapper wraps the stf router and implements the core appmodulev2.MsgRouter +// interface. +// The difference between this type and stf router is that the stf router expects +// us to provide it the msg name, but the core router interface does not have +// such requirement. +type stfRouterWrapper struct { + stfRouter *stf.MsgRouterBuilder + + error error + + handlers map[string]appmodulev2.Handler +} + +func (s *stfRouterWrapper) RegisterHandler(handler appmodulev2.Handler) { + req := handler.MakeMsg() + requestName := gogoproto.MessageName(req) + if requestName == "" { + s.error = errors.Join(s.error, fmt.Errorf("unable to extract request name for type: %T", req)) + } + + // register handler to stf router + err := s.stfRouter.RegisterHandler(requestName, handler.Func) + s.error = errors.Join(s.error, err) + + // also make the decoder + if s.error == nil { + s.handlers = map[string]appmodulev2.Handler{} + } + s.handlers[requestName] = handler +} diff --git a/runtime/v2/module.go b/runtime/v2/module.go index d4a9b4b534d9..a95e38f96ea5 100644 --- a/runtime/v2/module.go +++ b/runtime/v2/module.go @@ -16,6 +16,7 @@ import ( reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" appmodulev2 "cosmossdk.io/core/appmodule/v2" "cosmossdk.io/core/comet" + "cosmossdk.io/core/event" "cosmossdk.io/core/header" "cosmossdk.io/core/registry" "cosmossdk.io/core/server" @@ -26,6 +27,7 @@ import ( "cosmossdk.io/log" "cosmossdk.io/runtime/v2/services" "cosmossdk.io/server/v2/stf" + rootstore "cosmossdk.io/store/v2/root" ) var ( @@ -40,19 +42,19 @@ type appModule[T transaction.Tx] struct { func (m appModule[T]) IsOnePerModuleType() {} func (m appModule[T]) IsAppModule() {} -func (m appModule[T]) RegisterServices(registar grpc.ServiceRegistrar) error { +func (m appModule[T]) RegisterServices(registrar grpc.ServiceRegistrar) error { autoCliQueryService, err := services.NewAutoCLIQueryService(m.app.moduleManager.modules) if err != nil { return err } - autocliv1.RegisterQueryServer(registar, autoCliQueryService) + autocliv1.RegisterQueryServer(registrar, autoCliQueryService) reflectionSvc, err := services.NewReflectionService() if err != nil { return err } - reflectionv1.RegisterReflectionServiceServer(registar, reflectionSvc) + reflectionv1.RegisterReflectionServiceServer(registrar, reflectionSvc) return nil } @@ -97,6 +99,7 @@ func init() { ProvideAppBuilder[transaction.Tx], ProvideEnvironment[transaction.Tx], ProvideModuleManager[transaction.Tx], + ProvideStoreBuilder, ), appconfig.Invoke(SetupAppBuilder), ) @@ -124,13 +127,13 @@ func ProvideAppBuilder[T transaction.Tx]( msgRouterBuilder := stf.NewMsgRouterBuilder() app := &App[T]{ - storeKeys: nil, - interfaceRegistrar: interfaceRegistrar, - amino: amino, - msgRouterBuilder: msgRouterBuilder, - queryRouterBuilder: stf.NewMsgRouterBuilder(), // TODO dedicated query router - GRPCMethodsToMessageMap: map[string]func() proto.Message{}, - storeLoader: DefaultStoreLoader, + storeKeys: nil, + interfaceRegistrar: interfaceRegistrar, + amino: amino, + msgRouterBuilder: msgRouterBuilder, + queryRouterBuilder: stf.NewMsgRouterBuilder(), // TODO dedicated query router + QueryHandlers: map[string]appmodulev2.Handler{}, + storeLoader: DefaultStoreLoader, } appBuilder := &AppBuilder[T]{app: app} @@ -146,7 +149,12 @@ type AppInputs struct { InterfaceRegistrar registry.InterfaceRegistrar LegacyAmino registry.AminoRegistrar Logger log.Logger - DynamicConfig server.DynamicConfig `optional:"true"` // can be nil in client wiring + // StoreBuilder is a builder for a store/v2 RootStore satisfying the Store interface + StoreBuilder *StoreBuilder + // StoreOptions are required as input for the StoreBuilder. If not provided, the default options are used. + StoreOptions *rootstore.Options `optional:"true"` + // DynamicConfig can be nil in client wiring, but is required in server wiring. + DynamicConfig server.DynamicConfig `optional:"true"` } func SetupAppBuilder(inputs AppInputs) { @@ -157,8 +165,22 @@ func SetupAppBuilder(inputs AppInputs) { app.moduleManager.RegisterInterfaces(inputs.InterfaceRegistrar) app.moduleManager.RegisterLegacyAminoCodec(inputs.LegacyAmino) - if inputs.DynamicConfig != nil { - inputs.AppBuilder.config = inputs.DynamicConfig + if inputs.DynamicConfig == nil { + return + } + storeOptions := rootstore.DefaultStoreOptions() + if inputs.StoreOptions != nil { + storeOptions = *inputs.StoreOptions + } + var err error + app.db, err = inputs.StoreBuilder.Build( + inputs.Logger, + app.storeKeys, + inputs.DynamicConfig, + storeOptions, + ) + if err != nil { + panic(err) } } @@ -178,6 +200,7 @@ func ProvideEnvironment[T transaction.Tx]( appBuilder *AppBuilder[T], kvFactory store.KVStoreServiceFactory, headerService header.Service, + eventService event.Service, ) ( appmodulev2.Environment, store.KVStoreService, @@ -209,7 +232,7 @@ func ProvideEnvironment[T transaction.Tx]( env := appmodulev2.Environment{ Logger: logger, BranchService: stf.BranchService{}, - EventService: stf.NewEventService(), + EventService: eventService, GasService: stf.NewGasMeterService(), HeaderService: headerService, QueryRouterService: stf.NewQueryRouterService(), @@ -254,10 +277,12 @@ func DefaultServiceBindings() depinject.Config { } headerService header.Service = services.NewGenesisHeaderService(stf.HeaderService{}) cometService comet.Service = &services.ContextAwareCometInfoService{} + eventService = stf.NewEventService() ) return depinject.Supply( kvServiceFactory, headerService, cometService, + eventService, ) } diff --git a/runtime/v2/store.go b/runtime/v2/store.go index 40912ea41f48..6c45dd5e72db 100644 --- a/runtime/v2/store.go +++ b/runtime/v2/store.go @@ -3,11 +3,16 @@ package runtime import ( "errors" "fmt" + "path/filepath" + "cosmossdk.io/core/server" "cosmossdk.io/core/store" + "cosmossdk.io/log" "cosmossdk.io/server/v2/stf" storev2 "cosmossdk.io/store/v2" + "cosmossdk.io/store/v2/db" "cosmossdk.io/store/v2/proof" + "cosmossdk.io/store/v2/root" ) // NewKVStoreService creates a new KVStoreService. @@ -59,6 +64,58 @@ type Store interface { LastCommitID() (proof.CommitID, error) } +// StoreBuilder is a builder for a store/v2 RootStore satisfying the Store interface. +type StoreBuilder struct { + store Store +} + +// Build creates a new store/v2 RootStore. +func (sb *StoreBuilder) Build( + logger log.Logger, + storeKeys []string, + config server.DynamicConfig, + options root.Options, +) (Store, error) { + if sb.store != nil { + return sb.store, nil + } + home := config.GetString(flagHome) + scRawDb, err := db.NewDB( + db.DBType(config.GetString("store.app-db-backend")), + "application", + filepath.Join(home, "data"), + nil, + ) + if err != nil { + return nil, fmt.Errorf("failed to create SCRawDB: %w", err) + } + + factoryOptions := &root.FactoryOptions{ + Logger: logger, + RootDir: home, + Options: options, + // STF needs to store a bit of state + StoreKeys: append(storeKeys, "stf"), + SCRawDB: scRawDb, + } + + rs, err := root.CreateRootStore(factoryOptions) + if err != nil { + return nil, fmt.Errorf("failed to create root store: %w", err) + } + sb.store = rs + return sb.store, nil +} + +// Get returns the Store. Build must be called before calling Get or the result will be nil. +func (sb *StoreBuilder) Get() Store { + return sb.store +} + +func ProvideStoreBuilder() *StoreBuilder { + return &StoreBuilder{} +} + // StoreLoader allows for custom loading of the store, this is useful when upgrading the store from a previous version type StoreLoader func(store Store) error diff --git a/runtime/v2/types.go b/runtime/v2/types.go index baa20182b512..9018af921b1c 100644 --- a/runtime/v2/types.go +++ b/runtime/v2/types.go @@ -14,7 +14,7 @@ import ( const ( ModuleName = "runtime" - FlagHome = "home" + flagHome = "home" ) // validateProtoAnnotations validates that the proto annotations are correct. diff --git a/schema/api.go b/schema/api.go new file mode 100644 index 000000000000..3d8224a9a6d9 --- /dev/null +++ b/schema/api.go @@ -0,0 +1,98 @@ +package schema + +// APIDescriptor is a public versioned descriptor of an API. +// +// An APIDescriptor can be used as a native descriptor of an API's encoding. +// The native binary encoding of API requests and responses is to encode the input and output +// fields using value binary encoding. +// The native JSON encoding would be to encode the fields as a JSON object, canonically +// sorted by field name with no extra whitespace. +// Thus, APIDefinitions have deterministic binary and JSON encodings. +// +// APIDefinitions have a strong definition of compatibility between different versions +// of the same API. +// It is an INCOMPATIBLE change to add new input fields to existing methods or to remove or modify +// existing input or output fields. +// Input fields also cannot reference any unsealed structs, directly or transitively, +// because these types allow adding new fields. +// Adding new input fields to a method introduces the possibility that a newer client +// will send an incomprehensible message to an older server. +// The only safe ways that input field schemas can be extended are by adding +// new values to EnumType's and new cases to OneOfType's. +// It is a COMPATIBLE change to add new methods to an API and to add new output fields +// to existing methods. +// Output fields can reference any sealed or unsealed StructType, directly or transitively. +// +// Existing protobuf APIs could also be mapped into APIDefinitions, and used in the following ways: +// - to produce, user-friendly deterministic JSON +// - to produce a deterministic binary encoding +// - to check for compatibility in a way that is more appropriate to blockchain applications +// - to use any code generators designed to support this spec as an alternative to protobuf +// Also, a standardized way of serializing schema types as protobuf could be defined which +// maps to the original protobuf encoding, so that schemas can be used as an interop +// layer between different less expressive encoding systems. +// +// Existing EVM contract APIs expressed in Solidity could be mapped into APIDefinitions, and +// a mapping of all schema values to ABI encoding could be defined which preserves the +// original ABI encoding. +// +// In this way, we can define an interop layer between contracts in the EVM world, +// SDK modules accepting protobuf types, and any API using this schema system natively. +type APIDescriptor struct { + // Name is the versioned name of the API. + Name string + + // Methods is the list of methods in the API. + // It is a COMPATIBLE change to add new methods to an API. + // If a newer client tries to call a method that an older server does not recognize it, + // an error will simply be returned. + Methods []MethodDescriptor +} + +// MethodDescriptor describes a method in the API. +type MethodDescriptor struct { + // Name is the name of the method. + Name string + + // InputFields is the list of input fields for the method. + // + // It is an INCOMPATIBLE change to add, remove or update input fields to a method. + // The addition of new fields introduces the possibility that a newer client + // will send an incomprehensible message to an older server. + // InputFields can only reference sealed StructTypes, either directly and transitively. + // + // As a special case to represent protobuf service definitions, there can be a single + // unnamed struct input field that code generators can choose to either reference + // as a named struct or to expand inline as function arguments. + InputFields []Field + + // OutputFields is the list of output fields for the method. + // + // It is a COMPATIBLE change to add new output fields to a method, + // but existing output fields should not be removed or modified. + // OutputFields can reference any sealed or unsealed StructType, directly or transitively. + // If a newer client tries to call a method on an older server, the newer expected result output + // fields will simply be populated with the default values for that field kind. + // + // As a special case to represent protobuf service definitions, there can be a single + // unnamed struct output field. + // In this case, adding new output fields is an INCOMPATIBLE change (because protobuf service definitions + // don't allow this), but new fields can be added to the referenced struct if it is unsealed. + OutputFields []Field + + // Volatility is the volatility of the method. + Volatility Volatility +} + +// Volatility is the volatility of a method. +type Volatility int + +const ( + // PureVolatility indicates that the method can neither read nor write state. + PureVolatility Volatility = iota + // ReadonlyVolatility indicates that the method can read state but not write state. + ReadonlyVolatility + + // VolatileVolatility indicates that the method can read and write state. + VolatileVolatility +) diff --git a/schema/field.go b/schema/field.go index dfbae6ed1b97..b2bc76a2e3b6 100644 --- a/schema/field.go +++ b/schema/field.go @@ -15,8 +15,21 @@ type Field struct { // Nullable indicates whether null values are accepted for the field. Key fields CANNOT be nullable. Nullable bool `json:"nullable,omitempty"` - // ReferencedType is the referenced type name when Kind is EnumKind. + // ReferencedType is the referenced type name when Kind is EnumKind, StructKind or OneOfKind. ReferencedType string `json:"referenced_type,omitempty"` + + // ElementKind is the element type when Kind is ListKind. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + ElementKind Kind `json:"element_kind,omitempty"` + + // Size specifies the size or max-size of a field. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // Its specific meaning may vary depending on the field kind. + // For IntNKind and UintNKind fields, it specifies the bit width of the field. + // For StringKind, BytesKind, AddressKind, and JSONKind, fields it specifies the maximum length rather than a fixed length. + // If it is 0, such fields have no maximum length. + // It is invalid to have a non-zero Size for other kinds. + Size uint32 `json:"size,omitempty"` } // Validate validates the field. diff --git a/schema/indexer/README.md b/schema/indexer/README.md index 9fdec6753a27..9892bccea28d 100644 --- a/schema/indexer/README.md +++ b/schema/indexer/README.md @@ -6,7 +6,7 @@ Indexer implementations should be registered with the `indexer.Register` functio # Integrating the Indexer Manager -The indexer manager should be used for managing all indexers and should be integrated directly with applications wishing to support indexing. The `StartManager` function is used to start the manager. The configuration options for the manager and all indexer targets should be passed as the ManagerOptions.Config field and should match the json structure of ManagerConfig. An example configuration section in `app.toml` might look like this: +The indexer manager should be used for managing all indexers and should be integrated directly with applications wishing to support indexing. The `StartIndexing` function is used to start the manager. The configuration options for the manager and all indexer targets should be passed as the ManagerOptions.Config field and should match the json structure of ManagerConfig. An example configuration section in `app.toml` might look like this: ```toml [indexer.target.postgres] diff --git a/schema/kind.go b/schema/kind.go index 5eedee68c244..0992b297baa7 100644 --- a/schema/kind.go +++ b/schema/kind.go @@ -10,12 +10,25 @@ import ( // Kind represents the basic type of a field in an object. // Each kind defines the following encodings: -// Go Encoding: the golang type which should be accepted by listeners and +// +// - Go Encoding: the golang type which should be accepted by listeners and // generated by decoders when providing entity updates. -// JSON Encoding: the JSON encoding which should be used when encoding the field to JSON. +// - JSON Encoding: the JSON encoding which should be used when encoding the field to JSON. +// - Key Binary Encoding: the encoding which should be used when encoding the field +// as a key in binary messages. Some encodings specify a terminal and non-terminal form +// depending on whether or not the field is the last field in the key. +// - Value Binary Encoding: the encoding which should be used when encoding the field +// as a value in binary messages. +// // When there is some non-determinism in an encoding, kinds should specify what // values they accept and also what is the canonical, deterministic encoding which // should be preferably emitted by serializers. +// +// Binary encodings were chosen based on what is likely to be the most convenient default binary encoding +// for state management implementations. This encoding allows for sorted keys whenever it is possible for a kind +// and is deterministic. +// Modules that use the specified encoding natively will have a trivial decoder implementation because the +// encoding is already in the correct format after any initial prefix bytes are stripped. type Kind int const ( @@ -25,54 +38,82 @@ const ( // StringKind is a string type. // Go Encoding: UTF-8 string with no null characters. // JSON Encoding: string + // Key Binary Encoding: + // non-terminal: UTF-8 string with no null characters suffixed with a null character + // terminal: UTF-8 string with no null characters + // Value Binary Encoding: the same value binary encoding as BytesKind. StringKind - // BytesKind is a bytes type. + // BytesKind represents a byte array. // Go Encoding: []byte // JSON Encoding: base64 encoded string, canonical values should be encoded with standard encoding and padding. // Either standard or URL encoding with or without padding should be accepted. + // Key Binary Encoding: + // non-terminal: length prefixed bytes where the width of the length prefix is 1, 2, 3 or 4 bytes depending on + // the field's MaxLength (defaulting to 4 bytes). + // Length prefixes should be big-endian encoded. + // Values larger than 2^32 bytes are not supported (likely key-value stores impose a lower limit). + // terminal: raw bytes with no length prefix + // Value Binary Encoding: two 32-bit unsigned little-endian integers, the first one representing the offset of the + // value in the buffer and the second one representing the length of the value. BytesKind // Int8Kind represents an 8-bit signed integer. // Go Encoding: int8 // JSON Encoding: number + // Key Binary Encoding: 1-byte two's complement encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 1-byte two's complement encoding. Int8Kind // Uint8Kind represents an 8-bit unsigned integer. // Go Encoding: uint8 // JSON Encoding: number + // Key Binary Encoding: 1-byte unsigned encoding. + // Value Binary Encoding: 1-byte unsigned encoding. Uint8Kind // Int16Kind represents a 16-bit signed integer. // Go Encoding: int16 // JSON Encoding: number + // Key Binary Encoding: 2-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 2 byte two's complement little-endian encoding. Int16Kind // Uint16Kind represents a 16-bit unsigned integer. // Go Encoding: uint16 // JSON Encoding: number + // Key Binary Encoding: 2-byte unsigned big-endian encoding. + // Value Binary Encoding: 2-byte unsigned little-endian encoding. Uint16Kind // Int32Kind represents a 32-bit signed integer. // Go Encoding: int32 // JSON Encoding: number + // Key Binary Encoding: 4-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 4-byte two's complement little-endian encoding. Int32Kind // Uint32Kind represents a 32-bit unsigned integer. // Go Encoding: uint32 // JSON Encoding: number + // Key Binary Encoding: 4-byte unsigned big-endian encoding. + // Value Binary Encoding: 4-byte unsigned little-endian encoding. Uint32Kind // Int64Kind represents a 64-bit signed integer. // Go Encoding: int64 // JSON Encoding: base10 integer string which matches the IntegerFormat regex // The canonical encoding should include no leading zeros. + // Key Binary Encoding: 8-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 8-byte two's complement little-endian encoding. Int64Kind // Uint64Kind represents a 64-bit unsigned integer. // Go Encoding: uint64 // JSON Encoding: base10 integer string which matches the IntegerFormat regex // Canonically encoded values should include no leading zeros. + // Key Binary Encoding: 8-byte unsigned big-endian encoding. + // Value Binary Encoding: 8-byte unsigned little-endian encoding. Uint64Kind // IntegerKind represents an arbitrary precision integer number. @@ -98,6 +139,8 @@ const ( // BoolKind represents a boolean true or false value. // Go Encoding: bool // JSON Encoding: boolean + // Key Binary Encoding: 1-byte encoding where 0 is false and 1 is true. + // Value Binary Encoding: 1-byte encoding where 0 is false and 1 is true. BoolKind // TimeKind represents a nanosecond precision UNIX time value (with zero representing January 1, 1970 UTC). @@ -107,6 +150,8 @@ const ( // Canonical values should be encoded with UTC time zone Z, nanoseconds should // be encoded with no trailing zeros, and T time values should always be present // even at 00:00:00. + // Key Binary Encoding: 8-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 8-byte two's complement little-endian encoding. TimeKind // DurationKind represents the elapsed time between two nanosecond precision time values. @@ -114,24 +159,35 @@ const ( // Go Encoding: time.Duration // JSON Encoding: the number of seconds as a decimal string with no trailing zeros followed by // a lowercase 's' character to represent seconds. + // Key Binary Encoding: 8-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 8-byte two's complement little-endian encoding. DurationKind // Float32Kind represents an IEEE-754 32-bit floating point number. // Go Encoding: float32 // JSON Encoding: number + // Key Binary Encoding: 4-byte IEEE-754 encoding. + // Value Binary Encoding: 4-byte IEEE-754 encoding. Float32Kind // Float64Kind represents an IEEE-754 64-bit floating point number. // Go Encoding: float64 // JSON Encoding: number + // Key Binary Encoding: 8-byte IEEE-754 encoding. + // Value Binary Encoding: 8-byte IEEE-754 encoding. Float64Kind // AddressKind represents an account address which is represented by a variable length array of bytes. // Addresses usually have a human-readable rendering, such as bech32, and tooling should provide - // a way for apps to define a string encoder for friendly user-facing display. + // a way for apps to define a string encoder for friendly user-facing display. Addresses have a maximum + // supported length of 63 bytes. // Go Encoding: []byte // JSON Encoding: addresses should be encoded as strings using the human-readable address renderer // provided to the JSON encoder. + // Key Binary Encoding: + // non-terminal: bytes prefixed with 1-byte length prefix + // terminal: raw bytes with no length prefix + // Value Binary Encoding: bytes prefixed with 1-byte length prefix. AddressKind // EnumKind represents a value of an enum type. @@ -139,12 +195,68 @@ const ( // definition. // Go Encoding: string // JSON Encoding: string + // Key Binary Encoding: the same binary encoding as the EnumType's numeric kind. + // Value Binary Encoding: the same binary encoding as the EnumType's numeric kind. EnumKind // JSONKind represents arbitrary JSON data. // Go Encoding: json.RawMessage // JSON Encoding: any valid JSON value + // Key Binary Encoding: string encoding + // Value Binary Encoding: string encoding JSONKind + + // UIntNKind represents a signed integer type with a width in bits specified by the Size field in the + // field definition. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // N must be a multiple of 8, and it is invalid for N to equal 8, 16, 32, 64 as there are more specific + // types for these widths. + // Go Encoding: []byte where len([]byte) == Size / 8, little-endian encoded. + // JSON Encoding: base10 integer string matching the IntegerFormat regex, canonically with no leading zeros. + // Key Binary Encoding: N / 8 bytes big-endian encoded + // Value Binary Encoding: N / 8 bytes little-endian encoded + UIntNKind + + // IntNKind represents an unsigned integer type with a width in bits specified by the Size field in the + // field definition. N must be a multiple of 8. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // N must be a multiple of 8, and it is invalid for N to equal 8, 16, 32, 64 as there are more specific + // types for these widths. + // Go Encoding: []byte where len([]byte) == Size / 8, two's complement little-endian encoded. + // JSON Encoding: base10 integer string matching the IntegerFormat regex, canonically with no leading zeros. + // Key Binary Encoding: N / 8 bytes big-endian two's complement encoded with the first bit inverted for sorting. + // Value Binary Encoding: N / 8 bytes little-endian two's complement encoded. + IntNKind + + // StructKind represents a struct object. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // Go Encoding: an array of type []interface{} where each element is of the respective field's kind type. + // JSON Encoding: an object where each key is the field name and the value is the field value. + // Canonically, keys are in alphabetical order with no extra whitespace. + // Key Binary Encoding: not valid as a key field. + // Value Binary Encoding: 32-bit unsigned little-endian length prefix, + // followed by the value binary encoding of each field in order. + StructKind + + // OneOfKind represents a field that can be one of a set of types. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // Go Encoding: the anonymous struct { Case string; Value interface{} }, aliased as OneOfValue. + // JSON Encoding: same as the case's struct encoding with "@type" set to the case name. + // Key Binary Encoding: not valid as a key field. + // Value Binary Encoding: the oneof's discriminant numeric value encoded as its discriminant kind + // followed by the encoded value. + OneOfKind + + // ListKind represents a list of elements. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // Go Encoding: an array of type []interface{} where each element is of the respective field's kind type. + // JSON Encoding: an array of values where each element is the field value. + // Canonically, there is no extra whitespace. + // Key Binary Encoding: not valid as a key field. + // Value Binary Encoding: 32-bit unsigned little-endian size prefix indicating the size of the encoded data in bytes, + // followed by a 32-bit unsigned little-endian count of the number of elements in the list, + // followed by each element encoded with value binary encoding. + ListKind ) // MAX_VALID_KIND is the maximum valid kind value. diff --git a/schema/oneof.go b/schema/oneof.go new file mode 100644 index 000000000000..ec0cd6d649ae --- /dev/null +++ b/schema/oneof.go @@ -0,0 +1,43 @@ +package schema + +// OneOfType represents a oneof type. +// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. +type OneOfType struct { + // Name is the name of the oneof type. It must conform to the NameFormat regular expression. + Name string + + // Cases is a list of cases in the oneof type. + // It is a COMPATIBLE change to add new cases to a oneof type. + // If a newer client tries to send a message with a case that an older server does not recognize, + // the older server will simply reject it in a switch statement. + // It is INCOMPATIBLE to remove existing cases from a oneof type. + Cases []OneOfCase + + // DiscriminantKind is the kind of the discriminant field. + // It must be Uint8Kind, Int8Kind, Uint16Kind, Int16Kind, or Int32Kind. + DiscriminantKind Kind +} + +// OneOfCase represents a case in a oneof type. It is represented by a struct type internally with a discriminant value. +type OneOfCase struct { + // Name is the name of the case. It must conform to the NameFormat regular expression. + Name string + + // Discriminant is the discriminant value for the case. + Discriminant int32 + + // Kind is the kind of the case. ListKind is not allowed. + Kind Kind + + // Reference is the referenced type if Kind is EnumKind, StructKind, or OneOfKind. + ReferencedType string +} + +// OneOfValue is the golang runtime representation of a oneof value. +type OneOfValue = struct { + // Case is the name of the case. + Case string + + // Value is the value of the case. + Value interface{} +} diff --git a/schema/state_object.go b/schema/state_object.go index a4825726f685..eff8d1f98459 100644 --- a/schema/state_object.go +++ b/schema/state_object.go @@ -9,16 +9,23 @@ type StateObjectType struct { Name string `json:"name"` // KeyFields is a list of fields that make up the primary key of the object. - // It can be empty in which case indexers should assume that this object is + // It can be empty, in which case, indexers should assume that this object is // a singleton and only has one value. Field names must be unique within the // object between both key and value fields. - // Key fields CANNOT be nullable and Float32Kind, Float64Kind, and JSONKind types - // are not allowed. + // Key fields CANNOT be nullable and Float32Kind, Float64Kind, JSONKind, StructKind, + // OneOfKind, RepeatedKind, ListKind or ObjectKind + // are NOT ALLOWED. + // It is an INCOMPATIBLE change to add, remove or change fields in the key as this + // changes the underlying primary key of the object. KeyFields []Field `json:"key_fields,omitempty"` // ValueFields is a list of fields that are not part of the primary key of the object. // It can be empty in the case where all fields are part of the primary key. // Field names must be unique within the object between both key and value fields. + // ObjectKind fields are not allowed. + // It is a COMPATIBLE change to add new value fields to an object type because + // this does not affect the primary key of the object. + // Existing value fields should not be removed or modified. ValueFields []Field `json:"value_fields,omitempty"` // RetainDeletions is a flag that indicates whether the indexer should retain diff --git a/schema/struct.go b/schema/struct.go new file mode 100644 index 000000000000..20676a743ade --- /dev/null +++ b/schema/struct.go @@ -0,0 +1,21 @@ +package schema + +// StructType represents a struct type. +// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. +type StructType struct { + // Name is the name of the struct type. + Name string + + // Fields is the list of fields in the struct. + // It is a COMPATIBLE change to add new fields to an unsealed struct, + // but it is an INCOMPATIBLE change to add new fields to a sealed struct. + // + // A sealed struct cannot reference any unsealed structs directly or + // transitively because these types allow adding new fields. + Fields []Field + + // Sealed is true if it is an INCOMPATIBLE change to add new fields to the struct. + // It is a COMPATIBLE change to change an unsealed struct to sealed, but it is + // an INCOMPATIBLE change to change a sealed struct to unsealed. + Sealed bool +} diff --git a/scripts/local-testnet.sh b/scripts/local-testnet.sh deleted file mode 100644 index c73710dbab1e..000000000000 --- a/scripts/local-testnet.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -x - -ROOT=$PWD - -SIMD="$ROOT/build/simdv2" - -COSMOS_BUILD_OPTIONS=v2 make build - -$SIMD testnet init-files --chain-id=testing --output-dir="$HOME/.testnet" --validator-count=3 --keyring-backend=test --minimum-gas-prices=0.000001stake --commit-timeout=900ms --single-host - -$SIMD start --log_level=info --home "$HOME/.testnet/node0/simdv2" & -$SIMD start --log_level=info --home "$HOME/.testnet/node1/simdv2" & -$SIMD start --log_level=info --home "$HOME/.testnet/node2/simdv2" \ No newline at end of file diff --git a/server/start.go b/server/start.go index cff5807fbdb4..f9ae56676305 100644 --- a/server/start.go +++ b/server/start.go @@ -9,6 +9,7 @@ import ( "io" "net" "os" + "path/filepath" "runtime/pprof" "strings" "time" @@ -780,6 +781,17 @@ func testnetify[T types.Application](ctx *Context, testnetAppCreator types.AppCr return nil, err } + // Regenerate addrbook.json to prevent peers on old network from causing error logs. + addrBookPath := filepath.Join(config.RootDir, "config", "addrbook.json") + if err := os.Remove(addrBookPath); err != nil && !os.IsNotExist(err) { + return nil, fmt.Errorf("failed to remove existing addrbook.json: %w", err) + } + + emptyAddrBook := []byte("{}") + if err := os.WriteFile(addrBookPath, emptyAddrBook, 0o600); err != nil { + return nil, fmt.Errorf("failed to create empty addrbook.json: %w", err) + } + // Load the comet genesis doc provider. genDocProvider := node.DefaultGenesisDocProviderFunc(config) diff --git a/server/v2/api/grpc/config.go b/server/v2/api/grpc/config.go index 86fb514e70d8..4e9cabc7a418 100644 --- a/server/v2/api/grpc/config.go +++ b/server/v2/api/grpc/config.go @@ -4,14 +4,9 @@ import "math" func DefaultConfig() *Config { return &Config{ - Enable: true, - // DefaultGRPCAddress defines the default address to bind the gRPC server to. - Address: "localhost:9090", - // DefaultGRPCMaxRecvMsgSize defines the default gRPC max message size in - // bytes the server can receive. + Enable: true, + Address: "localhost:9090", MaxRecvMsgSize: 1024 * 1024 * 10, - // DefaultGRPCMaxSendMsgSize defines the default gRPC max message size in - // bytes the server can send. MaxSendMsgSize: math.MaxInt32, } } diff --git a/server/v2/api/grpc/gogoreflection/fix_registration.go b/server/v2/api/grpc/gogoreflection/fix_registration.go index d4edfc62b5e7..5704f054ff61 100644 --- a/server/v2/api/grpc/gogoreflection/fix_registration.go +++ b/server/v2/api/grpc/gogoreflection/fix_registration.go @@ -41,12 +41,12 @@ func getExtension(extID int32, m proto.Message) *gogoproto.ExtensionDesc { for id, desc := range proto.RegisteredExtensions(m) { //nolint:staticcheck // keep for backward compatibility if id == extID { return &gogoproto.ExtensionDesc{ - ExtendedType: desc.ExtendedType, - ExtensionType: desc.ExtensionType, - Field: desc.Field, - Name: desc.Name, - Tag: desc.Tag, - Filename: desc.Filename, + ExtendedType: desc.ExtendedType, + ExtensionType: desc.ExtensionType, + Field: desc.Field, + Name: desc.Name, + Tag: desc.Tag, + Filename: desc.Filename, } } } diff --git a/server/v2/api/grpc/server.go b/server/v2/api/grpc/server.go index 0003f2343222..7b70363f6f16 100644 --- a/server/v2/api/grpc/server.go +++ b/server/v2/api/grpc/server.go @@ -9,14 +9,18 @@ import ( "net" "slices" "strconv" + "strings" + "sync" - "github.com/cosmos/gogoproto/proto" + gogoproto "github.com/cosmos/gogoproto/proto" "github.com/spf13/pflag" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "google.golang.org/protobuf/reflect/protoreflect" + appmodulev2 "cosmossdk.io/core/appmodule/v2" "cosmossdk.io/core/transaction" "cosmossdk.io/log" serverv2 "cosmossdk.io/server/v2" @@ -53,7 +57,7 @@ func (s *Server[T]) Init(appI serverv2.AppI[T], cfg map[string]any, logger log.L return fmt.Errorf("failed to unmarshal config: %w", err) } } - methodsMap := appI.GetGPRCMethodsToMessageMap() + methodsMap := appI.GetQueryHandlers() grpcSrv := grpc.NewServer( grpc.ForceServerCodec(newProtoCodec(appI.InterfaceRegistry()).GRPCCodec()), @@ -80,21 +84,42 @@ func (s *Server[T]) StartCmdFlags() *pflag.FlagSet { return flags } -func makeUnknownServiceHandler(messageMap map[string]func() proto.Message, querier interface { - Query(ctx context.Context, version uint64, msg proto.Message) (proto.Message, error) +func makeUnknownServiceHandler(handlers map[string]appmodulev2.Handler, querier interface { + Query(ctx context.Context, version uint64, msg gogoproto.Message) (gogoproto.Message, error) }, ) grpc.StreamHandler { + getRegistry := sync.OnceValues(gogoproto.MergedRegistry) + return func(srv any, stream grpc.ServerStream) error { method, ok := grpc.MethodFromServerStream(stream) if !ok { return status.Error(codes.InvalidArgument, "unable to get method") } - makeMsg, exists := messageMap[method] + // if this fails we cannot serve queries anymore... + registry, err := getRegistry() + if err != nil { + return fmt.Errorf("failed to get registry: %w", err) + } + + method = strings.TrimPrefix(method, "/") + fullName := protoreflect.FullName(strings.ReplaceAll(method, "/", ".")) + // get descriptor from the invoke method + desc, err := registry.FindDescriptorByName(fullName) + if err != nil { + return fmt.Errorf("failed to find descriptor %s: %w", method, err) + } + md, ok := desc.(protoreflect.MethodDescriptor) + if !ok { + return fmt.Errorf("%s is not a method", method) + } + // find handler + handler, exists := handlers[string(md.Input().FullName())] if !exists { return status.Errorf(codes.Unimplemented, "gRPC method %s is not handled", method) } + for { - req := makeMsg() + req := handler.MakeMsg() err := stream.RecvMsg(req) if err != nil { if errors.Is(err, io.EOF) { @@ -148,7 +173,7 @@ func (s *Server[T]) Name() string { } func (s *Server[T]) Config() any { - if s.config == nil || s.config == (&Config{}) { + if s.config == nil || s.config.Address == "" { cfg := DefaultConfig() // overwrite the default config with the provided options for _, opt := range s.cfgOptions { @@ -163,6 +188,7 @@ func (s *Server[T]) Config() any { func (s *Server[T]) Start(ctx context.Context) error { if !s.config.Enable { + s.logger.Info(fmt.Sprintf("%s server is disabled via config", s.Name())) return nil } @@ -171,24 +197,12 @@ func (s *Server[T]) Start(ctx context.Context) error { return fmt.Errorf("failed to listen on address %s: %w", s.config.Address, err) } - errCh := make(chan error) - - // Start the gRPC in an external goroutine as Serve is blocking and will return - // an error upon failure, which we'll send on the error channel that will be - // consumed by the for block below. - go func() { - s.logger.Info("starting gRPC server...", "address", s.config.Address) - errCh <- s.grpcSrv.Serve(listener) - }() - - // Start a blocking select to wait for an indication to stop the server or that - // the server failed to start properly. - err = <-errCh - if err != nil { - s.logger.Error("failed to start gRPC server", "err", err) + s.logger.Info("starting gRPC server...", "address", s.config.Address) + if err := s.grpcSrv.Serve(listener); err != nil { + return fmt.Errorf("failed to start gRPC server: %w", err) } - return err + return nil } func (s *Server[T]) Stop(ctx context.Context) error { @@ -198,6 +212,10 @@ func (s *Server[T]) Stop(ctx context.Context) error { s.logger.Info("stopping gRPC server...", "address", s.config.Address) s.grpcSrv.GracefulStop() - return nil } + +// GetGRPCServer returns the underlying gRPC server. +func (s *Server[T]) GetGRPCServer() *grpc.Server { + return s.grpcSrv +} diff --git a/server/v2/api/grpcgateway/config.go b/server/v2/api/grpcgateway/config.go index c5ccb3bfe2d1..773eeb4d58ad 100644 --- a/server/v2/api/grpcgateway/config.go +++ b/server/v2/api/grpcgateway/config.go @@ -2,13 +2,17 @@ package grpcgateway func DefaultConfig() *Config { return &Config{ - Enable: true, + Enable: true, + Address: "localhost:1317", } } type Config struct { // Enable defines if the gRPC-gateway should be enabled. Enable bool `mapstructure:"enable" toml:"enable" comment:"Enable defines if the gRPC-gateway should be enabled."` + + // Address defines the address the gRPC-gateway server binds to. + Address string `mapstructure:"address" toml:"address" comment:"Address defines the address the gRPC-gateway server binds to."` } type CfgOption func(*Config) diff --git a/server/v2/api/grpcgateway/server.go b/server/v2/api/grpcgateway/server.go index 05a6bf1aa829..412c4e4ad81d 100644 --- a/server/v2/api/grpcgateway/server.go +++ b/server/v2/api/grpcgateway/server.go @@ -8,7 +8,6 @@ import ( gateway "github.com/cosmos/gogogateway" "github.com/cosmos/gogoproto/jsonpb" - "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "google.golang.org/grpc" @@ -17,26 +16,25 @@ import ( serverv2 "cosmossdk.io/server/v2" ) -var _ serverv2.ServerComponent[transaction.Tx] = (*GRPCGatewayServer[transaction.Tx])(nil) - -const ( - ServerName = "grpc-gateway" - - // GRPCBlockHeightHeader is the gRPC header for block height. - GRPCBlockHeightHeader = "x-cosmos-block-height" +var ( + _ serverv2.ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil) + _ serverv2.HasConfig = (*Server[transaction.Tx])(nil) ) -type GRPCGatewayServer[T transaction.Tx] struct { +const ServerName = "grpc-gateway" + +type Server[T transaction.Tx] struct { logger log.Logger config *Config cfgOptions []CfgOption - GRPCSrv *grpc.Server - GRPCGatewayRouter *runtime.ServeMux + server *http.Server + gRPCSrv *grpc.Server + gRPCGatewayRouter *runtime.ServeMux } // New creates a new gRPC-gateway server. -func New[T transaction.Tx](grpcSrv *grpc.Server, ir jsonpb.AnyResolver, cfgOptions ...CfgOption) *GRPCGatewayServer[T] { +func New[T transaction.Tx](grpcSrv *grpc.Server, ir jsonpb.AnyResolver, cfgOptions ...CfgOption) *Server[T] { // The default JSON marshaller used by the gRPC-Gateway is unable to marshal non-nullable non-scalar fields. // Using the gogo/gateway package with the gRPC-Gateway WithMarshaler option fixes the scalar field marshaling issue. marshalerOption := &gateway.JSONPb{ @@ -46,9 +44,9 @@ func New[T transaction.Tx](grpcSrv *grpc.Server, ir jsonpb.AnyResolver, cfgOptio AnyResolver: ir, } - return &GRPCGatewayServer[T]{ - GRPCSrv: grpcSrv, - GRPCGatewayRouter: runtime.NewServeMux( + return &Server[T]{ + gRPCSrv: grpcSrv, + gRPCGatewayRouter: runtime.NewServeMux( // Custom marshaler option is required for gogo proto runtime.WithMarshalerOption(runtime.MIMEWildcard, marshalerOption), @@ -64,12 +62,12 @@ func New[T transaction.Tx](grpcSrv *grpc.Server, ir jsonpb.AnyResolver, cfgOptio } } -func (g *GRPCGatewayServer[T]) Name() string { +func (s *Server[T]) Name() string { return ServerName } -func (s *GRPCGatewayServer[T]) Config() any { - if s.config == nil || s.config == (&Config{}) { +func (s *Server[T]) Config() any { + if s.config == nil || s.config.Address == "" { cfg := DefaultConfig() // overwrite the default config with the provided options for _, opt := range s.cfgOptions { @@ -82,7 +80,7 @@ func (s *GRPCGatewayServer[T]) Config() any { return s.config } -func (s *GRPCGatewayServer[T]) Init(appI serverv2.AppI[transaction.Tx], cfg map[string]any, logger log.Logger) error { +func (s *Server[T]) Init(appI serverv2.AppI[transaction.Tx], cfg map[string]any, logger log.Logger) error { serverCfg := s.Config().(*Config) if len(cfg) > 0 { if err := serverv2.UnmarshalSubConfig(cfg, s.Name(), &serverCfg); err != nil { @@ -90,42 +88,43 @@ func (s *GRPCGatewayServer[T]) Init(appI serverv2.AppI[transaction.Tx], cfg map[ } } - // Register the gRPC-Gateway server. - // appI.RegisterGRPCGatewayRoutes(s.GRPCGatewayRouter, s.GRPCSrv) + // TODO: register the gRPC-Gateway routes - s.logger = logger + s.logger = logger.With(log.ModuleKey, s.Name()) s.config = serverCfg return nil } -func (s *GRPCGatewayServer[T]) Start(ctx context.Context) error { +func (s *Server[T]) Start(ctx context.Context) error { if !s.config.Enable { + s.logger.Info(fmt.Sprintf("%s server is disabled via config", s.Name())) return nil } - // TODO start a normal Go http server (and do not leverage comet's like https://github.com/cosmos/cosmos-sdk/blob/9df6019de6ee7999fe9864bac836deb2f36dd44a/server/api/server.go#L98) + mux := http.NewServeMux() + mux.Handle("/", s.gRPCGatewayRouter) - return nil -} + s.server = &http.Server{ + Addr: s.config.Address, + Handler: mux, + } -func (s *GRPCGatewayServer[T]) Stop(ctx context.Context) error { - if !s.config.Enable { - return nil + s.logger.Info("starting gRPC-Gateway server...", "address", s.config.Address) + if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + return fmt.Errorf("failed to start gRPC-Gateway server: %w", err) } return nil } -// Register implements registers a grpc-gateway server -func (s *GRPCGatewayServer[T]) Register(r mux.Router) error { - // configure grpc-gatway server - r.PathPrefix("/").Handler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - // Fall back to grpc gateway server. - s.GRPCGatewayRouter.ServeHTTP(w, req) - })) +func (s *Server[T]) Stop(ctx context.Context) error { + if !s.config.Enable { + return nil + } - return nil + s.logger.Info("stopping gRPC-Gateway server...", "address", s.config.Address) + return s.server.Shutdown(ctx) } // CustomGRPCHeaderMatcher for mapping request headers to @@ -134,6 +133,9 @@ func (s *GRPCGatewayServer[T]) Register(r mux.Router) error { // gRPC metadata after removing prefix 'Grpc-Metadata-'. We can use this // CustomGRPCHeaderMatcher if headers don't start with `Grpc-Metadata-` func CustomGRPCHeaderMatcher(key string) (string, bool) { + // GRPCBlockHeightHeader is the gRPC header for block height. + const GRPCBlockHeightHeader = "x-cosmos-block-height" + switch strings.ToLower(key) { case GRPCBlockHeightHeader: return GRPCBlockHeightHeader, true diff --git a/server/v2/api/telemetry/config.go b/server/v2/api/telemetry/config.go index 63a37ed1f39d..2619665d1844 100644 --- a/server/v2/api/telemetry/config.go +++ b/server/v2/api/telemetry/config.go @@ -1,13 +1,32 @@ package telemetry -type Config struct { - // Prefixed with keys to separate services - ServiceName string `mapstructure:"service-name" toml:"service-name" comment:"Prefixed with keys to separate services."` +func DefaultConfig() *Config { + return &Config{ + Enable: true, + Address: "localhost:1318", + ServiceName: "", + EnableHostname: false, + EnableHostnameLabel: false, + EnableServiceLabel: false, + PrometheusRetentionTime: 0, + GlobalLabels: nil, + MetricsSink: "", + StatsdAddr: "", + DatadogHostname: "", + } +} - // Enabled enables the application telemetry functionality. When enabled, +type Config struct { + // Enable enables the application telemetry functionality. When enabled, // an in-memory sink is also enabled by default. Operators may also enabled // other sinks such as Prometheus. - Enabled bool `mapstructure:"enabled" toml:"enabled" comment:"Enabled enables the application telemetry functionality. When enabled, an in-memory sink is also enabled by default. Operators may also enabled other sinks such as Prometheus."` + Enable bool `mapstructure:"enable" toml:"enable" comment:"Enable enables the application telemetry functionality. When enabled, an in-memory sink is also enabled by default. Operators may also enabled other sinks such as Prometheus."` + + // Address defines the API server to listen on + Address string `mapstructure:"address" toml:"address" comment:"Address defines the metrics server address to bind to."` + + // Prefixed with keys to separate services + ServiceName string `mapstructure:"service-name" toml:"service-name" comment:"Prefixed with keys to separate services."` // Enable prefixing gauge values with hostname EnableHostname bool `mapstructure:"enable-hostname" toml:"enable-hostname" comment:"Enable prefixing gauge values with hostname."` diff --git a/server/v2/api/telemetry/metrics.go b/server/v2/api/telemetry/metrics.go index 75e857bb8ec4..3dd9e3d55b94 100644 --- a/server/v2/api/telemetry/metrics.go +++ b/server/v2/api/telemetry/metrics.go @@ -57,12 +57,8 @@ type GatherResponse struct { ContentType string } -// New creates a new instance of Metrics -func New(cfg Config) (_ *Metrics, rerr error) { - if !cfg.Enabled { - return nil, nil - } - +// NewMetrics creates a new instance of Metrics +func NewMetrics(cfg *Config) (*Metrics, error) { if numGlobalLabels := len(cfg.GlobalLabels); numGlobalLabels > 0 { parsedGlobalLabels := make([]metrics.Label, numGlobalLabels) for i, gl := range cfg.GlobalLabels { @@ -89,12 +85,11 @@ func New(cfg Config) (_ *Metrics, rerr error) { sink = memSink inMemSig := metrics.DefaultInmemSignal(memSink) defer func() { - if rerr != nil { + if err != nil { inMemSig.Stop() } }() } - if err != nil { return nil, err } diff --git a/server/v2/api/telemetry/server.go b/server/v2/api/telemetry/server.go index a944fc7f4f03..411b1bda797d 100644 --- a/server/v2/api/telemetry/server.go +++ b/server/v2/api/telemetry/server.go @@ -1,47 +1,126 @@ package telemetry import ( + "context" "encoding/json" "fmt" "net/http" "strings" - "github.com/gorilla/mux" + "cosmossdk.io/core/transaction" + "cosmossdk.io/log" + serverv2 "cosmossdk.io/server/v2" ) -func RegisterMetrics(r mux.Router, cfg Config) (*Metrics, error) { - m, err := New(cfg) +var ( + _ serverv2.ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil) + _ serverv2.HasConfig = (*Server[transaction.Tx])(nil) +) + +const ServerName = "telemetry" + +type Server[T transaction.Tx] struct { + config *Config + logger log.Logger + server *http.Server + metrics *Metrics +} + +// New creates a new telemetry server. +func New[T transaction.Tx]() *Server[T] { + return &Server[T]{} +} + +// Name returns the server name. +func (s *Server[T]) Name() string { + return ServerName +} + +func (s *Server[T]) Config() any { + if s.config == nil || s.config.Address == "" { + return DefaultConfig() + } + + return s.config +} + +// Init implements serverv2.ServerComponent. +func (s *Server[T]) Init(appI serverv2.AppI[T], cfg map[string]any, logger log.Logger) error { + serverCfg := s.Config().(*Config) + if len(cfg) > 0 { + if err := serverv2.UnmarshalSubConfig(cfg, s.Name(), &serverCfg); err != nil { + return fmt.Errorf("failed to unmarshal config: %w", err) + } + } + s.config = serverCfg + s.logger = logger.With(log.ModuleKey, s.Name()) + + metrics, err := NewMetrics(s.config) if err != nil { - return nil, err + return fmt.Errorf("failed to initialize metrics: %w", err) } + s.metrics = metrics - metricsHandler := func(w http.ResponseWriter, r *http.Request) { - format := strings.TrimSpace(r.FormValue("format")) + return nil +} - gr, err := m.Gather(format) - if err != nil { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusBadRequest) - bz, err := json.Marshal(errorResponse{Code: 400, Error: fmt.Sprintf("failed to gather metrics: %s", err)}) - if err != nil { - return - } - _, _ = w.Write(bz) +func (s *Server[T]) Start(ctx context.Context) error { + if !s.config.Enable { + s.logger.Info(fmt.Sprintf("%s server is disabled via config", s.Name())) + return nil + } - return - } + mux := http.NewServeMux() + mux.HandleFunc("/", s.metricsHandler) + // keeping /metrics for backwards compatibility + mux.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/", http.StatusMovedPermanently) + }) - w.Header().Set("Content-Type", gr.ContentType) - _, _ = w.Write(gr.Metrics) + s.server = &http.Server{ + Addr: s.config.Address, + Handler: mux, } - r.HandleFunc("/metrics", metricsHandler).Methods("GET") + s.logger.Info("starting telemetry server...", "address", s.config.Address) + if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + return fmt.Errorf("failed to start telemetry server: %w", err) + } - return m, nil + return nil } -// errorResponse defines the attributes of a JSON error response. -type errorResponse struct { - Code int `json:"code,omitempty"` - Error string `json:"error"` +func (s *Server[T]) Stop(ctx context.Context) error { + if !s.config.Enable || s.server == nil { + return nil + } + + s.logger.Info("stopping telemetry server...", "address", s.config.Address) + return s.server.Shutdown(ctx) +} + +func (s *Server[T]) metricsHandler(w http.ResponseWriter, r *http.Request) { + format := strings.TrimSpace(r.FormValue("format")) + + // errorResponse defines the attributes of a JSON error response. + type errorResponse struct { + Code int `json:"code,omitempty"` + Error string `json:"error"` + } + + gr, err := s.metrics.Gather(format) + if err != nil { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusBadRequest) + bz, err := json.Marshal(errorResponse{Code: 400, Error: fmt.Sprintf("failed to gather metrics: %s", err)}) + if err != nil { + return + } + _, _ = w.Write(bz) + + return + } + + w.Header().Set("Content-Type", gr.ContentType) + _, _ = w.Write(gr.Metrics) } diff --git a/server/v2/cometbft/abci.go b/server/v2/cometbft/abci.go index 537b3e2dc5f5..cbcf387168a2 100644 --- a/server/v2/cometbft/abci.go +++ b/server/v2/cometbft/abci.go @@ -5,20 +5,27 @@ import ( "crypto/sha256" "errors" "fmt" + "strings" + "sync" "sync/atomic" abci "github.com/cometbft/cometbft/abci/types" abciproto "github.com/cometbft/cometbft/api/cometbft/abci/v1" gogoproto "github.com/cosmos/gogoproto/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "cosmossdk.io/collections" + appmodulev2 "cosmossdk.io/core/appmodule/v2" "cosmossdk.io/core/comet" corecontext "cosmossdk.io/core/context" "cosmossdk.io/core/event" "cosmossdk.io/core/server" "cosmossdk.io/core/store" "cosmossdk.io/core/transaction" - errorsmod "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors/v2" "cosmossdk.io/log" + "cosmossdk.io/schema/appdata" "cosmossdk.io/server/v2/appmanager" "cosmossdk.io/server/v2/cometbft/client/grpc/cmtservice" "cosmossdk.io/server/v2/cometbft/handlers" @@ -39,6 +46,7 @@ type Consensus[T transaction.Tx] struct { txCodec transaction.Codec[T] store types.Store streaming streaming.Manager + listener *appdata.Listener snapshotManager *snapshots.Manager mempool mempool.Mempool[T] @@ -56,11 +64,13 @@ type Consensus[T transaction.Tx] struct { processProposalHandler handlers.ProcessHandler[T] verifyVoteExt handlers.VerifyVoteExtensionhandler extendVote handlers.ExtendVoteHandler + checkTxHandler handlers.CheckTxHandler[T] addrPeerFilter types.PeerFilter // filter peers by address and port idPeerFilter types.PeerFilter // filter peers by node ID - grpcMethodsMap map[string]func() transaction.Msg // maps gRPC method to message creator func + queryHandlersMap map[string]appmodulev2.Handler + getProtoRegistry func() (*protoregistry.Files, error) } func NewConsensus[T transaction.Tx]( @@ -69,7 +79,7 @@ func NewConsensus[T transaction.Tx]( app *appmanager.AppManager[T], mp mempool.Mempool[T], indexedEvents map[string]struct{}, - gRPCMethodsMap map[string]func() transaction.Msg, + queryHandlersMap map[string]appmodulev2.Handler, store types.Store, cfg Config, txCodec transaction.Codec[T], @@ -78,7 +88,6 @@ func NewConsensus[T transaction.Tx]( return &Consensus[T]{ appName: appName, version: getCometBFTServerVersion(), - grpcMethodsMap: gRPCMethodsMap, app: app, cfg: cfg, store: store, @@ -95,6 +104,8 @@ func NewConsensus[T transaction.Tx]( chainID: chainId, indexedEvents: indexedEvents, initialHeight: 0, + queryHandlersMap: queryHandlersMap, + getProtoRegistry: sync.OnceValues(func() (*protoregistry.Files, error) { return gogoproto.MergedRegistry() }), } } @@ -103,6 +114,11 @@ func (c *Consensus[T]) SetStreamingManager(sm streaming.Manager) { c.streaming = sm } +// SetListener sets the listener for the consensus module. +func (c *Consensus[T]) SetListener(l *appdata.Listener) { + c.listener = l +} + // RegisterSnapshotExtensions registers the given extensions with the consensus module's snapshot manager. // It allows additional snapshotter implementations to be used for creating and restoring snapshots. func (c *Consensus[T]) RegisterSnapshotExtensions(extensions ...snapshots.ExtensionSnapshotter) error { @@ -121,27 +137,35 @@ func (c *Consensus[T]) CheckTx(ctx context.Context, req *abciproto.CheckTxReques return nil, err } - resp, err := c.app.ValidateTx(ctx, decodedTx) - if err != nil { - return nil, err - } + if c.checkTxHandler == nil { + resp, err := c.app.ValidateTx(ctx, decodedTx) + // we do not want to return a cometbft error, but a check tx response with the error + if err != nil && !errors.Is(err, resp.Error) { + return nil, err + } - events, err := intoABCIEvents(resp.Events, c.indexedEvents) - if err != nil { - return nil, err - } + events, err := intoABCIEvents(resp.Events, c.indexedEvents) + if err != nil { + return nil, err + } - cometResp := &abciproto.CheckTxResponse{ - Code: resp.Code, - GasWanted: uint64ToInt64(resp.GasWanted), - GasUsed: uint64ToInt64(resp.GasUsed), - Events: events, - } - if resp.Error != nil { - cometResp.Code = 1 - cometResp.Log = resp.Error.Error() + cometResp := &abciproto.CheckTxResponse{ + Code: 0, + GasWanted: uint64ToInt64(resp.GasWanted), + GasUsed: uint64ToInt64(resp.GasUsed), + Events: events, + } + if resp.Error != nil { + space, code, log := errorsmod.ABCIInfo(resp.Error, c.cfg.AppTomlConfig.Trace) + cometResp.Code = code + cometResp.Codespace = space + cometResp.Log = log + } + + return cometResp, nil } - return cometResp, nil + + return c.checkTxHandler(c.app.ValidateTx) } // Info implements types.Application. @@ -157,7 +181,7 @@ func (c *Consensus[T]) Info(ctx context.Context, _ *abciproto.InfoRequest) (*abc cp, err := c.GetConsensusParams(ctx) // if the consensus params are not found, we set the app version to 0 // in the case that the start version is > 0 - if cp == nil || errors.Is(err, errors.New("collections: not found")) { + if cp == nil || errors.Is(err, collections.ErrNotFound) { appVersion = 0 } else if err != nil { return nil, err @@ -186,23 +210,9 @@ func (c *Consensus[T]) Info(ctx context.Context, _ *abciproto.InfoRequest) (*abc // Query implements types.Application. // It is called by cometbft to query application state. func (c *Consensus[T]) Query(ctx context.Context, req *abciproto.QueryRequest) (resp *abciproto.QueryResponse, err error) { - // check if it's a gRPC method - makeGRPCRequest, isGRPC := c.grpcMethodsMap[req.Path] + resp, isGRPC, err := c.maybeRunGRPCQuery(ctx, req) if isGRPC { - protoRequest := makeGRPCRequest() - err = gogoproto.Unmarshal(req.Data, protoRequest) // TODO: use codec - if err != nil { - return nil, fmt.Errorf("unable to decode gRPC request with path %s from ABCI.Query: %w", req.Path, err) - } - res, err := c.app.Query(ctx, uint64(req.Height), protoRequest) - if err != nil { - resp := queryResult(err) - resp.Height = req.Height - return resp, err - - } - - return queryResponse(res, req.Height) + return resp, err } // this error most probably means that we can't handle it with a proto message, so @@ -233,6 +243,50 @@ func (c *Consensus[T]) Query(ctx context.Context, req *abciproto.QueryRequest) ( return resp, nil } +func (c *Consensus[T]) maybeRunGRPCQuery(ctx context.Context, req *abci.QueryRequest) (resp *abciproto.QueryResponse, isGRPC bool, err error) { + // if this fails then we cannot serve queries anymore + registry, err := c.getProtoRegistry() + if err != nil { + return nil, false, err + } + + path := strings.TrimPrefix(req.Path, "/") + pathFullName := protoreflect.FullName(strings.ReplaceAll(path, "/", ".")) + + // in order to check if it's a gRPC query we ensure that there's a descriptor + // for the path, if such descriptor exists, and it is a method descriptor + // then we assume this is a gRPC query. + desc, err := registry.FindDescriptorByName(pathFullName) + if err != nil { + return nil, false, err + } + + md, isGRPC := desc.(protoreflect.MethodDescriptor) + if !isGRPC { + return nil, false, nil + } + + handler, found := c.queryHandlersMap[string(md.Input().FullName())] + if !found { + return nil, true, fmt.Errorf("no query handler found for %s", req.Path) + } + protoRequest := handler.MakeMsg() + err = gogoproto.Unmarshal(req.Data, protoRequest) // TODO: use codec + if err != nil { + return nil, true, fmt.Errorf("unable to decode gRPC request with path %s from ABCI.Query: %w", req.Path, err) + } + res, err := c.app.Query(ctx, uint64(req.Height), protoRequest) + if err != nil { + resp := QueryResult(err, c.cfg.AppTomlConfig.Trace) + resp.Height = req.Height + return resp, true, err + + } + + resp, err = queryResponse(res, req.Height) + return resp, isGRPC, err +} + // InitChain implements types.Application. func (c *Consensus[T]) InitChain(ctx context.Context, req *abciproto.InitChainRequest) (*abciproto.InitChainResponse, error) { c.logger.Info("InitChain", "initialHeight", req.InitialHeight, "chainID", req.ChainId) @@ -283,10 +337,10 @@ func (c *Consensus[T]) InitChain(ctx context.Context, req *abciproto.InitChainRe return nil, fmt.Errorf("genesis state init failure: %w", err) } - // TODO necessary? where should this WARN live if it all. helpful for testing for _, txRes := range blockresponse.TxResults { - if txRes.Error != nil { - c.logger.Warn("genesis tx failed", "code", txRes.Code, "error", txRes.Error) + if err := txRes.Error; err != nil { + space, code, log := errorsmod.ABCIInfo(err, c.cfg.AppTomlConfig.Trace) + c.logger.Warn("genesis tx failed", "codespace", space, "code", code, "log", log) } } @@ -485,7 +539,7 @@ func (c *Consensus[T]) FinalizeBlock( return nil, err } - return finalizeBlockResponse(resp, cp, appHash, c.indexedEvents) + return finalizeBlockResponse(resp, cp, appHash, c.indexedEvents, c.cfg.AppTomlConfig.Trace) } // Commit implements types.Application. diff --git a/server/v2/cometbft/commands.go b/server/v2/cometbft/commands.go index 787bd2c7810f..d1bb2f257245 100644 --- a/server/v2/cometbft/commands.go +++ b/server/v2/cometbft/commands.go @@ -106,15 +106,13 @@ func ShowValidatorCmd() *cobra.Command { return err } - cmd.Println(sdkPK) // TODO: figure out if we need the codec here or not, see below - - // clientCtx := client.GetClientContextFromCmd(cmd) - // bz, err := clientCtx.Codec.MarshalInterfaceJSON(sdkPK) - // if err != nil { - // return err - // } + clientCtx := client.GetClientContextFromCmd(cmd) + bz, err := clientCtx.Codec.MarshalInterfaceJSON(sdkPK) + if err != nil { + return err + } - // cmd.Println(string(bz)) + cmd.Println(string(bz)) return nil }, } diff --git a/server/v2/cometbft/go.mod b/server/v2/cometbft/go.mod index 7b7176f218d7..e92a3221ada5 100644 --- a/server/v2/cometbft/go.mod +++ b/server/v2/cometbft/go.mod @@ -18,9 +18,11 @@ replace ( require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 - cosmossdk.io/errors v1.0.1 + cosmossdk.io/collections v0.4.0 + cosmossdk.io/core v1.0.0-alpha.4 + cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 cosmossdk.io/log v1.4.1 + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 cosmossdk.io/server/v2 v2.0.0-00010101000000-000000000000 cosmossdk.io/server/v2/appmanager v0.0.0-20240802110823-cffeedff643d cosmossdk.io/server/v2/stf v0.0.0-20240708142107-25e99c54bac1 @@ -34,18 +36,17 @@ require ( github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 + google.golang.org/protobuf v1.34.2 sigs.k8s.io/yaml v1.4.0 ) require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect - cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 // indirect cosmossdk.io/depinject v1.0.0 // indirect - cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect + cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/math v1.3.0 // indirect - cosmossdk.io/schema v0.3.0 // indirect cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect @@ -141,7 +142,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -177,9 +178,8 @@ require ( golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/grpc v1.67.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect + google.golang.org/grpc v1.67.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/server/v2/cometbft/go.sum b/server/v2/cometbft/go.sum index ccfb57a2db3c..ea29392600d8 100644 --- a/server/v2/cometbft/go.sum +++ b/server/v2/cometbft/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -20,8 +20,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -418,8 +418,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -640,8 +640,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -652,8 +652,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/server/v2/cometbft/handlers/handlers.go b/server/v2/cometbft/handlers/handlers.go index 9008490f6a44..015594f469f7 100644 --- a/server/v2/cometbft/handlers/handlers.go +++ b/server/v2/cometbft/handlers/handlers.go @@ -5,6 +5,7 @@ import ( abci "github.com/cometbft/cometbft/api/cometbft/abci/v1" + "cosmossdk.io/core/server" "cosmossdk.io/core/store" "cosmossdk.io/core/transaction" ) @@ -27,4 +28,7 @@ type ( // It takes a context, a store reader map, and a request to extend a vote. // It returns a response to extend the vote and an error if any. ExtendVoteHandler func(context.Context, store.ReaderMap, *abci.ExtendVoteRequest) (*abci.ExtendVoteResponse, error) + + // CheckTxHandler is a function type that handles the execution of a transaction. + CheckTxHandler[T transaction.Tx] func(func(ctx context.Context, tx T) (server.TxResult, error)) (*abci.CheckTxResponse, error) ) diff --git a/server/v2/cometbft/options.go b/server/v2/cometbft/options.go index 0f5091da70a0..d5aa4872fff2 100644 --- a/server/v2/cometbft/options.go +++ b/server/v2/cometbft/options.go @@ -18,6 +18,7 @@ type keyGenF = func() (cmtcrypto.PrivKey, error) type ServerOptions[T transaction.Tx] struct { PrepareProposalHandler handlers.PrepareHandler[T] ProcessProposalHandler handlers.ProcessHandler[T] + CheckTxHandler handlers.CheckTxHandler[T] VerifyVoteExtensionHandler handlers.VerifyVoteExtensionhandler ExtendVoteHandler handlers.ExtendVoteHandler KeygenF keyGenF @@ -35,6 +36,7 @@ func DefaultServerOptions[T transaction.Tx]() ServerOptions[T] { return ServerOptions[T]{ PrepareProposalHandler: handlers.NoOpPrepareProposal[T](), ProcessProposalHandler: handlers.NoOpProcessProposal[T](), + CheckTxHandler: nil, VerifyVoteExtensionHandler: handlers.NoOpVerifyVoteExtensionHandler(), ExtendVoteHandler: handlers.NoOpExtendVote(), Mempool: func(cfg map[string]any) mempool.Mempool[T] { return mempool.NoOpMempool[T]{} }, diff --git a/server/v2/cometbft/query.go b/server/v2/cometbft/query.go index 912338ff79f3..8a624f56fc32 100644 --- a/server/v2/cometbft/query.go +++ b/server/v2/cometbft/query.go @@ -7,7 +7,7 @@ import ( abci "github.com/cometbft/cometbft/api/cometbft/abci/v1" crypto "github.com/cometbft/cometbft/api/cometbft/crypto/v1" - errorsmod "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors/v2" "cosmossdk.io/server/v2/cometbft/types" cometerrors "cosmossdk.io/server/v2/cometbft/types/errors" ) diff --git a/server/v2/cometbft/server.go b/server/v2/cometbft/server.go index 2f402522c099..b15f5695cf94 100644 --- a/server/v2/cometbft/server.go +++ b/server/v2/cometbft/server.go @@ -105,7 +105,7 @@ func (s *CometBFTServer[T]) Init(appI serverv2.AppI[T], cfg map[string]any, logg appI.GetAppManager(), s.serverOptions.Mempool(cfg), indexEvents, - appI.GetGPRCMethodsToMessageMap(), + appI.GetQueryHandlers(), store, s.config, s.initTxCodec, @@ -113,6 +113,7 @@ func (s *CometBFTServer[T]) Init(appI serverv2.AppI[T], cfg map[string]any, logg ) consensus.prepareProposalHandler = s.serverOptions.PrepareProposalHandler consensus.processProposalHandler = s.serverOptions.ProcessProposalHandler + consensus.checkTxHandler = s.serverOptions.CheckTxHandler consensus.verifyVoteExt = s.serverOptions.VerifyVoteExtensionHandler consensus.extendVote = s.serverOptions.ExtendVoteHandler consensus.addrPeerFilter = s.serverOptions.AddrPeerFilter @@ -271,7 +272,7 @@ func (s *CometBFTServer[T]) CLICommands() serverv2.CLIConfig { // Config returns the (app.toml) server configuration. func (s *CometBFTServer[T]) Config() any { - if s.config.AppTomlConfig == nil || s.config.AppTomlConfig == (&AppTomlConfig{}) { + if s.config.AppTomlConfig == nil || s.config.AppTomlConfig.Address == "" { cfg := &Config{AppTomlConfig: DefaultAppTomlConfig()} // overwrite the default config with the provided options for _, opt := range s.cfgOptions { diff --git a/server/v2/cometbft/streaming.go b/server/v2/cometbft/streaming.go index 54abe20aaa96..65f52a002af1 100644 --- a/server/v2/cometbft/streaming.go +++ b/server/v2/cometbft/streaming.go @@ -6,6 +6,8 @@ import ( "cosmossdk.io/core/event" "cosmossdk.io/core/server" "cosmossdk.io/core/store" + errorsmod "cosmossdk.io/errors/v2" + "cosmossdk.io/schema/appdata" "cosmossdk.io/server/v2/streaming" ) @@ -21,12 +23,17 @@ func (c *Consensus[T]) streamDeliverBlockChanges( // convert txresults to streaming txresults streamingTxResults := make([]*streaming.ExecTxResult, len(txResults)) for i, txResult := range txResults { + space, code, log := errorsmod.ABCIInfo(txResult.Error, c.cfg.AppTomlConfig.Trace) + events, err := streaming.IntoStreamingEvents(txResult.Events) if err != nil { return err } + streamingTxResults[i] = &streaming.ExecTxResult{ - Code: txResult.Code, + Code: code, + Codespace: space, + Log: log, GasWanted: uint64ToInt64(txResult.GasWanted), GasUsed: uint64ToInt64(txResult.GasUsed), Events: events, @@ -51,6 +58,55 @@ func (c *Consensus[T]) streamDeliverBlockChanges( c.logger.Error("ListenStateChanges listening hook failed", "height", height, "err", err) } } + + if c.listener == nil { + return nil + } + // stream the StartBlockData to the listener. + if c.listener.StartBlock != nil { + if err := c.listener.StartBlock(appdata.StartBlockData{ + Height: uint64(height), + HeaderBytes: nil, // TODO: https://github.com/cosmos/cosmos-sdk/issues/22009 + HeaderJSON: nil, // TODO: https://github.com/cosmos/cosmos-sdk/issues/22009 + }); err != nil { + return err + } + } + // stream the TxData to the listener. + if c.listener.OnTx != nil { + for i, tx := range txs { + if err := c.listener.OnTx(appdata.TxData{ + TxIndex: int32(i), + Bytes: func() ([]byte, error) { return tx, nil }, + JSON: nil, // TODO: https://github.com/cosmos/cosmos-sdk/issues/22009 + }); err != nil { + return err + } + } + } + // stream the EventData to the listener. + if c.listener.OnEvent != nil { + if err := c.listener.OnEvent(appdata.EventData{Events: events}); err != nil { + return err + } + } + // stream the KVPairData to the listener. + if c.listener.OnKVPair != nil { + if err := c.listener.OnKVPair(appdata.KVPairData{Updates: stateChanges}); err != nil { + return err + } + } + // stream the CommitData to the listener. + if c.listener.Commit != nil { + if completionCallback, err := c.listener.Commit(appdata.CommitData{}); err != nil { + return err + } else if completionCallback != nil { + if err := completionCallback(); err != nil { + return err + } + } + } + return nil } diff --git a/server/v2/cometbft/types/errors/errors.go b/server/v2/cometbft/types/errors/errors.go index 380c176ff306..e60f32338358 100644 --- a/server/v2/cometbft/types/errors/errors.go +++ b/server/v2/cometbft/types/errors/errors.go @@ -1,7 +1,7 @@ package errors import ( - errorsmod "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors/v2" ) // RootCodespace is the codespace for all errors defined in this package diff --git a/server/v2/cometbft/utils.go b/server/v2/cometbft/utils.go index d48147e0a243..2b1052bd1953 100644 --- a/server/v2/cometbft/utils.go +++ b/server/v2/cometbft/utils.go @@ -18,7 +18,7 @@ import ( "cosmossdk.io/core/event" "cosmossdk.io/core/server" "cosmossdk.io/core/transaction" - errorsmod "cosmossdk.io/errors" + errorsmod "cosmossdk.io/errors/v2" consensus "cosmossdk.io/x/consensus/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -70,6 +70,7 @@ func finalizeBlockResponse( cp *cmtproto.ConsensusParams, appHash []byte, indexSet map[string]struct{}, + debug bool, ) (*abci.FinalizeBlockResponse, error) { allEvents := append(in.BeginBlockEvents, in.EndBlockEvents...) @@ -78,7 +79,7 @@ func finalizeBlockResponse( return nil, err } - txResults, err := intoABCITxResults(in.TxResults, indexSet) + txResults, err := intoABCITxResults(in.TxResults, indexSet, debug) if err != nil { return nil, err } @@ -107,29 +108,20 @@ func intoABCIValidatorUpdates(updates []appmodulev2.ValidatorUpdate) []abci.Vali return valsetUpdates } -func intoABCITxResults(results []server.TxResult, indexSet map[string]struct{}) ([]*abci.ExecTxResult, error) { +func intoABCITxResults(results []server.TxResult, indexSet map[string]struct{}, debug bool) ([]*abci.ExecTxResult, error) { res := make([]*abci.ExecTxResult, len(results)) for i := range results { - if results[i].Error != nil { - space, code, log := errorsmod.ABCIInfo(results[i].Error, true) - res[i] = &abci.ExecTxResult{ - Codespace: space, - Code: code, - Log: log, - } - - continue - } events, err := intoABCIEvents(results[i].Events, indexSet) if err != nil { return nil, err } + res[i] = responseExecTxResultWithEvents( results[i].Error, results[i].GasWanted, results[i].GasUsed, events, - false, + debug, ) } @@ -387,10 +379,10 @@ func (c *Consensus[T]) GetBlockRetentionHeight(cp *cmtproto.ConsensusParams, com func (c *Consensus[T]) checkHalt(height int64, time time.Time) error { var halt bool switch { - case c.cfg.AppTomlConfig.HaltHeight > 0 && uint64(height) > c.cfg.AppTomlConfig.HaltHeight: + case c.cfg.AppTomlConfig.HaltHeight > 0 && uint64(height) >= c.cfg.AppTomlConfig.HaltHeight: halt = true - case c.cfg.AppTomlConfig.HaltTime > 0 && time.Unix() > int64(c.cfg.AppTomlConfig.HaltTime): + case c.cfg.AppTomlConfig.HaltTime > 0 && time.Unix() >= int64(c.cfg.AppTomlConfig.HaltTime): halt = true } @@ -408,14 +400,3 @@ func uint64ToInt64(u uint64) int64 { } return int64(u) } - -// queryResult returns a ResponseQuery from an error. It will try to parse ABCI -// info from the error. -func queryResult(err error) *abci.QueryResponse { - space, code, log := errorsmod.ABCIInfo(err, false) - return &abci.QueryResponse{ - Codespace: space, - Code: code, - Log: log, - } -} diff --git a/server/v2/go.mod b/server/v2/go.mod index 7ccfca6f628c..220989a6186e 100644 --- a/server/v2/go.mod +++ b/server/v2/go.mod @@ -13,7 +13,7 @@ replace ( require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/log v1.4.1 cosmossdk.io/server/v2/appmanager v0.0.0-00010101000000-000000000000 @@ -22,7 +22,6 @@ require ( github.com/cosmos/gogogateway v1.2.0 github.com/cosmos/gogoproto v1.7.0 github.com/golang/protobuf v1.5.4 - github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/go-metrics v0.5.3 @@ -30,14 +29,14 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/pelletier/go-toml/v2 v2.2.2 github.com/prometheus/client_golang v1.20.4 - github.com/prometheus/common v0.59.1 + github.com/prometheus/common v0.60.0 github.com/rs/zerolog v1.33.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 golang.org/x/sync v0.8.0 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -107,7 +106,7 @@ require ( golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/server/v2/go.sum b/server/v2/go.sum index 748913b517f3..842232d93dbb 100644 --- a/server/v2/go.sum +++ b/server/v2/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 h1:IQNdY2kB+k+1OM2DvqFG1+UgeU1JzZrWtwuWzI3ZfwA= @@ -150,8 +150,6 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -270,8 +268,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -452,8 +450,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -462,8 +460,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/server/v2/server_test.go b/server/v2/server_test.go index e84bcd598890..97afa40fdaa9 100644 --- a/server/v2/server_test.go +++ b/server/v2/server_test.go @@ -11,6 +11,7 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/require" + appmodulev2 "cosmossdk.io/core/appmodule/v2" coreserver "cosmossdk.io/core/server" "cosmossdk.io/core/transaction" "cosmossdk.io/log" @@ -35,8 +36,8 @@ type mockApp[T transaction.Tx] struct { serverv2.AppI[T] } -func (*mockApp[T]) GetGPRCMethodsToMessageMap() map[string]func() gogoproto.Message { - return map[string]func() gogoproto.Message{} +func (*mockApp[T]) GetQueryHandlers() map[string]appmodulev2.Handler { + return map[string]appmodulev2.Handler{} } func (*mockApp[T]) GetAppManager() *appmanager.AppManager[T] { diff --git a/server/v2/stf/go.mod b/server/v2/stf/go.mod index b6de9d6002d8..06f5ca471a13 100644 --- a/server/v2/stf/go.mod +++ b/server/v2/stf/go.mod @@ -3,7 +3,7 @@ module cosmossdk.io/server/v2/stf go 1.23 require ( - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/schema v0.3.0 github.com/cosmos/gogoproto v1.7.0 github.com/tidwall/btree v1.7.0 diff --git a/server/v2/stf/go.sum b/server/v2/stf/go.sum index 3517a521d31c..95ab31efba84 100644 --- a/server/v2/stf/go.sum +++ b/server/v2/stf/go.sum @@ -1,5 +1,5 @@ -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= diff --git a/server/v2/stf/stf.go b/server/v2/stf/stf.go index 497b3d389085..f665aaf3c6e9 100644 --- a/server/v2/stf/stf.go +++ b/server/v2/stf/stf.go @@ -57,11 +57,11 @@ func NewSTF[T transaction.Tx]( postTxExec func(ctx context.Context, tx T, success bool) error, branch func(store store.ReaderMap) store.WriterMap, ) (*STF[T], error) { - msgRouter, err := msgRouterBuilder.Build() + msgRouter, err := msgRouterBuilder.build() if err != nil { return nil, fmt.Errorf("build msg router: %w", err) } - queryRouter, err := queryRouterBuilder.Build() + queryRouter, err := queryRouterBuilder.build() if err != nil { return nil, fmt.Errorf("build query router: %w", err) } @@ -123,7 +123,6 @@ func (s STF[T]) DeliverBlock( // reset events exCtx.events = make([]event.Event, 0) - // begin block var beginBlockEvents []event.Event if !block.IsGenesis { @@ -147,7 +146,7 @@ func (s STF[T]) DeliverBlock( if err = isCtxCancelled(ctx); err != nil { return nil, nil, err } - txResults[i] = s.deliverTx(exCtx, newState, txBytes, transaction.ExecModeFinalize, hi) + txResults[i] = s.deliverTx(exCtx, newState, txBytes, transaction.ExecModeFinalize, hi, int32(i+1)) } // reset events exCtx.events = make([]event.Event, 0) @@ -173,6 +172,7 @@ func (s STF[T]) deliverTx( tx T, execMode transaction.ExecMode, hi header.Info, + txIndex int32, ) server.TxResult { // recover in the case of a panic var recoveryError error @@ -195,17 +195,32 @@ func (s STF[T]) deliverTx( Error: recoveryError, } } - validateGas, validationEvents, err := s.validateTx(ctx, state, gasLimit, tx, execMode) if err != nil { return server.TxResult{ Error: err, } } + events := make([]event.Event, 0) + // set the event indexes, set MsgIndex to 0 in validation events + for i, e := range validationEvents { + e.BlockStage = appdata.TxProcessingStage + e.TxIndex = txIndex + e.MsgIndex = 0 + e.EventIndex = int32(i + 1) + events = append(events, e) + } execResp, execGas, execEvents, err := s.execTx(ctx, state, gasLimit-validateGas, tx, execMode, hi) + // set the TxIndex in the exec events + for _, e := range execEvents { + e.BlockStage = appdata.TxProcessingStage + e.TxIndex = txIndex + events = append(events, e) + } + return server.TxResult{ - Events: append(validationEvents, execEvents...), + Events: events, GasUsed: execGas + validateGas, GasWanted: gasLimit, Resp: execResp, @@ -271,6 +286,12 @@ func (s STF[T]) execTx( if applyErr != nil { return nil, 0, nil, applyErr } + // set the event indexes, set MsgIndex to -1 in post tx events + for i := range postTxCtx.events { + postTxCtx.events[i].EventIndex = int32(i + 1) + postTxCtx.events[i].MsgIndex = -1 + } + return nil, gasUsed, postTxCtx.events, txErr } // tx execution went fine, now we use the same state to run the post tx exec handler, @@ -290,6 +311,11 @@ func (s STF[T]) execTx( if applyErr != nil { return nil, 0, nil, applyErr } + // set the event indexes, set MsgIndex to -1 in post tx events + for i := range postTxCtx.events { + postTxCtx.events[i].EventIndex = int32(i + 1) + postTxCtx.events[i].MsgIndex = -1 + } return msgsResp, gasUsed, append(runTxMsgsEvents, postTxCtx.events...), nil } @@ -316,17 +342,24 @@ func (s STF[T]) runTxMsgs( execCtx := s.makeContext(ctx, RuntimeIdentity, state, execMode) execCtx.setHeaderInfo(hi) execCtx.setGasLimit(gasLimit) + events := make([]event.Event, 0) for i, msg := range msgs { execCtx.sender = txSenders[i] + execCtx.events = make([]event.Event, 0) // reset events resp, err := s.msgRouter.Invoke(execCtx, msg) if err != nil { - return nil, 0, nil, fmt.Errorf("message execution at index %d failed: %w", i, err) + return nil, 0, nil, err // do not wrap the error or we lose the original error type } msgResps[i] = resp + for j, e := range execCtx.events { + e.MsgIndex = int32(i + 1) + e.EventIndex = int32(j + 1) + events = append(events, e) + } } consumed := execCtx.meter.Limit() - execCtx.meter.Remaining() - return msgResps, consumed, execCtx.events, nil + return msgResps, consumed, events, nil } // preBlock executes the pre block logic. @@ -341,6 +374,7 @@ func (s STF[T]) preBlock( for i := range ctx.events { ctx.events[i].BlockStage = appdata.PreBlockStage + ctx.events[i].EventIndex = int32(i + 1) } return ctx.events, nil @@ -357,6 +391,7 @@ func (s STF[T]) beginBlock( for i := range ctx.events { ctx.events[i].BlockStage = appdata.BeginBlockStage + ctx.events[i].EventIndex = int32(i + 1) } return ctx.events, nil @@ -370,30 +405,30 @@ func (s STF[T]) endBlock( if err != nil { return nil, nil, err } - - events, valsetUpdates, err := s.validatorUpdates(ctx) + events := ctx.events + ctx.events = make([]event.Event, 0) // reset events + valsetUpdates, err := s.validatorUpdates(ctx) if err != nil { return nil, nil, err } - - ctx.events = append(ctx.events, events...) - - for i := range ctx.events { - ctx.events[i].BlockStage = appdata.EndBlockStage + events = append(events, ctx.events...) + for i := range events { + events[i].BlockStage = appdata.EndBlockStage + events[i].EventIndex = int32(i + 1) } - return ctx.events, valsetUpdates, nil + return events, valsetUpdates, nil } // validatorUpdates returns the validator updates for the current block. It is called by endBlock after the endblock execution has concluded func (s STF[T]) validatorUpdates( ctx *executionContext, -) ([]event.Event, []appmodulev2.ValidatorUpdate, error) { +) ([]appmodulev2.ValidatorUpdate, error) { valSetUpdates, err := s.doValidatorUpdate(ctx) if err != nil { - return nil, nil, err + return nil, err } - return ctx.events, valSetUpdates, nil + return valSetUpdates, nil } // Simulate simulates the execution of a tx on the provided state. @@ -408,7 +443,7 @@ func (s STF[T]) Simulate( if err != nil { return server.TxResult{}, nil } - txr := s.deliverTx(ctx, simulationState, tx, internal.ExecModeSimulate, hi) + txr := s.deliverTx(ctx, simulationState, tx, internal.ExecModeSimulate, hi, 0) return txr, simulationState } diff --git a/server/v2/stf/stf_router.go b/server/v2/stf/stf_router.go index 0417788e4b78..86a27efc49e8 100644 --- a/server/v2/stf/stf_router.go +++ b/server/v2/stf/stf_router.go @@ -18,21 +18,21 @@ var ErrNoHandler = errors.New("no handler") // NewMsgRouterBuilder is a router that routes messages to their respective handlers. func NewMsgRouterBuilder() *MsgRouterBuilder { return &MsgRouterBuilder{ - handlers: make(map[string]appmodulev2.Handler), + handlers: make(map[string]appmodulev2.HandlerFunc), preHandlers: make(map[string][]appmodulev2.PreMsgHandler), postHandlers: make(map[string][]appmodulev2.PostMsgHandler), } } type MsgRouterBuilder struct { - handlers map[string]appmodulev2.Handler + handlers map[string]appmodulev2.HandlerFunc globalPreHandlers []appmodulev2.PreMsgHandler preHandlers map[string][]appmodulev2.PreMsgHandler postHandlers map[string][]appmodulev2.PostMsgHandler globalPostHandlers []appmodulev2.PostMsgHandler } -func (b *MsgRouterBuilder) RegisterHandler(msgType string, handler appmodulev2.Handler) error { +func (b *MsgRouterBuilder) RegisterHandler(msgType string, handler appmodulev2.HandlerFunc) error { // panic on override if _, ok := b.handlers[msgType]; ok { return fmt.Errorf("handler already registered: %s", msgType) @@ -62,8 +62,8 @@ func (b *MsgRouterBuilder) HandlerExists(msgType string) bool { return ok } -func (b *MsgRouterBuilder) Build() (coreRouterImpl, error) { - handlers := make(map[string]appmodulev2.Handler) +func (b *MsgRouterBuilder) build() (coreRouterImpl, error) { + handlers := make(map[string]appmodulev2.HandlerFunc) globalPreHandler := func(ctx context.Context, msg transaction.Msg) error { for _, h := range b.globalPreHandlers { @@ -100,12 +100,12 @@ func (b *MsgRouterBuilder) Build() (coreRouterImpl, error) { } func buildHandler( - handler appmodulev2.Handler, + handler appmodulev2.HandlerFunc, preHandlers []appmodulev2.PreMsgHandler, globalPreHandler appmodulev2.PreMsgHandler, postHandlers []appmodulev2.PostMsgHandler, globalPostHandler appmodulev2.PostMsgHandler, -) appmodulev2.Handler { +) appmodulev2.HandlerFunc { return func(ctx context.Context, msg transaction.Msg) (msgResp transaction.Msg, err error) { if len(preHandlers) != 0 { for _, preHandler := range preHandlers { @@ -144,7 +144,7 @@ var _ router.Service = (*coreRouterImpl)(nil) // coreRouterImpl implements the STF router for msg and query handlers. type coreRouterImpl struct { - handlers map[string]appmodulev2.Handler + handlers map[string]appmodulev2.HandlerFunc } func (r coreRouterImpl) CanInvoke(_ context.Context, typeURL string) error { diff --git a/server/v2/stf/stf_router_test.go b/server/v2/stf/stf_router_test.go index 0a63ae4b79d4..8e17b22fc805 100644 --- a/server/v2/stf/stf_router_test.go +++ b/server/v2/stf/stf_router_test.go @@ -18,7 +18,7 @@ func TestRouter(t *testing.T) { expectedResp := &gogotypes.StringValue{Value: "test"} - router := coreRouterImpl{handlers: map[string]appmodulev2.Handler{ + router := coreRouterImpl{handlers: map[string]appmodulev2.HandlerFunc{ gogoproto.MessageName(expectedMsg): func(ctx context.Context, gotMsg transaction.Msg) (msgResp transaction.Msg, err error) { if !reflect.DeepEqual(expectedMsg, gotMsg) { t.Errorf("expected message: %v, got: %v", expectedMsg, gotMsg) diff --git a/server/v2/stf/stf_test.go b/server/v2/stf/stf_test.go index 5fa4fce15b40..b4c84a62ff9a 100644 --- a/server/v2/stf/stf_test.go +++ b/server/v2/stf/stf_test.go @@ -11,15 +11,19 @@ import ( gogotypes "github.com/cosmos/gogoproto/types" appmodulev2 "cosmossdk.io/core/appmodule/v2" + "cosmossdk.io/core/event" coregas "cosmossdk.io/core/gas" "cosmossdk.io/core/server" "cosmossdk.io/core/store" "cosmossdk.io/core/transaction" + "cosmossdk.io/schema/appdata" "cosmossdk.io/server/v2/stf/branch" "cosmossdk.io/server/v2/stf/gas" "cosmossdk.io/server/v2/stf/mock" ) +const senderAddr = "sender" + func addMsgHandlerToSTF[T any, PT interface { *T transaction.Msg @@ -50,7 +54,7 @@ func addMsgHandlerToSTF[T any, PT interface { t.Errorf("Failed to register handler: %v", err) } - msgRouter, err := msgRouterBuilder.Build() + msgRouter, err := msgRouterBuilder.build() if err != nil { t.Errorf("Failed to build message router: %v", err) } @@ -60,7 +64,7 @@ func addMsgHandlerToSTF[T any, PT interface { func TestSTF(t *testing.T) { state := mock.DB() mockTx := mock.Tx{ - Sender: []byte("sender"), + Sender: []byte(senderAddr), Msg: &gogotypes.BoolValue{Value: true}, GasLimit: 100_000, } @@ -68,22 +72,48 @@ func TestSTF(t *testing.T) { sum := sha256.Sum256([]byte("test-hash")) s := &STF[mock.Tx]{ - doPreBlock: func(ctx context.Context, txs []mock.Tx) error { return nil }, + doPreBlock: func(ctx context.Context, txs []mock.Tx) error { + ctx.(*executionContext).events = append(ctx.(*executionContext).events, event.NewEvent("pre-block")) + return nil + }, doBeginBlock: func(ctx context.Context) error { kvSet(t, ctx, "begin-block") + ctx.(*executionContext).events = append(ctx.(*executionContext).events, event.NewEvent("begin-block")) return nil }, doEndBlock: func(ctx context.Context) error { kvSet(t, ctx, "end-block") + ctx.(*executionContext).events = append(ctx.(*executionContext).events, event.NewEvent("end-block")) return nil }, - doValidatorUpdate: func(ctx context.Context) ([]appmodulev2.ValidatorUpdate, error) { return nil, nil }, + doValidatorUpdate: func(ctx context.Context) ([]appmodulev2.ValidatorUpdate, error) { + ctx.(*executionContext).events = append(ctx.(*executionContext).events, event.NewEvent("validator-update")) + return nil, nil + }, doTxValidation: func(ctx context.Context, tx mock.Tx) error { kvSet(t, ctx, "validate") + ctx.(*executionContext).events = append( + ctx.(*executionContext).events, + event.NewEvent("validate-tx", event.NewAttribute(senderAddr, string(tx.Sender))), + event.NewEvent( + "validate-tx", + event.NewAttribute(senderAddr, string(tx.Sender)), + event.NewAttribute("index", "2"), + ), + ) return nil }, postTxExec: func(ctx context.Context, tx mock.Tx, success bool) error { kvSet(t, ctx, "post-tx-exec") + ctx.(*executionContext).events = append( + ctx.(*executionContext).events, + event.NewEvent("post-tx-exec", event.NewAttribute(senderAddr, string(tx.Sender))), + event.NewEvent( + "post-tx-exec", + event.NewAttribute(senderAddr, string(tx.Sender)), + event.NewAttribute("index", "2"), + ), + ) return nil }, branchFn: branch.DefaultNewWriterMap, @@ -93,6 +123,15 @@ func TestSTF(t *testing.T) { addMsgHandlerToSTF(t, s, func(ctx context.Context, msg *gogotypes.BoolValue) (*gogotypes.BoolValue, error) { kvSet(t, ctx, "exec") + ctx.(*executionContext).events = append( + ctx.(*executionContext).events, + event.NewEvent("handle-msg", event.NewAttribute("msg", msg.String())), + event.NewEvent( + "handle-msg", + event.NewAttribute("msg", msg.String()), + event.NewAttribute("index", "2"), + ), + ) return nil, nil }) @@ -135,13 +174,124 @@ func TestSTF(t *testing.T) { if txResult.GasWanted != mockTx.GasLimit { t.Errorf("Expected GasWanted to be %d, got %d", mockTx.GasLimit, txResult.GasWanted) } + + // Check PreBlockEvents + preBlockEvents := result.PreBlockEvents + if len(preBlockEvents) != 1 { + t.Fatalf("Expected 1 PreBlockEvent, got %d", len(preBlockEvents)) + } + if preBlockEvents[0].Type != "pre-block" { + t.Errorf("Expected PreBlockEvent Type 'pre-block', got %s", preBlockEvents[0].Type) + } + if preBlockEvents[0].BlockStage != appdata.PreBlockStage { + t.Errorf("Expected PreBlockStage %d, got %d", appdata.PreBlockStage, preBlockEvents[0].BlockStage) + } + if preBlockEvents[0].EventIndex != 1 { + t.Errorf("Expected PreBlockEventIndex 1, got %d", preBlockEvents[0].EventIndex) + } + // Check BeginBlockEvents + beginBlockEvents := result.BeginBlockEvents + if len(beginBlockEvents) != 1 { + t.Fatalf("Expected 1 BeginBlockEvent, got %d", len(beginBlockEvents)) + } + if beginBlockEvents[0].Type != "begin-block" { + t.Errorf("Expected BeginBlockEvent Type 'begin-block', got %s", beginBlockEvents[0].Type) + } + if beginBlockEvents[0].BlockStage != appdata.BeginBlockStage { + t.Errorf("Expected BeginBlockStage %d, got %d", appdata.BeginBlockStage, beginBlockEvents[0].BlockStage) + } + if beginBlockEvents[0].EventIndex != 1 { + t.Errorf("Expected BeginBlockEventIndex 1, got %d", beginBlockEvents[0].EventIndex) + } + // Check EndBlockEvents + endBlockEvents := result.EndBlockEvents + if len(endBlockEvents) != 2 { + t.Fatalf("Expected 2 EndBlockEvents, got %d", len(endBlockEvents)) + } + if endBlockEvents[0].Type != "end-block" { + t.Errorf("Expected EndBlockEvent Type 'end-block', got %s", endBlockEvents[0].Type) + } + if endBlockEvents[1].Type != "validator-update" { + t.Errorf("Expected EndBlockEvent Type 'validator-update', got %s", endBlockEvents[1].Type) + } + if endBlockEvents[1].BlockStage != appdata.EndBlockStage { + t.Errorf("Expected EndBlockStage %d, got %d", appdata.EndBlockStage, endBlockEvents[1].BlockStage) + } + if endBlockEvents[0].EventIndex != 1 { + t.Errorf("Expected EndBlockEventIndex 1, got %d", endBlockEvents[0].EventIndex) + } + if endBlockEvents[1].EventIndex != 2 { + t.Errorf("Expected EndBlockEventIndex 2, got %d", endBlockEvents[1].EventIndex) + } + // check TxEvents + events := txResult.Events + if len(events) != 6 { + t.Fatalf("Expected 6 TxEvents, got %d", len(events)) + } + for i, event := range events { + if event.BlockStage != appdata.TxProcessingStage { + t.Errorf("Expected BlockStage %d, got %d", appdata.TxProcessingStage, event.BlockStage) + } + if event.TxIndex != 1 { + t.Errorf("Expected TxIndex 1, got %d", event.TxIndex) + } + if event.EventIndex != int32(i%2+1) { + t.Errorf("Expected EventIndex %d, got %d", i%2+1, event.EventIndex) + } + + attrs, err := event.Attributes() + if err != nil { + t.Fatalf("Error getting event attributes: %v", err) + } + if len(attrs) < 1 || len(attrs) > 2 { + t.Errorf("Expected 1 or 2 attributes, got %d", len(attrs)) + } + + if len(attrs) == 2 { + if attrs[1].Key != "index" || attrs[1].Value != "2" { + t.Errorf("Expected attribute key 'index' and value '2', got key '%s' and value '%s'", attrs[1].Key, attrs[1].Value) + } + } + switch i { + case 0, 1: + if event.Type != "validate-tx" { + t.Errorf("Expected event type 'validate-tx', got %s", event.Type) + } + if event.MsgIndex != 0 { + t.Errorf("Expected MsgIndex 0, got %d", event.MsgIndex) + } + if attrs[0].Key != senderAddr || attrs[0].Value != senderAddr { + t.Errorf("Expected sender attribute key 'sender' and value 'sender', got key '%s' and value '%s'", attrs[0].Key, attrs[0].Value) + } + case 2, 3: + if event.Type != "handle-msg" { + t.Errorf("Expected event type 'handle-msg', got %s", event.Type) + } + if event.MsgIndex != 1 { + t.Errorf("Expected MsgIndex 1, got %d", event.MsgIndex) + } + if attrs[0].Key != "msg" || attrs[0].Value != "&BoolValue{Value:true,XXX_unrecognized:[],}" { + t.Errorf("Expected msg attribute with value '&BoolValue{Value:true,XXX_unrecognized:[],}', got '%s'", attrs[0].Value) + } + case 4, 5: + if event.Type != "post-tx-exec" { + t.Errorf("Expected event type 'post-tx-exec', got %s", event.Type) + } + if event.MsgIndex != -1 { + t.Errorf("Expected MsgIndex -1, got %d", event.MsgIndex) + } + if attrs[0].Key != senderAddr || attrs[0].Value != senderAddr { + t.Errorf("Expected sender attribute key 'sender' and value 'sender', got key '%s' and value '%s'", attrs[0].Key, attrs[0].Value) + } + } + } }) t.Run("exec tx out of gas", func(t *testing.T) { s := s.clone() mockTx := mock.Tx{ - Sender: []byte("sender"), + Sender: []byte(senderAddr), Msg: &gogotypes.BoolValue{Value: true}, // msg does not matter at all because our handler does nothing. GasLimit: 0, // NO GAS! } diff --git a/server/v2/store/commands.go b/server/v2/store/commands.go index 7c50995f923e..3b9f175c7b0f 100644 --- a/server/v2/store/commands.go +++ b/server/v2/store/commands.go @@ -16,8 +16,8 @@ import ( "cosmossdk.io/store/v2/root" ) -// QueryBlockResultsCmd implements the default command for a BlockResults query. -func (s *StoreComponent[T]) PrunesCmd() *cobra.Command { +// PrunesCmd implements the default command for pruning app history states. +func (s *Server[T]) PrunesCmd() *cobra.Command { cmd := &cobra.Command{ Use: "prune [pruning-method]", Short: "Prune app history states by keeping the recent heights and deleting old heights", diff --git a/server/v2/store/server.go b/server/v2/store/server.go index a5f464c964a5..c50a53dc6e24 100644 --- a/server/v2/store/server.go +++ b/server/v2/store/server.go @@ -12,49 +12,49 @@ import ( ) var ( - _ serverv2.ServerComponent[transaction.Tx] = (*StoreComponent[transaction.Tx])(nil) - _ serverv2.HasConfig = (*StoreComponent[transaction.Tx])(nil) - _ serverv2.HasCLICommands = (*StoreComponent[transaction.Tx])(nil) + _ serverv2.ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil) + _ serverv2.HasConfig = (*Server[transaction.Tx])(nil) + _ serverv2.HasCLICommands = (*Server[transaction.Tx])(nil) ) const ServerName = "store" -// StoreComponent manages store config -// and contains prune & snapshot commands -type StoreComponent[T transaction.Tx] struct { +// Server manages store config and contains prune & snapshot commands +type Server[T transaction.Tx] struct { config *Config // saving appCreator for only RestoreSnapshotCmd appCreator serverv2.AppCreator[T] } -func New[T transaction.Tx](appCreator serverv2.AppCreator[T]) *StoreComponent[T] { - return &StoreComponent[T]{appCreator: appCreator} +func New[T transaction.Tx](appCreator serverv2.AppCreator[T]) *Server[T] { + return &Server[T]{appCreator: appCreator} } -func (s *StoreComponent[T]) Init(appI serverv2.AppI[T], cfg map[string]any, logger log.Logger) error { - serverCfg := DefaultConfig() +func (s *Server[T]) Init(appI serverv2.AppI[T], cfg map[string]any, logger log.Logger) error { + serverCfg := s.Config().(*Config) if len(cfg) > 0 { if err := serverv2.UnmarshalSubConfig(cfg, s.Name(), &serverCfg); err != nil { return fmt.Errorf("failed to unmarshal config: %w", err) } } + s.config = serverCfg return nil } -func (s *StoreComponent[T]) Name() string { +func (s *Server[T]) Name() string { return ServerName } -func (s *StoreComponent[T]) Start(ctx context.Context) error { +func (s *Server[T]) Start(ctx context.Context) error { return nil } -func (s *StoreComponent[T]) Stop(ctx context.Context) error { +func (s *Server[T]) Stop(ctx context.Context) error { return nil } -func (s *StoreComponent[T]) CLICommands() serverv2.CLIConfig { +func (s *Server[T]) CLICommands() serverv2.CLIConfig { return serverv2.CLIConfig{ Commands: []*cobra.Command{ s.PrunesCmd(), @@ -68,10 +68,10 @@ func (s *StoreComponent[T]) CLICommands() serverv2.CLIConfig { } } -func (g *StoreComponent[T]) Config() any { - if g.config == nil || g.config == (&Config{}) { +func (s *Server[T]) Config() any { + if s.config == nil || s.config.AppDBBackend == "" { return DefaultConfig() } - return g.config + return s.config } diff --git a/server/v2/store/snapshot.go b/server/v2/store/snapshot.go index 2c106f85fe69..b804e34b71c8 100644 --- a/server/v2/store/snapshot.go +++ b/server/v2/store/snapshot.go @@ -24,8 +24,8 @@ import ( const SnapshotFileName = "_snapshot" -// QueryBlockResultsCmd implements the default command for a BlockResults query. -func (s *StoreComponent[T]) ExportSnapshotCmd() *cobra.Command { +// ExportSnapshotCmd exports app state to snapshot store. +func (s *Server[T]) ExportSnapshotCmd() *cobra.Command { cmd := &cobra.Command{ Use: "export", Short: "Export app state to snapshot store", @@ -76,7 +76,7 @@ func (s *StoreComponent[T]) ExportSnapshotCmd() *cobra.Command { } // RestoreSnapshotCmd returns a command to restore a snapshot -func (s *StoreComponent[T]) RestoreSnapshotCmd(newApp serverv2.AppCreator[T]) *cobra.Command { +func (s *Server[T]) RestoreSnapshotCmd(newApp serverv2.AppCreator[T]) *cobra.Command { cmd := &cobra.Command{ Use: "restore ", Short: "Restore app state from local snapshot", @@ -113,7 +113,7 @@ func (s *StoreComponent[T]) RestoreSnapshotCmd(newApp serverv2.AppCreator[T]) *c } // ListSnapshotsCmd returns the command to list local snapshots -func (s *StoreComponent[T]) ListSnapshotsCmd() *cobra.Command { +func (s *Server[T]) ListSnapshotsCmd() *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "List local snapshots", @@ -139,7 +139,7 @@ func (s *StoreComponent[T]) ListSnapshotsCmd() *cobra.Command { } // DeleteSnapshotCmd returns the command to delete a local snapshot -func (s *StoreComponent[T]) DeleteSnapshotCmd() *cobra.Command { +func (s *Server[T]) DeleteSnapshotCmd() *cobra.Command { return &cobra.Command{ Use: "delete ", Short: "Delete a local snapshot", @@ -167,7 +167,7 @@ func (s *StoreComponent[T]) DeleteSnapshotCmd() *cobra.Command { } // DumpArchiveCmd returns a command to dump the snapshot as portable archive format -func (s *StoreComponent[T]) DumpArchiveCmd() *cobra.Command { +func (s *Server[T]) DumpArchiveCmd() *cobra.Command { cmd := &cobra.Command{ Use: "dump ", Short: "Dump the snapshot as portable archive format", @@ -260,7 +260,7 @@ func (s *StoreComponent[T]) DumpArchiveCmd() *cobra.Command { } // LoadArchiveCmd load a portable archive format snapshot into snapshot store -func (s *StoreComponent[T]) LoadArchiveCmd() *cobra.Command { +func (s *Server[T]) LoadArchiveCmd() *cobra.Command { return &cobra.Command{ Use: "load ", Short: "Load a snapshot archive file (.tar.gz) into snapshot store", diff --git a/server/v2/types.go b/server/v2/types.go index afa82969131a..7cd15fd10307 100644 --- a/server/v2/types.go +++ b/server/v2/types.go @@ -1,9 +1,9 @@ package serverv2 import ( - gogoproto "github.com/cosmos/gogoproto/proto" "github.com/spf13/viper" + appmodulev2 "cosmossdk.io/core/appmodule/v2" "cosmossdk.io/core/server" "cosmossdk.io/core/transaction" "cosmossdk.io/log" @@ -16,6 +16,6 @@ type AppI[T transaction.Tx] interface { Name() string InterfaceRegistry() server.InterfaceRegistry GetAppManager() *appmanager.AppManager[T] - GetGPRCMethodsToMessageMap() map[string]func() gogoproto.Message + GetQueryHandlers() map[string]appmodulev2.Handler GetStore() any } diff --git a/simapp/app.go b/simapp/app.go index b02c5e14599f..96ae2f04dbae 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -28,6 +28,7 @@ import ( "cosmossdk.io/x/accounts/accountstd" baseaccount "cosmossdk.io/x/accounts/defaults/base" lockup "cosmossdk.io/x/accounts/defaults/lockup" + "cosmossdk.io/x/accounts/defaults/multisig" "cosmossdk.io/x/accounts/testing/account_abstraction" "cosmossdk.io/x/accounts/testing/counter" "cosmossdk.io/x/authz" @@ -315,6 +316,7 @@ func NewSimApp( accountstd.AddAccount(lockup.PERIODIC_LOCKING_ACCOUNT, lockup.NewPeriodicLockingAccount), accountstd.AddAccount(lockup.DELAYED_LOCKING_ACCOUNT, lockup.NewDelayedLockingAccount), accountstd.AddAccount(lockup.PERMANENT_LOCKING_ACCOUNT, lockup.NewPermanentLockingAccount), + accountstd.AddAccount("multisig", multisig.NewAccount), // PRODUCTION: add baseaccount.NewAccount("base", txConfig.SignModeHandler(), baseaccount.WithSecp256K1PubKey()), ) @@ -396,7 +398,7 @@ func NewSimApp( app.CircuitKeeper = circuitkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[circuittypes.StoreKey]), logger.With(log.ModuleKey, "x/circuit")), appCodec, govModuleAddr, app.AuthKeeper.AddressCodec()) app.BaseApp.SetCircuitBreaker(&app.CircuitKeeper) - app.AuthzKeeper = authzkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), logger.With(log.ModuleKey, "x/authz"), runtime.EnvWithMsgRouterService(app.MsgServiceRouter()), runtime.EnvWithQueryRouterService(app.GRPCQueryRouter())), appCodec, app.AuthKeeper) + app.AuthzKeeper = authzkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), logger.With(log.ModuleKey, "x/authz"), runtime.EnvWithMsgRouterService(app.MsgServiceRouter()), runtime.EnvWithQueryRouterService(app.GRPCQueryRouter())), appCodec, signingCtx.AddressCodec()) groupConfig := group.DefaultConfig() /* diff --git a/simapp/app_di.go b/simapp/app_di.go index 32046a59b7e0..b26220892e0d 100644 --- a/simapp/app_di.go +++ b/simapp/app_di.go @@ -15,6 +15,9 @@ import ( "cosmossdk.io/depinject" "cosmossdk.io/log" "cosmossdk.io/x/accounts" + basedepinject "cosmossdk.io/x/accounts/defaults/base/depinject" + lockupdepinject "cosmossdk.io/x/accounts/defaults/lockup/depinject" + multisigdepinject "cosmossdk.io/x/accounts/defaults/multisig/depinject" bankkeeper "cosmossdk.io/x/bank/keeper" circuitkeeper "cosmossdk.io/x/circuit/keeper" consensuskeeper "cosmossdk.io/x/consensus/keeper" @@ -155,6 +158,27 @@ func NewSimApp( // For providing a custom inflation function for x/mint add here your // custom function that implements the minttypes.MintFn interface. ), + depinject.Provide( + // inject desired account types: + multisigdepinject.ProvideAccount, + basedepinject.ProvideAccount, + lockupdepinject.ProvideAllLockupAccounts, + + // provide base account options + basedepinject.ProvideSecp256K1PubKey, + // if you want to provide a custom public key you + // can do it from here. + // Example: + // basedepinject.ProvideCustomPubkey[Ed25519PublicKey]() + // + // You can also provide a custom public key with a custom validation function: + // + // basedepinject.ProvideCustomPubKeyAndValidationFunc(func(pub Ed25519PublicKey) error { + // if len(pub.Key) != 64 { + // return fmt.Errorf("invalid pub key size") + // } + // }) + ), ) ) diff --git a/simapp/go.mod b/simapp/go.mod index f6e537b4a73d..c2eeafc74d92 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -6,7 +6,7 @@ require ( cosmossdk.io/api v0.7.6 cosmossdk.io/client/v2 v2.0.0-20230630094428-02b760776860 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/log v1.4.1 @@ -48,7 +48,8 @@ require ( require ( cosmossdk.io/x/accounts/defaults/base v0.0.0-00010101000000-000000000000 - google.golang.org/grpc v1.67.0 + cosmossdk.io/x/accounts/defaults/multisig v0.0.0-00010101000000-000000000000 + google.golang.org/grpc v1.67.1 ) require ( @@ -61,8 +62,7 @@ require ( cloud.google.com/go/iam v1.1.13 // indirect cloud.google.com/go/storage v1.43.0 // indirect cosmossdk.io/errors v1.0.1 // indirect - cosmossdk.io/schema v0.3.0 // indirect - cosmossdk.io/x/accounts/defaults/multisig v0.0.0-00010101000000-000000000000 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect @@ -179,7 +179,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.2.0 // indirect @@ -213,7 +213,7 @@ require ( golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect @@ -223,7 +223,7 @@ require ( google.golang.org/api v0.192.0 // indirect google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/simapp/go.sum b/simapp/go.sum index 943624caf8b8..84be5993cd65 100644 --- a/simapp/go.sum +++ b/simapp/go.sum @@ -192,8 +192,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -204,8 +204,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= @@ -731,8 +731,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -983,8 +983,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1338,8 +1338,8 @@ google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22du google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142/go.mod h1:G11eXq53iI5Q+kyNOmCvnzBaxEA2Q/Ik5Tj7nqBE8j4= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1375,8 +1375,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/simapp/simd/cmd/testnet.go b/simapp/simd/cmd/testnet.go index 116307f63bf2..b7199b4cbafa 100644 --- a/simapp/simd/cmd/testnet.go +++ b/simapp/simd/cmd/testnet.go @@ -353,7 +353,7 @@ func initTestnetFiles( valStr, valPubKeys[i], sdk.NewCoin(args.bondTokenDenom, valTokens), - stakingtypes.NewDescription(nodeDirName, "", "", "", ""), + stakingtypes.NewDescription(nodeDirName, "", "", "", "", stakingtypes.Metadata{}), stakingtypes.NewCommissionRates(math.LegacyOneDec(), math.LegacyOneDec(), math.LegacyOneDec()), math.OneInt(), ) diff --git a/simapp/upgrades.go b/simapp/upgrades.go index a4a475490ca2..fc754250b6ce 100644 --- a/simapp/upgrades.go +++ b/simapp/upgrades.go @@ -15,12 +15,12 @@ import ( ) // UpgradeName defines the on-chain upgrade name for the sample SimApp upgrade -// from v0.50.x to v0.51.x +// from v0.52.x to v0.54.x // // NOTE: This upgrade defines a reference implementation of what an upgrade // could look like when an application is migrating from Cosmos SDK version -// v0.50.x to v0.51.x. -const UpgradeName = "v050-to-v051" +// v0.52.x to v0.54.x. +const UpgradeName = "v052-to-v054" func (app SimApp) RegisterUpgradeHandlers() { app.UpgradeKeeper.SetUpgradeHandler( diff --git a/simapp/v2/app_di.go b/simapp/v2/app_di.go index 25f62b8f3ca5..43ca45f99aed 100644 --- a/simapp/v2/app_di.go +++ b/simapp/v2/app_di.go @@ -13,6 +13,9 @@ import ( "cosmossdk.io/log" "cosmossdk.io/runtime/v2" "cosmossdk.io/store/v2/root" + basedepinject "cosmossdk.io/x/accounts/defaults/base/depinject" + lockupdepinject "cosmossdk.io/x/accounts/defaults/lockup/depinject" + multisigdepinject "cosmossdk.io/x/accounts/defaults/multisig/depinject" upgradekeeper "cosmossdk.io/x/upgrade/keeper" "github.com/cosmos/cosmos-sdk/client" @@ -61,10 +64,9 @@ func NewSimApp[T transaction.Tx]( viper *viper.Viper, ) *SimApp[T] { var ( - app = &SimApp[T]{} - appBuilder *runtime.AppBuilder[T] - err error - storeOptions = &root.Options{} + app = &SimApp[T]{} + appBuilder *runtime.AppBuilder[T] + err error // merge the AppConfig and other configuration in one config appConfig = depinject.Configs( @@ -119,6 +121,25 @@ func NewSimApp[T transaction.Tx]( codec.ProvideAddressCodec, codec.ProvideProtoCodec, codec.ProvideLegacyAmino, + // inject desired account types: + multisigdepinject.ProvideAccount, + basedepinject.ProvideAccount, + lockupdepinject.ProvideAllLockupAccounts, + + // provide base account options + basedepinject.ProvideSecp256K1PubKey, + // if you want to provide a custom public key you + // can do it from here. + // Example: + // basedepinject.ProvideCustomPubkey[Ed25519PublicKey]() + // + // You can also provide a custom public key with a custom validation function: + // + // basedepinject.ProvideCustomPubKeyAndValidationFunc(func(pub Ed25519PublicKey) error { + // if len(pub.Key) != 64 { + // return fmt.Errorf("invalid pub key size") + // } + // }) ), depinject.Invoke( std.RegisterInterfaces, @@ -127,6 +148,19 @@ func NewSimApp[T transaction.Tx]( ) ) + // the subsection of config that contains the store options (in app.toml [store.options] header) + // is unmarshaled into a store.Options struct and passed to the store builder. + // future work may move this specification and retrieval into store/v2. + // If these options are not specified then default values will be used. + if sub := viper.Sub("store.options"); sub != nil { + storeOptions := &root.Options{} + err := sub.Unmarshal(storeOptions) + if err != nil { + panic(err) + } + appConfig = depinject.Configs(appConfig, depinject.Supply(storeOptions)) + } + if err := depinject.Inject(appConfig, &appBuilder, &app.appCodec, @@ -138,15 +172,7 @@ func NewSimApp[T transaction.Tx]( panic(err) } - var builderOpts []runtime.AppBuilderOption[T] - if sub := viper.Sub("store.options"); sub != nil { - err = sub.Unmarshal(storeOptions) - if err != nil { - panic(err) - } - builderOpts = append(builderOpts, runtime.AppBuilderWithStoreOptions[T](storeOptions)) - } - app.App, err = appBuilder.Build(builderOpts...) + app.App, err = appBuilder.Build() if err != nil { panic(err) } diff --git a/simapp/v2/go.mod b/simapp/v2/go.mod index 06d1f5260c92..484d0de1e4ee 100644 --- a/simapp/v2/go.mod +++ b/simapp/v2/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/client/v2 v2.0.0-00010101000000-000000000000 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 cosmossdk.io/log v1.4.1 cosmossdk.io/math v1.3.0 @@ -42,6 +42,12 @@ require ( google.golang.org/protobuf v1.34.2 ) +require ( + cosmossdk.io/x/accounts/defaults/base v0.0.0-00010101000000-000000000000 + cosmossdk.io/x/accounts/defaults/lockup v0.0.0-00010101000000-000000000000 + cosmossdk.io/x/accounts/defaults/multisig v0.0.0-00010101000000-000000000000 +) + require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect @@ -55,13 +61,10 @@ require ( cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/errors/v2 v2.0.0-20240731132947-df72853b3ca5 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/server/v2/appmanager v0.0.0-20240802110823-cffeedff643d // indirect cosmossdk.io/server/v2/stf v0.0.0-20240708142107-25e99c54bac1 // indirect cosmossdk.io/store v1.1.1 // indirect - cosmossdk.io/x/accounts/defaults/base v0.0.0-00010101000000-000000000000 // indirect - cosmossdk.io/x/accounts/defaults/lockup v0.0.0-20240417181816-5e7aae0db1f5 // indirect - cosmossdk.io/x/accounts/defaults/multisig v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.5 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -183,7 +186,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.2.0 // indirect @@ -217,7 +220,7 @@ require ( golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect @@ -227,8 +230,8 @@ require ( google.golang.org/api v0.192.0 // indirect google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/grpc v1.67.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect + google.golang.org/grpc v1.67.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect @@ -288,7 +291,6 @@ replace ( // server v2 integration replace ( cosmossdk.io/api => ../../api - cosmossdk.io/core => ../../core cosmossdk.io/runtime/v2 => ../../runtime/v2 cosmossdk.io/server/v2 => ../../server/v2 cosmossdk.io/server/v2/appmanager => ../../server/v2/appmanager diff --git a/simapp/v2/go.sum b/simapp/v2/go.sum index 6aa505080e4e..b0eca7fdef2e 100644 --- a/simapp/v2/go.sum +++ b/simapp/v2/go.sum @@ -192,6 +192,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -204,8 +206,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= @@ -733,8 +735,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -985,8 +987,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1340,8 +1342,8 @@ google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22du google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142/go.mod h1:G11eXq53iI5Q+kyNOmCvnzBaxEA2Q/Ik5Tj7nqBE8j4= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1377,8 +1379,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/simapp/v2/simdv2/cmd/commands.go b/simapp/v2/simdv2/cmd/commands.go index 916f4b2be9da..addc7eeb768b 100644 --- a/simapp/v2/simdv2/cmd/commands.go +++ b/simapp/v2/simdv2/cmd/commands.go @@ -15,6 +15,7 @@ import ( runtimev2 "cosmossdk.io/runtime/v2" serverv2 "cosmossdk.io/server/v2" "cosmossdk.io/server/v2/api/grpc" + "cosmossdk.io/server/v2/api/telemetry" "cosmossdk.io/server/v2/cometbft" "cosmossdk.io/server/v2/store" "cosmossdk.io/simapp/v2" @@ -81,6 +82,7 @@ func initRootCmd[T transaction.Tx]( ), grpc.New[T](), store.New[T](newApp), + telemetry.New[T](), ); err != nil { panic(err) } diff --git a/simapp/v2/simdv2/cmd/testnet.go b/simapp/v2/simdv2/cmd/testnet.go index 8b15f9ccd7ad..ae01310f9151 100644 --- a/simapp/v2/simdv2/cmd/testnet.go +++ b/simapp/v2/simdv2/cmd/testnet.go @@ -296,7 +296,7 @@ func initTestnetFiles[T transaction.Tx]( valStr, valPubKeys[i], sdk.NewCoin(args.bondTokenDenom, valTokens), - stakingtypes.NewDescription(nodeDirName, "", "", "", ""), + stakingtypes.NewDescription(nodeDirName, "", "", "", "", stakingtypes.Metadata{}), stakingtypes.NewCommissionRates(math.LegacyOneDec(), math.LegacyOneDec(), math.LegacyOneDec()), math.OneInt(), ) diff --git a/simapp/v2/upgrades.go b/simapp/v2/upgrades.go index 48d557eedb41..2145196fa86d 100644 --- a/simapp/v2/upgrades.go +++ b/simapp/v2/upgrades.go @@ -14,12 +14,12 @@ import ( ) // UpgradeName defines the on-chain upgrade name for the sample SimApp upgrade -// from v0.50.x to v0.51.x +// from v0.52.x to v2 // // NOTE: This upgrade defines a reference implementation of what an upgrade // could look like when an application is migrating from Cosmos SDK version -// v0.50.x to v0.51.x. -const UpgradeName = "v050-to-v051" +// v0.52.x to v2. +const UpgradeName = "v052-to-v2" func (app *SimApp[T]) RegisterUpgradeHandlers() { app.UpgradeKeeper.SetUpgradeHandler( diff --git a/store/go.mod b/store/go.mod index 6107221697d9..a1d3ad87b431 100644 --- a/store/go.mod +++ b/store/go.mod @@ -21,7 +21,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/tidwall/btree v1.7.0 go.uber.org/mock v0.4.0 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 gotest.tools/v3 v3.5.1 ) @@ -53,6 +53,6 @@ require ( golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/store/go.sum b/store/go.sum index 8d72d4ff8231..f00b75056cd0 100644 --- a/store/go.sum +++ b/store/go.sum @@ -280,10 +280,10 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index 0c8a1ef3a3b0..d23bcc57b090 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -1147,7 +1147,9 @@ func (rs *Store) flushMetadata(db corestore.KVStoreWithBatch, version int64, cIn rs.logger.Debug("flushing metadata", "height", version) batch := db.NewBatch() defer func() { - _ = batch.Close() + if err := batch.Close(); err != nil { + rs.logger.Error("call flushMetadata error on batch close", "err", err) + } }() if cInfo != nil { diff --git a/store/v2/commitment/metadata.go b/store/v2/commitment/metadata.go index d7aea487c706..642e6b630dac 100644 --- a/store/v2/commitment/metadata.go +++ b/store/v2/commitment/metadata.go @@ -2,6 +2,7 @@ package commitment import ( "bytes" + "errors" "fmt" corestore "cosmossdk.io/core/store" @@ -81,10 +82,7 @@ func (m *MetadataStore) flushCommitInfo(version uint64, cInfo *proof.CommitInfo) batch := m.kv.NewBatch() defer func() { - cErr := batch.Close() - if err == nil { - err = cErr - } + err = errors.Join(err, batch.Close()) }() cInfoKey := []byte(fmt.Sprintf(commitInfoKeyFmt, version)) value, err := cInfo.Marshal() @@ -113,10 +111,7 @@ func (m *MetadataStore) flushCommitInfo(version uint64, cInfo *proof.CommitInfo) func (m *MetadataStore) flushRemovedStoreKeys(version uint64, storeKeys []string) (err error) { batch := m.kv.NewBatch() defer func() { - cErr := batch.Close() - if err == nil { - err = cErr - } + err = errors.Join(err, batch.Close()) }() for _, storeKey := range storeKeys { @@ -158,9 +153,7 @@ func (m *MetadataStore) deleteRemovedStoreKeys(version uint64, removeStore func( batch := m.kv.NewBatch() defer func() { - if berr := batch.Close(); berr != nil { - err = berr - } + err = errors.Join(err, batch.Close()) }() for _, storeKey := range removedStoreKeys { if err := removeStore(storeKey, version); err != nil { diff --git a/store/v2/go.mod b/store/v2/go.mod index 95d69785d137..1a0d84d80a8b 100644 --- a/store/v2/go.mod +++ b/store/v2/go.mod @@ -52,7 +52,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/zerolog v1.33.0 // indirect diff --git a/store/v2/go.sum b/store/v2/go.sum index 18861dba214c..8211266d41a1 100644 --- a/store/v2/go.sum +++ b/store/v2/go.sum @@ -189,8 +189,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -245,8 +245,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/store/v2/migration/manager.go b/store/v2/migration/manager.go index a7ce8204a4b3..237dbd1e3606 100644 --- a/store/v2/migration/manager.go +++ b/store/v2/migration/manager.go @@ -185,10 +185,7 @@ func (m *Manager) writeChangeset() error { // yet not in the for-loop which can leave resource lingering. err = func() (err error) { defer func() { - cErr := batch.Close() - if err == nil { - err = cErr - } + err = errors.Join(err, batch.Close()) }() if err := batch.Set(csKey, csBytes); err != nil { diff --git a/store/v2/storage/pebbledb/db.go b/store/v2/storage/pebbledb/db.go index 4acdc392b63a..e5fd49ca3e5d 100644 --- a/store/v2/storage/pebbledb/db.go +++ b/store/v2/storage/pebbledb/db.go @@ -212,10 +212,7 @@ func (db *Database) Prune(version uint64) (err error) { batch := db.storage.NewBatch() defer func() { - cErr := batch.Close() - if err == nil { - err = cErr - } + err = errors.Join(err, batch.Close()) }() var ( @@ -339,10 +336,7 @@ func (db *Database) ReverseIterator(storeKey []byte, version uint64, start, end func (db *Database) PruneStoreKeys(storeKeys []string, version uint64) (err error) { batch := db.storage.NewBatch() defer func() { - cErr := batch.Close() - if err == nil { - err = cErr - } + err = errors.Join(err, batch.Close()) }() for _, storeKey := range storeKeys { @@ -444,10 +438,7 @@ func getMVCCSlice(db *pebble.DB, storeKey, key []byte, version uint64) ([]byte, func (db *Database) deleteRemovedStoreKeys(version uint64) (err error) { batch := db.storage.NewBatch() defer func() { - cErr := batch.Close() - if err == nil { - err = cErr - } + err = errors.Join(err, batch.Close()) }() end := encoding.BuildPrefixWithVersion(removedStoreKeyPrefix, version+1) diff --git a/telemetry/wrapper.go b/telemetry/wrapper.go index 1e37cb8cc296..4362c46a4413 100644 --- a/telemetry/wrapper.go +++ b/telemetry/wrapper.go @@ -8,11 +8,9 @@ import ( // Common metric key constants const ( - MetricKeyBeginBlocker = "begin_blocker" - MetricKeyEndBlocker = "end_blocker" - MetricKeyPrepareCheckStater = "prepare_check_stater" - MetricKeyPrecommiter = "precommiter" - MetricLabelNameModule = "module" + MetricKeyBeginBlocker = "begin_blocker" + MetricKeyEndBlocker = "end_blocker" + MetricLabelNameModule = "module" ) // NewLabel creates a new instance of Label with name and value diff --git a/tests/e2e/accounts/multisig/test_suite.go b/tests/e2e/accounts/multisig/test_suite.go index 3aa23f147d25..d2e6debb6de6 100644 --- a/tests/e2e/accounts/multisig/test_suite.go +++ b/tests/e2e/accounts/multisig/test_suite.go @@ -10,7 +10,6 @@ import ( "cosmossdk.io/core/transaction" "cosmossdk.io/math" "cosmossdk.io/simapp" - multisigaccount "cosmossdk.io/x/accounts/defaults/multisig" v1 "cosmossdk.io/x/accounts/defaults/multisig/v1" "cosmossdk.io/x/bank/testutil" @@ -76,7 +75,7 @@ func (s *E2ETestSuite) initAccount(ctx context.Context, sender []byte, membersPo members = append(members, &v1.Member{Address: addrStr, Weight: power}) } - _, accountAddr, err := s.app.AccountsKeeper.Init(ctx, multisigaccount.MULTISIG_ACCOUNT, sender, + _, accountAddr, err := s.app.AccountsKeeper.Init(ctx, "multisig", sender, &v1.MsgInit{ Members: members, Config: &v1.Config{ diff --git a/tests/e2e/authz/cli_test.go b/tests/e2e/authz/cli_test.go deleted file mode 100644 index 55348c99bd8f..000000000000 --- a/tests/e2e/authz/cli_test.go +++ /dev/null @@ -1,20 +0,0 @@ -//go:build e2e -// +build e2e - -package authz - -import ( - "testing" - - "github.com/stretchr/testify/suite" - - "cosmossdk.io/simapp" - - "github.com/cosmos/cosmos-sdk/testutil/network" -) - -func TestE2ETestSuite(t *testing.T) { - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - suite.Run(t, NewE2ETestSuite(cfg)) -} diff --git a/tests/e2e/authz/grpc.go b/tests/e2e/authz/grpc.go deleted file mode 100644 index d06c85bb024c..000000000000 --- a/tests/e2e/authz/grpc.go +++ /dev/null @@ -1,270 +0,0 @@ -package authz - -import ( - "fmt" - "time" - - "cosmossdk.io/math" - "cosmossdk.io/x/authz" - "cosmossdk.io/x/authz/client/cli" - authzclitestutil "cosmossdk.io/x/authz/client/testutil" - banktypes "cosmossdk.io/x/bank/types" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/testutil" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (s *E2ETestSuite) TestQueryGrantGRPC() { - val := s.network.GetValidators()[0] - grantee := s.grantee[1] - grantsURL := val.GetAPIAddress() + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s&msg_type_url=%s" - testCases := []struct { - name string - url string - expectErr bool - errorMsg string - }{ - { - "fail invalid granter address", - fmt.Sprintf(grantsURL, "invalid_granter", grantee.String(), typeMsgSend), - true, - "decoding bech32 failed: invalid separator index -1: invalid request", - }, - { - "fail invalid grantee address", - fmt.Sprintf(grantsURL, val.GetAddress().String(), "invalid_grantee", typeMsgSend), - true, - "decoding bech32 failed: invalid separator index -1: invalid request", - }, - { - "fail with empty granter", - fmt.Sprintf(grantsURL, "", grantee.String(), typeMsgSend), - true, - "empty address string is not allowed: invalid request", - }, - { - "fail with empty grantee", - fmt.Sprintf(grantsURL, val.GetAddress().String(), "", typeMsgSend), - true, - "empty address string is not allowed: invalid request", - }, - { - "fail invalid msg-type", - fmt.Sprintf(grantsURL, val.GetAddress().String(), grantee.String(), "invalidMsg"), - true, - "authorization not found for invalidMsg type", - }, - { - "valid query", - fmt.Sprintf(grantsURL, val.GetAddress().String(), grantee.String(), typeMsgSend), - false, - "", - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, _ := testutil.GetRequest(tc.url) - require := s.Require() - if tc.expectErr { - require.Contains(string(resp), tc.errorMsg) - } else { - var g authz.QueryGrantsResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(resp, &g) - require.NoError(err) - require.Len(g.Grants, 1) - err = g.Grants[0].UnpackInterfaces(val.GetClientCtx().InterfaceRegistry) - require.NoError(err) - auth, err := g.Grants[0].GetAuthorization() - require.NoError(err) - require.Equal(auth.MsgTypeURL(), banktypes.SendAuthorization{}.MsgTypeURL()) - } - }) - } -} - -func (s *E2ETestSuite) TestQueryGrantsGRPC() { - val := s.network.GetValidators()[0] - grantee := s.grantee[1] - grantsURL := val.GetAPIAddress() + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s" - testCases := []struct { - name string - url string - expectErr bool - errMsg string - preRun func() - postRun func(*authz.QueryGrantsResponse) - }{ - { - "valid query: expect single grant", - fmt.Sprintf(grantsURL, val.GetAddress().String(), grantee.String()), - false, - "", - func() {}, - func(g *authz.QueryGrantsResponse) { - s.Require().Len(g.Grants, 1) - }, - }, - { - "valid query: expect two grants", - fmt.Sprintf(grantsURL, val.GetAddress().String(), grantee.String()), - false, - "", - func() { - _, err := authzclitestutil.CreateGrant(val.GetClientCtx(), []string{ - grantee.String(), - "generic", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), - }) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - }, - func(g *authz.QueryGrantsResponse) { - s.Require().Len(g.Grants, 2) - }, - }, - { - "valid query: expect single grant with pagination", - fmt.Sprintf(grantsURL+"&pagination.limit=1", val.GetAddress().String(), grantee.String()), - false, - "", - func() {}, - func(g *authz.QueryGrantsResponse) { - s.Require().Len(g.Grants, 1) - }, - }, - { - "valid query: expect two grants with pagination", - fmt.Sprintf(grantsURL+"&pagination.limit=2", val.GetAddress().String(), grantee.String()), - false, - "", - func() {}, - func(g *authz.QueryGrantsResponse) { - s.Require().Len(g.Grants, 2) - }, - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - tc.preRun() - resp, err := testutil.GetRequest(tc.url) - s.Require().NoError(err) - - if tc.expectErr { - s.Require().Contains(string(resp), tc.errMsg) - } else { - var authorizations authz.QueryGrantsResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(resp, &authorizations) - s.Require().NoError(err) - tc.postRun(&authorizations) - } - }) - } -} - -func (s *E2ETestSuite) TestQueryGranterGrantsGRPC() { - val := s.network.GetValidators()[0] - grantee := s.grantee[1] - require := s.Require() - - testCases := []struct { - name string - url string - expectErr bool - errMsg string - numItems int - }{ - { - "invalid account address", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/granter/%s", val.GetAPIAddress(), "invalid address"), - true, - "decoding bech32 failed", - 0, - }, - { - "no authorizations found", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/granter/%s", val.GetAPIAddress(), grantee.String()), - false, - "", - 0, - }, - { - "valid query", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/granter/%s", val.GetAPIAddress(), val.GetAddress().String()), - false, - "", - 6, - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := testutil.GetRequest(tc.url) - require.NoError(err) - - if tc.expectErr { - require.Contains(string(resp), tc.errMsg) - } else { - var authorizations authz.QueryGranterGrantsResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(resp, &authorizations) - require.NoError(err) - require.Len(authorizations.Grants, tc.numItems) - } - }) - } -} - -func (s *E2ETestSuite) TestQueryGranteeGrantsGRPC() { - val := s.network.GetValidators()[0] - grantee := s.grantee[1] - require := s.Require() - - testCases := []struct { - name string - url string - expectErr bool - errMsg string - numItems int - }{ - { - "invalid account address", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/grantee/%s", val.GetAPIAddress(), "invalid address"), - true, - "decoding bech32 failed", - 0, - }, - { - "no authorizations found", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/grantee/%s", val.GetAPIAddress(), val.GetAddress().String()), - false, - "", - 0, - }, - { - "valid query", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/grantee/%s", val.GetAPIAddress(), grantee.String()), - false, - "", - 1, - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := testutil.GetRequest(tc.url) - require.NoError(err) - - if tc.expectErr { - require.Contains(string(resp), tc.errMsg) - } else { - var authorizations authz.QueryGranteeGrantsResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(resp, &authorizations) - require.NoError(err) - require.Len(authorizations.Grants, tc.numItems) - } - }) - } -} diff --git a/tests/e2e/authz/tx.go b/tests/e2e/authz/tx.go deleted file mode 100644 index bf8757c0777b..000000000000 --- a/tests/e2e/authz/tx.go +++ /dev/null @@ -1,923 +0,0 @@ -package authz - -import ( - "fmt" - "time" - - "github.com/cosmos/gogoproto/proto" - "github.com/stretchr/testify/suite" - - // without this import amino json encoding will fail when resolving any types - _ "cosmossdk.io/api/cosmos/authz/v1beta1" - "cosmossdk.io/math" - "cosmossdk.io/x/authz" - "cosmossdk.io/x/authz/client/cli" - authzclitestutil "cosmossdk.io/x/authz/client/testutil" - bank "cosmossdk.io/x/bank/types" - govcli "cosmossdk.io/x/gov/client/cli" - govtestutil "cosmossdk.io/x/gov/client/testutil" - govv1 "cosmossdk.io/x/gov/types/v1" - govv1beta1 "cosmossdk.io/x/gov/types/v1beta1" - stakingtypes "cosmossdk.io/x/staking/types" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" - authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" -) - -type E2ETestSuite struct { - suite.Suite - - cfg network.Config - network network.NetworkI - grantee []sdk.AccAddress -} - -func NewE2ETestSuite(cfg network.Config) *E2ETestSuite { - return &E2ETestSuite{cfg: cfg} -} - -func (s *E2ETestSuite) SetupSuite() { - s.T().Log("setting up e2e test suite") - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) - - val := s.network.GetValidators()[0] - s.grantee = make([]sdk.AccAddress, 6) - - // Send some funds to the new account. - // Create new account in the keyring. - s.grantee[0] = s.createAccount("grantee1") - s.msgSendExec(s.grantee[0]) - - // create a proposal with deposit - _, err = govtestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 1", "Where is the title!?", govv1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", govcli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, govv1.DefaultMinDepositTokens).String())) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // Create new account in the keyring. - s.grantee[1] = s.createAccount("grantee2") - // Send some funds to the new account. - s.msgSendExec(s.grantee[1]) - - // grant send authorization to grantee2 - out, err := authzclitestutil.CreateGrant(val.GetClientCtx(), []string{ - s.grantee[1].String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), - }) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - var response sdk.TxResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, 0)) - - // Create new account in the keyring. - s.grantee[2] = s.createAccount("grantee3") - - // grant send authorization to grantee3 - _, err = authzclitestutil.CreateGrant(val.GetClientCtx(), []string{ - s.grantee[2].String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), - }) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // Create new accounts in the keyring. - s.grantee[3] = s.createAccount("grantee4") - s.msgSendExec(s.grantee[3]) - - s.grantee[4] = s.createAccount("grantee5") - s.grantee[5] = s.createAccount("grantee6") - - // grant send authorization with allow list to grantee4 - out, err = authzclitestutil.CreateGrant(val.GetClientCtx(), - []string{ - s.grantee[3].String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%s", cli.FlagAllowList, s.grantee[4]), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, 0)) -} - -func (s *E2ETestSuite) createAccount(uid string) sdk.AccAddress { - val := s.network.GetValidators()[0] - // Create new account in the keyring. - k, _, err := val.GetClientCtx().Keyring.NewMnemonic(uid, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - - addr, err := k.GetAddress() - s.Require().NoError(err) - - return addr -} - -func (s *E2ETestSuite) msgSendExec(grantee sdk.AccAddress) { - val := s.network.GetValidators()[0] - // Send some funds to the new account. - - from := val.GetAddress() - coins := sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(200))) - msgSend := &bank.MsgSend{ - FromAddress: from.String(), - ToAddress: grantee.String(), - Amount: coins, - } - - out, err := clitestutil.SubmitTestTx( - val.GetClientCtx(), - msgSend, - from, - clitestutil.TestTxConfig{}, - ) - - s.Require().NoError(err) - s.Require().Contains(out.String(), `"code":0`) - s.Require().NoError(s.network.WaitForNextBlock()) -} - -func (s *E2ETestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite") - s.network.Cleanup() -} - -var ( - typeMsgSend = bank.SendAuthorization{}.MsgTypeURL() - typeMsgVote = sdk.MsgTypeURL(&govv1.MsgVote{}) -) - -func (s *E2ETestSuite) TestExecAuthorizationWithExpiration() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - tenSeconds := time.Now().Add(time.Second * time.Duration(10)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "generic", - fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, tenSeconds), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - // msg vote - voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String()) - execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) - defer execMsg.Close() - - // waiting for authorization to expires - time.Sleep(12 * time.Second) - - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }) - s.Require().NoError(err) - var response sdk.TxResponse - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, response.TxHash, authz.ErrNoAuthorizationFound.ABCICode())) -} - -func (s *E2ETestSuite) TestNewExecGenericAuthorized() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "generic", - fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // msg vote - voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String()) - execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) - defer execMsg.Close() - - testCases := []struct { - name string - args []string - respType proto.Message - expectedCode uint32 - expectErr bool - }{ - { - "fail invalid grantee", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, "grantee"), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - }, - nil, - 0, - true, - }, - { - "fail invalid json path", - []string{ - "/invalid/file.txt", - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - }, - nil, - 0, - true, - }, - { - "valid txn", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - &sdk.TxResponse{}, - 0, - false, - }, - { - "valid tx with amino", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), - }, - &sdk.TxResponse{}, 0, - false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - txResp := tc.respType.(*sdk.TxResponse) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), txResp.TxHash, tc.expectedCode)) - } - }) - } -} - -func (s *E2ETestSuite) TestNewExecGrantAuthorized() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - grantee1 := s.grantee[2] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "send", - fmt.Sprintf("--%s=12%stoken", cli.FlagSpendLimit, val.GetMoniker()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - from := val.GetAddress() - tokens := sdk.NewCoins( - sdk.NewCoin(fmt.Sprintf("%stoken", val.GetMoniker()), math.NewInt(12)), - ) - msgSend := &bank.MsgSend{ - FromAddress: from.String(), - ToAddress: grantee.String(), - Amount: tokens, - } - normalGeneratedTx, err := clitestutil.SubmitTestTx( - val.GetClientCtx(), - msgSend, - from, - clitestutil.TestTxConfig{ - GenOnly: true, - }, - ) - - s.Require().NoError(err) - execMsg := testutil.WriteToNewTempFile(s.T(), normalGeneratedTx.String()) - defer execMsg.Close() - testCases := []struct { - name string - args []string - expectedCode uint32 - expectErr bool - expectErrMsg string - }{ - { - "valid txn", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "error over grantee doesn't exist on chain", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee1.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - true, - "insufficient funds", // earlier the error was account not found here. - }, - { - "error over spent", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - authz.ErrNoAuthorizationFound.ABCICode(), - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - var response sdk.TxResponse - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - switch { - case tc.expectErrMsg != "": - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().Contains(response.RawLog, tc.expectErrMsg) - - case tc.expectErr: - s.Require().Error(err) - - default: - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } -} - -func (s *E2ETestSuite) TestExecSendAuthzWithAllowList() { - val := s.network.GetValidators()[0] - grantee := s.grantee[3] - allowedAddr := s.grantee[4] - notAllowedAddr := s.grantee[5] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%s", cli.FlagAllowList, allowedAddr), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - from := val.GetAddress() - tokens := sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(12)), - ) - msgSend := &bank.MsgSend{ - FromAddress: from.String(), - ToAddress: allowedAddr.String(), - Amount: tokens, - } - - validGeneratedTx, err := clitestutil.SubmitTestTx( - val.GetClientCtx(), - msgSend, - from, - clitestutil.TestTxConfig{ - GenOnly: true, - }, - ) - s.Require().NoError(err) - execMsg := testutil.WriteToNewTempFile(s.T(), validGeneratedTx.String()) - defer execMsg.Close() - - msgSend1 := &bank.MsgSend{ - FromAddress: from.String(), - ToAddress: notAllowedAddr.String(), - Amount: tokens, - } - invalidGeneratedTx, err := clitestutil.SubmitTestTx( - val.GetClientCtx(), - msgSend1, - from, - clitestutil.TestTxConfig{ - GenOnly: true, - }, - ) - s.Require().NoError(err) - execMsg1 := testutil.WriteToNewTempFile(s.T(), invalidGeneratedTx.String()) - defer execMsg1.Close() - - // test sending to allowed address - args := []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - } - var response sdk.TxResponse - cmd := cli.NewCmdExecAuthorization() - out, err := clitestutil.ExecTestCLICmd(val.GetClientCtx(), cmd, args) - s.Require().NoError(err) - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(s.network.WaitForNextBlock()) - - // test sending to not allowed address - args = []string{ - execMsg1.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - } - out, err = clitestutil.ExecTestCLICmd(val.GetClientCtx(), cmd, args) - s.Require().NoError(err) - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(s.network.WaitForNextBlock()) - - // query tx and check result - err = s.network.RetryForBlocks(func() error { - out, err = clitestutil.ExecTestCLICmd(val.GetClientCtx(), authcli.QueryTxCmd(), []string{response.TxHash, fmt.Sprintf("--%s=json", flags.FlagOutput)}) - return err - }, 3) - s.Require().NoError(err) - s.Contains(out.String(), fmt.Sprintf("cannot send to %s address", notAllowedAddr)) -} - -func (s *E2ETestSuite) TestExecDelegateAuthorization() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "delegate", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - tokens := sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(50)), - ) - - delegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String(), val.GetValAddress().String(), - tokens.GetDenomByIndex(0), tokens[0].Amount) - execMsg := testutil.WriteToNewTempFile(s.T(), delegateTx) - defer execMsg.Close() - - testCases := []struct { - name string - args []string - expectedCode uint32 - expectErr bool - errMsg string - }{ - { - "valid txn: (delegate half tokens)", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "valid txn: (delegate remaining half tokens)", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "failed with error no authorization found", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - authz.ErrNoAuthorizationFound.ABCICode(), - false, - authz.ErrNoAuthorizationFound.Error(), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errMsg) - } else { - var response sdk.TxResponse - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } - - // test delegate no spend-limit - _, err = authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "delegate", - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - tokens = sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(50)), - ) - - delegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String(), val.GetValAddress().String(), - tokens.GetDenomByIndex(0), tokens[0].Amount) - execMsg = testutil.WriteToNewTempFile(s.T(), delegateTx) - defer execMsg.Close() - - testCases = []struct { - name string - args []string - expectedCode uint32 - expectErr bool - errMsg string - }{ - { - "valid txn", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errMsg) - } else { - var response sdk.TxResponse - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } - - // test delegating to denied validator - _, err = authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "delegate", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagDenyValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - args := []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - } - cmd := cli.NewCmdExecAuthorization() - out, err := clitestutil.ExecTestCLICmd(val.GetClientCtx(), cmd, args) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - var response sdk.TxResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - - // query tx and check result - err = s.network.RetryForBlocks(func() error { - out, err = clitestutil.ExecTestCLICmd(val.GetClientCtx(), authcli.QueryTxCmd(), []string{response.TxHash, fmt.Sprintf("--%s=json", flags.FlagOutput)}) - return err - }, 3) - s.Require().NoError(err) - s.Contains(out.String(), fmt.Sprintf("cannot delegate/undelegate to %s validator", val.GetValAddress().String())) -} - -func (s *E2ETestSuite) TestExecUndelegateAuthorization() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - // granting undelegate msg authorization - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "unbond", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // delegating stakes to validator - msg := &stakingtypes.MsgDelegate{ - DelegatorAddress: val.GetAddress().String(), - ValidatorAddress: val.GetValAddress().String(), - Amount: sdk.NewCoin("stake", math.NewInt(100)), - } - - _, err = clitestutil.SubmitTestTx(val.GetClientCtx(), msg, val.GetAddress(), clitestutil.TestTxConfig{}) - - s.Require().NoError(err) - - tokens := sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(50)), - ) - - undelegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String(), val.GetValAddress().String(), - tokens.GetDenomByIndex(0), tokens[0].Amount) - execMsg := testutil.WriteToNewTempFile(s.T(), undelegateTx) - defer execMsg.Close() - - testCases := []struct { - name string - args []string - expectedCode uint32 - expectErr bool - errMsg string - }{ - { - "valid txn: (undelegate half tokens)", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "valid txn: (undelegate remaining half tokens)", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "failed with error no authorization found", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - authz.ErrNoAuthorizationFound.ABCICode(), - false, - authz.ErrNoAuthorizationFound.Error(), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errMsg) - } else { - var response sdk.TxResponse - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } - - // grant undelegate authorization without limit - _, err = authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "unbond", - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - tokens = sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(50)), - ) - - undelegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String(), val.GetValAddress().String(), - tokens.GetDenomByIndex(0), tokens[0].Amount) - execMsg = testutil.WriteToNewTempFile(s.T(), undelegateTx) - defer execMsg.Close() - - testCases = []struct { - name string - args []string - expectedCode uint32 - expectErr bool - errMsg string - }{ - { - "valid txn", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errMsg) - } else { - var response sdk.TxResponse - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } -} diff --git a/tests/e2e/client/grpc/cmtservice/service_test.go b/tests/e2e/client/grpc/cmtservice/service_test.go deleted file mode 100644 index e4177a11edfb..000000000000 --- a/tests/e2e/client/grpc/cmtservice/service_test.go +++ /dev/null @@ -1,347 +0,0 @@ -//go:build e2e -// +build e2e - -package cmtservice_test - -import ( - "context" - "fmt" - "testing" - - "github.com/stretchr/testify/suite" - - "cosmossdk.io/simapp" - _ "cosmossdk.io/x/gov" - - "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/network" - qtypes "github.com/cosmos/cosmos-sdk/types/query" - "github.com/cosmos/cosmos-sdk/version" -) - -type E2ETestSuite struct { - suite.Suite - - cfg network.Config - network network.NetworkI - queryClient cmtservice.ServiceClient -} - -func TestE2ETestSuite(t *testing.T) { - suite.Run(t, new(E2ETestSuite)) -} - -func (s *E2ETestSuite) SetupSuite() { - s.T().Log("setting up e2e test suite") - - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - s.cfg = cfg - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - s.queryClient = cmtservice.NewServiceClient(s.network.GetValidators()[0].GetClientCtx()) -} - -func (s *E2ETestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite") - s.network.Cleanup() -} - -func (s *E2ETestSuite) TestQueryNodeInfo() { - val := s.network.GetValidators()[0] - - res, err := s.queryClient.GetNodeInfo(context.Background(), &cmtservice.GetNodeInfoRequest{}) - s.Require().NoError(err) - s.Require().Equal(res.ApplicationVersion.AppName, version.NewInfo().AppName) - - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", val.GetAPIAddress())) - s.Require().NoError(err) - var getInfoRes cmtservice.GetNodeInfoResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &getInfoRes)) - s.Require().Equal(getInfoRes.ApplicationVersion.AppName, version.NewInfo().AppName) -} - -func (s *E2ETestSuite) TestQuerySyncing() { - val := s.network.GetValidators()[0] - - _, err := s.queryClient.GetSyncing(context.Background(), &cmtservice.GetSyncingRequest{}) - s.Require().NoError(err) - - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/syncing", val.GetAPIAddress())) - s.Require().NoError(err) - var syncingRes cmtservice.GetSyncingResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &syncingRes)) -} - -func (s *E2ETestSuite) TestQueryLatestBlock() { - val := s.network.GetValidators()[0] - - _, err := s.queryClient.GetLatestBlock(context.Background(), &cmtservice.GetLatestBlockRequest{}) - s.Require().NoError(err) - - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/latest", val.GetAPIAddress())) - s.Require().NoError(err) - var blockInfoRes cmtservice.GetLatestBlockResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &blockInfoRes)) - s.Require().Contains(blockInfoRes.SdkBlock.Header.ProposerAddress, "cosmosvalcons") -} - -func (s *E2ETestSuite) TestQueryBlockByHeight() { - val := s.network.GetValidators()[0] - _, err := s.queryClient.GetBlockByHeight(context.Background(), &cmtservice.GetBlockByHeightRequest{Height: 1}) - s.Require().NoError(err) - - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/%d", val.GetAPIAddress(), 1)) - s.Require().NoError(err) - var blockInfoRes cmtservice.GetBlockByHeightResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &blockInfoRes)) - s.Require().Contains(blockInfoRes.SdkBlock.Header.ProposerAddress, "cosmosvalcons") -} - -func (s *E2ETestSuite) TestQueryLatestValidatorSet() { - val := s.network.GetValidators()[0] - - // nil pagination - res, err := s.queryClient.GetLatestValidatorSet(context.Background(), &cmtservice.GetLatestValidatorSetRequest{ - Pagination: nil, - }) - s.Require().NoError(err) - s.Require().Equal(1, len(res.Validators)) - content, ok := res.Validators[0].PubKey.GetCachedValue().(cryptotypes.PubKey) - s.Require().Equal(true, ok) - s.Require().Equal(content, val.GetPubKey()) - - // with pagination - _, err = s.queryClient.GetLatestValidatorSet(context.Background(), &cmtservice.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{ - Offset: 0, - Limit: 10, - }}) - s.Require().NoError(err) - - // rest request without pagination - _, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest", val.GetAPIAddress())) - s.Require().NoError(err) - - // rest request with pagination - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=%d&pagination.limit=%d", val.GetAPIAddress(), 0, 1)) - s.Require().NoError(err) - var validatorSetRes cmtservice.GetLatestValidatorSetResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &validatorSetRes)) - s.Require().Equal(1, len(validatorSetRes.Validators)) - anyPub, err := codectypes.NewAnyWithValue(val.GetPubKey()) - s.Require().NoError(err) - s.Require().Equal(validatorSetRes.Validators[0].PubKey, anyPub) -} - -func (s *E2ETestSuite) TestLatestValidatorSet_GRPC() { - vals := s.network.GetValidators() - testCases := []struct { - name string - req *cmtservice.GetLatestValidatorSetRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "cannot be nil"}, - {"no pagination", &cmtservice.GetLatestValidatorSetRequest{}, false, ""}, - {"with pagination", &cmtservice.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{Offset: 0, Limit: uint64(len(vals))}}, false, ""}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - grpcRes, err := s.queryClient.GetLatestValidatorSet(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - } else { - s.Require().NoError(err) - s.Require().Len(grpcRes.Validators, len(vals)) - s.Require().Equal(grpcRes.Pagination.Total, uint64(len(vals))) - content, ok := grpcRes.Validators[0].PubKey.GetCachedValue().(cryptotypes.PubKey) - s.Require().Equal(true, ok) - s.Require().Equal(content, vals[0].GetPubKey()) - } - }) - } -} - -func (s *E2ETestSuite) TestLatestValidatorSet_GRPCGateway() { - vals := s.network.GetValidators() - testCases := []struct { - name string - url string - expErr bool - expErrMsg string - }{ - {"no pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest", vals[0].GetAPIAddress()), false, ""}, - {"pagination invalid fields", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=-1&pagination.limit=-2", vals[0].GetAPIAddress()), true, "strconv.ParseUint"}, - {"with pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=0&pagination.limit=2", vals[0].GetAPIAddress()), false, ""}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := testutil.GetRequest(tc.url) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result cmtservice.GetLatestValidatorSetResponse - err = vals[0].GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - s.Require().Equal(uint64(len(vals)), result.Pagination.Total) - anyPub, err := codectypes.NewAnyWithValue(vals[0].GetPubKey()) - s.Require().NoError(err) - s.Require().Equal(result.Validators[0].PubKey, anyPub) - } - }) - } -} - -func (s *E2ETestSuite) TestValidatorSetByHeight_GRPC() { - vals := s.network.GetValidators() - testCases := []struct { - name string - req *cmtservice.GetValidatorSetByHeightRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "request cannot be nil"}, - {"empty request", &cmtservice.GetValidatorSetByHeightRequest{}, true, "height must be greater than 0"}, - {"no pagination", &cmtservice.GetValidatorSetByHeightRequest{Height: 1}, false, ""}, - {"with pagination", &cmtservice.GetValidatorSetByHeightRequest{Height: 1, Pagination: &qtypes.PageRequest{Offset: 0, Limit: 1}}, false, ""}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - grpcRes, err := s.queryClient.GetValidatorSetByHeight(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - } else { - s.Require().NoError(err) - s.Require().Len(grpcRes.Validators, len(vals)) - s.Require().Equal(grpcRes.Pagination.Total, uint64(len(vals))) - } - }) - } -} - -func (s *E2ETestSuite) TestValidatorSetByHeight_GRPCGateway() { - vals := s.network.GetValidators() - testCases := []struct { - name string - url string - expErr bool - expErrMsg string - }{ - {"invalid height", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d", vals[0].GetAPIAddress(), -1), true, "height must be greater than 0"}, - {"no pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d", vals[0].GetAPIAddress(), 1), false, ""}, - {"pagination invalid fields", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d?pagination.offset=-1&pagination.limit=-2", vals[0].GetAPIAddress(), 1), true, "strconv.ParseUint"}, - {"with pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d?pagination.offset=0&pagination.limit=2", vals[0].GetAPIAddress(), 1), false, ""}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := testutil.GetRequest(tc.url) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result cmtservice.GetValidatorSetByHeightResponse - err = vals[0].GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - s.Require().Equal(uint64(len(vals)), result.Pagination.Total) - } - }) - } -} - -func (s *E2ETestSuite) TestABCIQuery() { - testCases := []struct { - name string - req *cmtservice.ABCIQueryRequest - expectErr bool - expectedCode uint32 - validQuery bool - }{ - { - name: "valid request with proof", - req: &cmtservice.ABCIQueryRequest{ - Path: "/store/gov/key", - Data: []byte{0x03}, - Prove: true, - }, - validQuery: true, - }, - { - name: "valid request without proof", - req: &cmtservice.ABCIQueryRequest{ - Path: "/store/gov/key", - Data: []byte{0x03}, - Prove: false, - }, - validQuery: true, - }, - { - name: "request with invalid path", - req: &cmtservice.ABCIQueryRequest{ - Path: "/foo/bar", - Data: []byte{0x03}, - }, - expectErr: true, - }, - { - name: "request with invalid path recursive", - req: &cmtservice.ABCIQueryRequest{ - Path: "/cosmos.base.tendermint.v1beta1.Service/ABCIQuery", - Data: s.cfg.Codec.MustMarshal(&cmtservice.ABCIQueryRequest{ - Path: "/cosmos.base.tendermint.v1beta1.Service/ABCIQuery", - }), - }, - expectErr: true, - }, - { - name: "request with invalid broadcast tx path", - req: &cmtservice.ABCIQueryRequest{ - Path: "/cosmos.tx.v1beta1.Service/BroadcastTx", - Data: []byte{0x00}, - }, - expectErr: true, - }, - { - name: "request with invalid data", - req: &cmtservice.ABCIQueryRequest{ - Path: "/store/gov/key", - Data: []byte{0x0044, 0x00}, - }, - validQuery: false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := s.queryClient.ABCIQuery(context.Background(), tc.req) - if tc.expectErr { - s.Require().Error(err) - s.Require().Nil(res) - } else { - s.Require().NoError(err) - s.Require().NotNil(res) - s.Require().Equal(res.Code, tc.expectedCode) - } - - if tc.validQuery { - s.Require().Greater(res.Height, int64(0)) - s.Require().Greater(len(res.Key), 0, "expected non-empty key") - s.Require().Greater(len(res.Value), 0, "expected non-empty value") - } - - if tc.req.Prove { - s.Require().Greater(len(res.ProofOps.Ops), 0, "expected proofs") - } - }) - } -} diff --git a/tests/e2e/gov/cli_test.go b/tests/e2e/gov/cli_test.go deleted file mode 100644 index be8e7afc82e3..000000000000 --- a/tests/e2e/gov/cli_test.go +++ /dev/null @@ -1,37 +0,0 @@ -//go:build e2e -// +build e2e - -package gov - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - "cosmossdk.io/simapp" - v1 "cosmossdk.io/x/gov/types/v1" - - "github.com/cosmos/cosmos-sdk/testutil/network" -) - -func TestE2ETestSuite(t *testing.T) { - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - suite.Run(t, NewE2ETestSuite(cfg)) -} - -func TestDepositTestSuite(t *testing.T) { - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - genesisState := v1.DefaultGenesisState() - maxDepPeriod := time.Duration(20) * time.Second - votingPeriod := time.Duration(8) * time.Second - genesisState.Params.MaxDepositPeriod = &maxDepPeriod - genesisState.Params.VotingPeriod = &votingPeriod - bz, err := cfg.Codec.MarshalJSON(genesisState) - require.NoError(t, err) - cfg.GenesisState["gov"] = bz - suite.Run(t, NewDepositTestSuite(cfg)) -} diff --git a/tests/e2e/gov/deposits.go b/tests/e2e/gov/deposits.go deleted file mode 100644 index b685fa08bc62..000000000000 --- a/tests/e2e/gov/deposits.go +++ /dev/null @@ -1,164 +0,0 @@ -package gov - -import ( - "fmt" - "strconv" - "time" - - "github.com/stretchr/testify/suite" - - "cosmossdk.io/math" - "cosmossdk.io/x/gov/client/cli" - govclitestutil "cosmossdk.io/x/gov/client/testutil" - v1 "cosmossdk.io/x/gov/types/v1" - "cosmossdk.io/x/gov/types/v1beta1" - - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -type DepositTestSuite struct { - suite.Suite - - cfg network.Config - network network.NetworkI -} - -func NewDepositTestSuite(cfg network.Config) *DepositTestSuite { - return &DepositTestSuite{cfg: cfg} -} - -func (s *DepositTestSuite) SetupSuite() { - s.T().Log("setting up test suite") - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) -} - -func (s *DepositTestSuite) submitProposal(val network.ValidatorI, initialDeposit sdk.Coin, name string) uint64 { - var exactArgs []string - - if !initialDeposit.IsZero() { - exactArgs = append(exactArgs, fmt.Sprintf("--%s=%s", cli.FlagDeposit, initialDeposit.String())) - } - - _, err := govclitestutil.MsgSubmitLegacyProposal( - val.GetClientCtx(), - val.GetAddress().String(), - fmt.Sprintf("Text Proposal %s", name), - "Where is the title!?", - v1beta1.ProposalTypeText, - exactArgs..., - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // query proposals, return the last's id - res, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals", val.GetAPIAddress())) - s.Require().NoError(err) - var proposals v1.QueryProposalsResponse - err = s.cfg.Codec.UnmarshalJSON(res, &proposals) - s.Require().NoError(err) - s.Require().GreaterOrEqual(len(proposals.Proposals), 1) - - return proposals.Proposals[len(proposals.Proposals)-1].Id -} - -func (s *DepositTestSuite) TearDownSuite() { - s.T().Log("tearing down test suite") - s.network.Cleanup() -} - -func (s *DepositTestSuite) TestQueryDepositsWithInitialDeposit() { - val := s.network.GetValidators()[0] - depositAmount := sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens) - - // submit proposal with an initial deposit - id := s.submitProposal(val, depositAmount, "TestQueryDepositsWithInitialDeposit") - proposalID := strconv.FormatUint(id, 10) - - // query deposit - deposit := s.queryDeposit(val, proposalID, false, "") - s.Require().NotNil(deposit) - s.Require().Equal(depositAmount.String(), sdk.Coins(deposit.Deposit.Amount).String()) - - // query deposits - deposits := s.queryDeposits(val, proposalID, false, "") - s.Require().NotNil(deposits) - s.Require().Len(deposits.Deposits, 1) - // verify initial deposit - s.Require().Equal(depositAmount.String(), sdk.Coins(deposits.Deposits[0].Amount).String()) -} - -func (s *DepositTestSuite) TestQueryProposalAfterVotingPeriod() { - val := s.network.GetValidators()[0] - depositAmount := sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens.Sub(math.NewInt(50))) - - // submit proposal with an initial deposit - id := s.submitProposal(val, depositAmount, "TestQueryProposalAfterVotingPeriod") - proposalID := strconv.FormatUint(id, 10) - - resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals", val.GetAPIAddress())) - s.Require().NoError(err) - var proposals v1.QueryProposalsResponse - err = s.cfg.Codec.UnmarshalJSON(resp, &proposals) - s.Require().NoError(err) - s.Require().GreaterOrEqual(len(proposals.Proposals), 1) - - // query proposal - resp, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals/%s", val.GetAPIAddress(), proposalID)) - s.Require().NoError(err) - var proposal v1.QueryProposalResponse - err = s.cfg.Codec.UnmarshalJSON(resp, &proposal) - s.Require().NoError(err) - - // waiting for deposit and voting period to end - time.Sleep(25 * time.Second) - - // query proposal - resp, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals/%s", val.GetAPIAddress(), proposalID)) - s.Require().NoError(err) - s.Require().Contains(string(resp), fmt.Sprintf("proposal %s doesn't exist", proposalID)) - - // query deposits - deposits := s.queryDeposits(val, proposalID, false, "") - s.Require().Len(deposits.Deposits, 0) -} - -func (s *DepositTestSuite) queryDeposits(val network.ValidatorI, proposalID string, exceptErr bool, message string) *v1.QueryDepositsResponse { - s.Require().NoError(s.network.WaitForNextBlock()) - - resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals/%s/deposits", val.GetAPIAddress(), proposalID)) - s.Require().NoError(err) - - if exceptErr { - s.Require().Contains(string(resp), message) - return nil - } - - var depositsRes v1.QueryDepositsResponse - err = val.GetClientCtx().Codec.UnmarshalJSON(resp, &depositsRes) - s.Require().NoError(err) - - return &depositsRes -} - -func (s *DepositTestSuite) queryDeposit(val network.ValidatorI, proposalID string, exceptErr bool, message string) *v1.QueryDepositResponse { - s.Require().NoError(s.network.WaitForNextBlock()) - - resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals/%s/deposits/%s", val.GetAPIAddress(), proposalID, val.GetAddress().String())) - s.Require().NoError(err) - - if exceptErr { - s.Require().Contains(string(resp), message) - return nil - } - - var depositRes v1.QueryDepositResponse - err = val.GetClientCtx().Codec.UnmarshalJSON(resp, &depositRes) - s.Require().NoError(err) - - return &depositRes -} diff --git a/tests/e2e/gov/tx.go b/tests/e2e/gov/tx.go deleted file mode 100644 index 9d6f84ce15aa..000000000000 --- a/tests/e2e/gov/tx.go +++ /dev/null @@ -1,372 +0,0 @@ -package gov - -import ( - "encoding/base64" - "fmt" - - "github.com/cosmos/gogoproto/proto" - "github.com/stretchr/testify/suite" - - "cosmossdk.io/math" - "cosmossdk.io/x/gov/client/cli" - govclitestutil "cosmossdk.io/x/gov/client/testutil" - "cosmossdk.io/x/gov/types" - v1 "cosmossdk.io/x/gov/types/v1" - "cosmossdk.io/x/gov/types/v1beta1" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -) - -type E2ETestSuite struct { - suite.Suite - - cfg network.Config - network network.NetworkI -} - -func NewE2ETestSuite(cfg network.Config) *E2ETestSuite { - return &E2ETestSuite{cfg: cfg} -} - -func (s *E2ETestSuite) SetupSuite() { - s.T().Log("setting up e2e test suite") - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - val := s.network.GetValidators()[0] - clientCtx := val.GetClientCtx() - var resp sdk.TxResponse - - // create a proposal with deposit - out, err := govclitestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 1", "Where is the title!?", v1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens).String())) - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // vote for proposal - out, err = govclitestutil.MsgVote(val.GetClientCtx(), val.GetAddress().String(), "1", "yes") - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // create a proposal with a small deposit - minimumAcceptedDep := v1.DefaultMinDepositTokens.ToLegacyDec().Mul(v1.DefaultMinDepositRatio).Ceil().TruncateInt() - out, err = govclitestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 2", "Where is the title!?", v1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, minimumAcceptedDep).String())) - - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // create a proposal3 with deposit - out, err = govclitestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 3", "Where is the title!?", v1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens).String())) - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // create a proposal4 with deposit to check the cancel proposal cli tx - out, err = govclitestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 4", "Where is the title!?", v1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens).String())) - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // vote for proposal3 as val - out, err = govclitestutil.MsgVote(val.GetClientCtx(), val.GetAddress().String(), "3", "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05") - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) -} - -func (s *E2ETestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite") - s.network.Cleanup() -} - -func (s *E2ETestSuite) TestNewCmdSubmitProposal() { - val := s.network.GetValidators()[0] - - // Create a legacy proposal JSON, make sure it doesn't pass this new CLI - // command. - invalidProp := `{ - "title": "", - "description": "Where is the title!?", - "type": "Text", - "deposit": "-324foocoin" -}` - invalidPropFile := testutil.WriteToNewTempFile(s.T(), invalidProp) - defer invalidPropFile.Close() - - // Create a valid new proposal JSON. - propMetadata := []byte{42} - validProp := fmt.Sprintf(` -{ - "messages": [ - { - "@type": "/cosmos.gov.v1.MsgExecLegacyContent", - "authority": "%s", - "content": { - "@type": "/cosmos.gov.v1beta1.TextProposal", - "title": "My awesome title", - "description": "My awesome description" - } - } - ], - "title": "My awesome title", - "summary": "My awesome description", - "metadata": "%s", - "deposit": "%s" -}`, authtypes.NewModuleAddress(types.ModuleName), base64.StdEncoding.EncodeToString(propMetadata), sdk.NewCoin(s.cfg.BondDenom, math.NewInt(100000))) - validPropFile := testutil.WriteToNewTempFile(s.T(), validProp) - defer validPropFile.Close() - - testCases := []struct { - name string - args []string - expectErr bool - expectedCode uint32 - respType proto.Message - }{ - { - "invalid proposal", - []string{ - invalidPropFile.Name(), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, nil, - }, - { - "valid proposal", - []string{ - validPropFile.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdSubmitProposal() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - txResp := tc.respType.(*sdk.TxResponse) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode)) - } - }) - } -} - -func (s *E2ETestSuite) TestNewCmdSubmitLegacyProposal() { - val := s.network.GetValidators()[0] - invalidProp := `{ - "title": "", - "description": "Where is the title!?", - "type": "Text", - "deposit": "-324foocoin" - }` - invalidPropFile := testutil.WriteToNewTempFile(s.T(), invalidProp) - defer invalidPropFile.Close() - validProp := fmt.Sprintf(`{ - "title": "Text Proposal", - "description": "Hello, World!", - "type": "Text", - "deposit": "%s" - }`, sdk.NewCoin(s.cfg.BondDenom, math.NewInt(154310))) - validPropFile := testutil.WriteToNewTempFile(s.T(), validProp) - defer validPropFile.Close() - - testCases := []struct { - name string - args []string - expectErr bool - expectedCode uint32 - respType proto.Message - }{ - { - "invalid proposal (file)", - []string{ - fmt.Sprintf("--%s=%s", cli.FlagProposal, invalidPropFile.Name()), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, nil, - }, - { - "invalid proposal", - []string{ - fmt.Sprintf("--%s='Where is the title!?'", cli.FlagDescription), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", cli.FlagProposalType, v1beta1.ProposalTypeText), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10000)).String()), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, nil, - }, - { - "valid transaction (file)", - //nolint:staticcheck // we are intentionally using a deprecated flag here. - []string{ - fmt.Sprintf("--%s=%s", cli.FlagProposal, validPropFile.Name()), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - }, - { - "valid transaction", - []string{ - fmt.Sprintf("--%s='Text Proposal'", cli.FlagTitle), - fmt.Sprintf("--%s='Where is the title!?'", cli.FlagDescription), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", cli.FlagProposalType, v1beta1.ProposalTypeText), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, math.NewInt(100000)).String()), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdSubmitLegacyProposal() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - txResp := tc.respType.(*sdk.TxResponse) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode)) - } - }) - } -} - -func (s *E2ETestSuite) TestNewCmdWeightedVote() { - val := s.network.GetValidators()[0] - - testCases := []struct { - name string - args []string - expectErr bool - expectedCode uint32 - }{ - { - "invalid vote", - []string{}, - true, 0, - }, - { - "vote for invalid proposal", - []string{ - "10", - "yes", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 3, - }, - { - "valid vote", - []string{ - "1", - "yes", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, - }, - { - "valid vote with metadata", - []string{ - "1", - "yes", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--metadata=%s", "AQ=="), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, - }, - { - "invalid valid split vote string", - []string{ - "1", - "yes/0.6,no/0.3,abstain/0.05,no_with_veto/0.05", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, - }, - { - "valid split vote", - []string{ - "1", - "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdWeightedVote() - clientCtx := val.GetClientCtx() - var txResp sdk.TxResponse - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode)) - } - }) - } -} diff --git a/tests/go.mod b/tests/go.mod index a2af50c06077..bbc2a3c3e485 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 cosmossdk.io/log v1.4.1 cosmossdk.io/math v1.3.0 @@ -25,7 +25,7 @@ require ( github.com/golang/mock v1.6.0 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 gotest.tools/v3 v3.5.1 pgregory.net/rapid v1.1.0 @@ -65,7 +65,7 @@ require ( cloud.google.com/go/storage v1.43.0 // indirect cosmossdk.io/client/v2 v2.0.0-20230630094428-02b760776860 // indirect cosmossdk.io/errors v1.0.1 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/circuit v0.0.0-20230613133644-0a778132a60f // indirect cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -176,7 +176,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -210,7 +210,7 @@ require ( golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect @@ -220,7 +220,7 @@ require ( google.golang.org/api v0.192.0 // indirect google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/tests/go.sum b/tests/go.sum index a0ab6f8190ac..b2cfe1aa475e 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -192,8 +192,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -204,8 +204,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= @@ -722,8 +722,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -972,8 +972,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1327,8 +1327,8 @@ google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22du google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142/go.mod h1:G11eXq53iI5Q+kyNOmCvnzBaxEA2Q/Ik5Tj7nqBE8j4= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1364,8 +1364,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/tests/integration/gov/common_test.go b/tests/integration/gov/common_test.go index ced80fc6ad84..f84bbc81a857 100644 --- a/tests/integration/gov/common_test.go +++ b/tests/integration/gov/common_test.go @@ -34,7 +34,7 @@ import ( var ( valTokens = sdk.TokensFromConsensusPower(42, sdk.DefaultPowerReduction) TestProposal = v1beta1.NewTextProposal("Test", "description") - TestDescription = stakingtypes.NewDescription("T", "E", "S", "T", "Z") + TestDescription = stakingtypes.NewDescription("T", "E", "S", "T", "Z", stakingtypes.Metadata{}) TestCommissionRates = stakingtypes.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()) ) diff --git a/tests/integration/rapidgen/rapidgen.go b/tests/integration/rapidgen/rapidgen.go index e33e794b00f2..0060ca1976ce 100644 --- a/tests/integration/rapidgen/rapidgen.go +++ b/tests/integration/rapidgen/rapidgen.go @@ -222,7 +222,6 @@ var ( NonsignableTypes = []GeneratedType{ GenType(&authtypes.Params{}, &authapi.Params{}, GenOpts), GenType(&authtypes.BaseAccount{}, &authapi.BaseAccount{}, GenOpts.WithAnyTypes(&ed25519.PubKey{})), - GenType(&authtypes.ModuleAccount{}, &authapi.ModuleAccount{}, GenOpts.WithAnyTypes(&ed25519.PubKey{})), GenType(&authtypes.ModuleCredential{}, &authapi.ModuleCredential{}, GenOpts), GenType(&authztypes.GenericAuthorization{}, &authzapi.GenericAuthorization{}, GenOpts), @@ -260,7 +259,9 @@ var ( GenType(&slashingtypes.Params{}, &slashingapi.Params{}, GenOpts.WithDisallowNil()), - GenType(&stakingtypes.StakeAuthorization{}, &stakingapi.StakeAuthorization{}, GenOpts), + // JSON ordering of one of fields to be fixed in https://github.com/cosmos/cosmos-sdk/pull/21782 + // TODO uncomment once merged + // GenType(&stakingtypes.StakeAuthorization{}, &stakingapi.StakeAuthorization{}, GenOpts), GenType(&upgradetypes.CancelSoftwareUpgradeProposal{}, &upgradeapi.CancelSoftwareUpgradeProposal{}, GenOpts), //nolint:staticcheck // testing legacy code path GenType(&upgradetypes.SoftwareUpgradeProposal{}, &upgradeapi.SoftwareUpgradeProposal{}, GenOpts.WithDisallowNil()), //nolint:staticcheck // testing legacy code path diff --git a/tests/integration/slashing/slashing_test.go b/tests/integration/slashing/slashing_test.go index 60fc4f1e5ac6..6c60ce295b5d 100644 --- a/tests/integration/slashing/slashing_test.go +++ b/tests/integration/slashing/slashing_test.go @@ -83,7 +83,7 @@ func TestSlashingMsgs(t *testing.T) { require.NoError(t, err) - description := stakingtypes.NewDescription("foo_moniker", "", "", "", "") + description := stakingtypes.NewDescription("foo_moniker", "", "", "", "", stakingtypes.Metadata{}) commission := stakingtypes.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()) addrStrVal, err := valaddrCodec.BytesToString(addr1) diff --git a/tests/integration/staking/keeper/deterministic_test.go b/tests/integration/staking/keeper/deterministic_test.go index 4a15c7775a35..4b9afd591281 100644 --- a/tests/integration/staking/keeper/deterministic_test.go +++ b/tests/integration/staking/keeper/deterministic_test.go @@ -2,6 +2,8 @@ package keeper_test import ( "context" + "fmt" + "net/url" "testing" "time" @@ -214,6 +216,26 @@ func bondTypeGenerator() *rapid.Generator[stakingtypes.BondStatus] { }) } +func metadataGenerator() *rapid.Generator[stakingtypes.Metadata] { + return rapid.Custom(func(t *rapid.T) stakingtypes.Metadata { + return stakingtypes.Metadata{ + ProfilePicUri: generateUri(t), + SocialHandleUris: []string{generateUri(t), generateUri(t)}, + } + }) +} + +func generateUri(t *rapid.T) string { + host := fmt.Sprintf("%s.com", rapid.StringN(5, 250, 255).Draw(t, "host")) + path := rapid.StringN(5, 250, 255).Draw(t, "path") + uri := url.URL{ + Scheme: "https", + Host: host, + Path: path, + } + return uri.String() +} + // createValidator creates a validator with random values. func createValidator(t *testing.T, rt *rapid.T, _ *deterministicFixture) stakingtypes.Validator { t.Helper() @@ -233,6 +255,7 @@ func createValidator(t *testing.T, rt *rapid.T, _ *deterministicFixture) staking rapid.StringN(5, 250, 255).Draw(rt, "website"), rapid.StringN(5, 250, 255).Draw(rt, "securityContact"), rapid.StringN(5, 250, 255).Draw(rt, "details"), + metadataGenerator().Draw(rt, "metadata"), ), UnbondingHeight: rapid.Int64Min(1).Draw(rt, "unbonding-height"), UnbondingTime: time.Now().Add(durationGenerator().Draw(rt, "duration")), @@ -308,6 +331,7 @@ func getStaticValidator(t *testing.T, f *deterministicFixture) stakingtypes.Vali "website", "securityContact", "details", + stakingtypes.Metadata{}, ), UnbondingHeight: 10, UnbondingTime: time.Date(2022, 10, 1, 0, 0, 0, 0, time.UTC), @@ -343,6 +367,7 @@ func getStaticValidator2(t *testing.T, f *deterministicFixture) stakingtypes.Val "website", "securityContact", "details", + stakingtypes.Metadata{}, ), UnbondingHeight: 100132, UnbondingTime: time.Date(2025, 10, 1, 0, 0, 0, 0, time.UTC), @@ -408,7 +433,7 @@ func TestGRPCValidator(t *testing.T) { ValidatorAddr: val.OperatorAddress, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Validator, 1915, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Validator, 1921, false) } func TestGRPCValidators(t *testing.T) { @@ -434,7 +459,7 @@ func TestGRPCValidators(t *testing.T) { getStaticValidator(t, f) getStaticValidator2(t, f) - testdata.DeterministicIterations(t, f.ctx, &stakingtypes.QueryValidatorsRequest{}, f.queryClient.Validators, 2862, false) + testdata.DeterministicIterations(t, f.ctx, &stakingtypes.QueryValidatorsRequest{}, f.queryClient.Validators, 2880, false) } func TestGRPCValidatorDelegations(t *testing.T) { @@ -479,7 +504,7 @@ func TestGRPCValidatorDelegations(t *testing.T) { ValidatorAddr: validator.OperatorAddress, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.ValidatorDelegations, 14610, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.ValidatorDelegations, 14628, false) } func TestGRPCValidatorUnbondingDelegations(t *testing.T) { @@ -569,7 +594,7 @@ func TestGRPCDelegation(t *testing.T) { DelegatorAddr: delegator1, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Delegation, 4680, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Delegation, 4686, false) } func TestGRPCUnbondingDelegation(t *testing.T) { @@ -652,7 +677,7 @@ func TestGRPCDelegatorDelegations(t *testing.T) { DelegatorAddr: delegator1, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorDelegations, 4283, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorDelegations, 4289, false) } func TestGRPCDelegatorValidator(t *testing.T) { @@ -690,7 +715,7 @@ func TestGRPCDelegatorValidator(t *testing.T) { ValidatorAddr: validator.OperatorAddress, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorValidator, 3563, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorValidator, 3569, false) } func TestGRPCDelegatorUnbondingDelegations(t *testing.T) { @@ -772,7 +797,7 @@ func TestGRPCDelegatorValidators(t *testing.T) { assert.NilError(t, err) req := &stakingtypes.QueryDelegatorValidatorsRequest{DelegatorAddr: delegator1} - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorValidators, 3166, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorValidators, 3172, false) } func TestGRPCPool(t *testing.T) { @@ -856,7 +881,7 @@ func TestGRPCRedelegations(t *testing.T) { DstValidatorAddr: validator2, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Redelegations, 3920, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Redelegations, 3926, false) } func TestGRPCParams(t *testing.T) { diff --git a/tests/integration/staking/keeper/genesis_test.go b/tests/integration/staking/keeper/genesis_test.go index 95e34da18485..da9fd6c5d660 100644 --- a/tests/integration/staking/keeper/genesis_test.go +++ b/tests/integration/staking/keeper/genesis_test.go @@ -41,7 +41,7 @@ func TestInitGenesis(t *testing.T) { Status: types.Bonded, Tokens: valTokens, DelegatorShares: math.LegacyNewDecFromInt(valTokens), - Description: types.NewDescription("hoop", "", "", "", ""), + Description: types.NewDescription("hoop", "", "", "", "", types.Metadata{}), } assert.NilError(t, f.stakingKeeper.SetValidator(f.sdkCtx, bondedVal)) @@ -67,7 +67,7 @@ func TestInitGenesis(t *testing.T) { Status: types.Bonded, Tokens: valTokens, DelegatorShares: math.LegacyNewDecFromInt(valTokens), - Description: types.NewDescription("hoop", "", "", "", ""), + Description: types.NewDescription("hoop", "", "", "", "", types.Metadata{}), } bondedVal2 := types.Validator{ OperatorAddress: sdk.ValAddress(addrs[2]).String(), @@ -75,7 +75,7 @@ func TestInitGenesis(t *testing.T) { Status: types.Bonded, Tokens: valTokens, DelegatorShares: math.LegacyNewDecFromInt(valTokens), - Description: types.NewDescription("bloop", "", "", "", ""), + Description: types.NewDescription("bloop", "", "", "", "", types.Metadata{}), } // append new bonded validators to the list @@ -148,7 +148,7 @@ func TestInitGenesis_PoolsBalanceMismatch(t *testing.T) { Jailed: false, Tokens: math.NewInt(10), DelegatorShares: math.LegacyNewDecFromInt(math.NewInt(10)), - Description: types.NewDescription("bloop", "", "", "", ""), + Description: types.NewDescription("bloop", "", "", "", "", types.Metadata{}), } params := types.Params{ @@ -195,7 +195,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { validators[i], err = types.NewValidator( sdk.ValAddress(addrs[i]).String(), PKs[i], - types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""), + types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", "", types.Metadata{}), ) assert.NilError(t, err) validators[i].Status = types.Bonded diff --git a/tests/integration/staking/keeper/msg_server_test.go b/tests/integration/staking/keeper/msg_server_test.go index 7eb00bb97a97..f07308591a84 100644 --- a/tests/integration/staking/keeper/msg_server_test.go +++ b/tests/integration/staking/keeper/msg_server_test.go @@ -44,7 +44,7 @@ func TestCancelUnbondingDelegation(t *testing.T) { delegatorAddr := addrs[1] // setup a new validator with bonded status - validator, err := types.NewValidator(valAddr.String(), PKs[0], types.NewDescription("Validator", "", "", "", "")) + validator, err := types.NewValidator(valAddr.String(), PKs[0], types.NewDescription("Validator", "", "", "", "", types.Metadata{})) validator.Status = types.Bonded assert.NilError(t, err) assert.NilError(t, f.stakingKeeper.SetValidator(ctx, validator)) diff --git a/tests/integration/tx/aminojson/aminojson_test.go b/tests/integration/tx/aminojson/aminojson_test.go index ec218ca47da3..cf9695b4b451 100644 --- a/tests/integration/tx/aminojson/aminojson_test.go +++ b/tests/integration/tx/aminojson/aminojson_test.go @@ -1,10 +1,9 @@ package aminojson import ( - "context" + "bytes" "fmt" - "reflect" - "strings" + stdmath "math" "testing" "time" @@ -12,26 +11,12 @@ import ( gogoproto "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/timestamppb" "pgregory.net/rapid" authapi "cosmossdk.io/api/cosmos/auth/v1beta1" - authzapi "cosmossdk.io/api/cosmos/authz/v1beta1" bankapi "cosmossdk.io/api/cosmos/bank/v1beta1" v1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" - "cosmossdk.io/api/cosmos/crypto/ed25519" - multisigapi "cosmossdk.io/api/cosmos/crypto/multisig" - "cosmossdk.io/api/cosmos/crypto/secp256k1" - distapi "cosmossdk.io/api/cosmos/distribution/v1beta1" - gov_v1_api "cosmossdk.io/api/cosmos/gov/v1" - gov_v1beta1_api "cosmossdk.io/api/cosmos/gov/v1beta1" msgv1 "cosmossdk.io/api/cosmos/msg/v1" - slashingapi "cosmossdk.io/api/cosmos/slashing/v1beta1" - stakingapi "cosmossdk.io/api/cosmos/staking/v1beta1" - txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1" - vestingapi "cosmossdk.io/api/cosmos/vesting/v1beta1" "cosmossdk.io/math" authztypes "cosmossdk.io/x/authz" authzmodule "cosmossdk.io/x/authz/module" @@ -52,7 +37,6 @@ import ( "cosmossdk.io/x/staking" stakingtypes "cosmossdk.io/x/staking/types" "cosmossdk.io/x/tx/signing/aminojson" - signing_testutil "cosmossdk.io/x/tx/signing/testutil" "cosmossdk.io/x/upgrade" codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" @@ -61,17 +45,13 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" secp256k1types "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/tests/integration/rapidgen" + "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal" gogo_testpb "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal/gogo/testpb" - pulsar_testpb "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal/pulsar/testpb" "github.com/cosmos/cosmos-sdk/testutil/testdata" "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/bech32" "github.com/cosmos/cosmos-sdk/types/module/testutil" - signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" - "github.com/cosmos/cosmos-sdk/x/auth/signing" - "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/auth/vesting" vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" @@ -92,13 +72,23 @@ import ( // In order for step 3 to work certain restrictions on the data generated in step 1 must be enforced and are described // by the mutation of genOpts passed to the generator. func TestAminoJSON_Equivalence(t *testing.T) { - encCfg := testutil.MakeTestEncodingConfig( - codectestutil.CodecOptions{}, auth.AppModule{}, authzmodule.AppModule{}, bank.AppModule{}, - consensus.AppModule{}, distribution.AppModule{}, evidence.AppModule{}, feegrantmodule.AppModule{}, - gov.AppModule{}, groupmodule.AppModule{}, mint.AppModule{}, - slashing.AppModule{}, staking.AppModule{}, upgrade.AppModule{}, vesting.AppModule{}) - legacytx.RegressionTestingAminoCodec = encCfg.Amino - aj := aminojson.NewEncoder(aminojson.EncoderOptions{DoNotSortFields: true}) + fixture := internal.NewSigningFixture(t, internal.SigningFixtureOptions{}, + auth.AppModule{}, + authzmodule.AppModule{}, + bank.AppModule{}, + consensus.AppModule{}, + distribution.AppModule{}, + evidence.AppModule{}, + feegrantmodule.AppModule{}, + gov.AppModule{}, + groupmodule.AppModule{}, + mint.AppModule{}, + slashing.AppModule{}, + staking.AppModule{}, + upgrade.AppModule{}, + vesting.AppModule{}, + ) + aj := aminojson.NewEncoder(aminojson.EncoderOptions{}) for _, tt := range rapidgen.DefaultGeneratedTypes { desc := tt.Pulsar.ProtoReflect().Descriptor() @@ -106,7 +96,7 @@ func TestAminoJSON_Equivalence(t *testing.T) { t.Run(name, func(t *testing.T) { gen := rapidproto.MessageGenerator(tt.Pulsar, tt.Opts) fmt.Printf("testing %s\n", tt.Pulsar.ProtoReflect().Descriptor().FullName()) - rapid.Check(t, func(t *rapid.T) { + rapid.Check(t, func(r *rapid.T) { // uncomment to debug; catch a panic and inspect application state // defer func() { // if r := recover(); r != nil { @@ -115,39 +105,28 @@ func TestAminoJSON_Equivalence(t *testing.T) { // } // }() - msg := gen.Draw(t, "msg") + msg := gen.Draw(r, "msg") postFixPulsarMessage(msg) - // txBuilder.GetTx will fail if the msg has no signers - // so it does not make sense to run these cases, apparently. - signers, err := encCfg.TxConfig.SigningContext().GetSigners(msg) - if len(signers) == 0 { - // skip - return - } - if err != nil { - if strings.Contains(err.Error(), "empty address string is not allowed") { - return - } - require.NoError(t, err) - } gogo := tt.Gogo sanity := tt.Pulsar protoBz, err := proto.Marshal(msg) - require.NoError(t, err) + require.NoError(r, err) err = proto.Unmarshal(protoBz, sanity) - require.NoError(t, err) + require.NoError(r, err) - err = encCfg.Codec.Unmarshal(protoBz, gogo) - require.NoError(t, err) + err = fixture.UnmarshalGogoProto(protoBz, gogo) + require.NoError(r, err) - legacyAminoJSON, err := encCfg.Amino.MarshalJSON(gogo) - require.NoError(t, err) + legacyAminoJSON := fixture.MarshalLegacyAminoJSON(t, gogo) aminoJSON, err := aj.Marshal(msg) - require.NoError(t, err) - require.Equal(t, string(legacyAminoJSON), string(aminoJSON)) + require.NoError(r, err) + if !bytes.Equal(legacyAminoJSON, aminoJSON) { + require.Failf(r, "JSON mismatch", "legacy: %s\n x/tx: %s\n", + string(legacyAminoJSON), string(aminoJSON)) + } // test amino json signer handler equivalence if !proto.HasExtension(desc.Options(), msgv1.E_Signer) { @@ -155,366 +134,240 @@ func TestAminoJSON_Equivalence(t *testing.T) { return } - handlerOptions := signing_testutil.HandlerArgumentOptions{ - ChainID: "test-chain", - Memo: "sometestmemo", - Msg: tt.Pulsar, - AccNum: 1, - AccSeq: 2, - SignerAddress: "signerAddress", - Fee: &txv1beta1.Fee{ - Amount: []*v1beta1.Coin{{Denom: "uatom", Amount: "1000"}}, - }, - } - - signerData, txData, err := signing_testutil.MakeHandlerArguments(handlerOptions) - require.NoError(t, err) - - handler := aminojson.NewSignModeHandler(aminojson.SignModeHandlerOptions{}) - signBz, err := handler.GetSignBytes(context.Background(), signerData, txData) - require.NoError(t, err) - - legacyHandler := tx.NewSignModeLegacyAminoJSONHandler() - txBuilder := encCfg.TxConfig.NewTxBuilder() - require.NoError(t, txBuilder.SetMsgs([]types.Msg{tt.Gogo}...)) - txBuilder.SetMemo(handlerOptions.Memo) - txBuilder.SetFeeAmount(types.Coins{types.NewInt64Coin("uatom", 1000)}) - theTx := txBuilder.GetTx() - - legacySigningData := signing.SignerData{ - ChainID: handlerOptions.ChainID, - Address: handlerOptions.SignerAddress, - AccountNumber: handlerOptions.AccNum, - Sequence: handlerOptions.AccSeq, - } - legacySignBz, err := legacyHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - legacySigningData, theTx) - require.NoError(t, err) - require.Equal(t, string(legacySignBz), string(signBz)) + fixture.RequireLegacyAminoEquivalent(t, gogo) }) }) } } -func newAny(t *testing.T, msg proto.Message) *anypb.Any { - t.Helper() - bz, err := proto.Marshal(msg) - require.NoError(t, err) - typeName := fmt.Sprintf("/%s", msg.ProtoReflect().Descriptor().FullName()) - return &anypb.Any{ - TypeUrl: typeName, - Value: bz, - } -} - // TestAminoJSON_LegacyParity tests that the Encoder encoder produces the same output as the Encoder encoder. func TestAminoJSON_LegacyParity(t *testing.T) { - encCfg := testutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, auth.AppModule{}, authzmodule.AppModule{}, + fixture := internal.NewSigningFixture(t, internal.SigningFixtureOptions{}, + auth.AppModule{}, authzmodule.AppModule{}, bank.AppModule{}, distribution.AppModule{}, slashing.AppModule{}, staking.AppModule{}, vesting.AppModule{}, gov.AppModule{}) - legacytx.RegressionTestingAminoCodec = encCfg.Amino + aj := aminojson.NewEncoder(aminojson.EncoderOptions{}) - aj := aminojson.NewEncoder(aminojson.EncoderOptions{DoNotSortFields: true}) addr1 := types.AccAddress("addr1") now := time.Now() - genericAuth, _ := codectypes.NewAnyWithValue(&authztypes.GenericAuthorization{Msg: "foo"}) - genericAuthPulsar := newAny(t, &authzapi.GenericAuthorization{Msg: "foo"}) pubkeyAny, _ := codectypes.NewAnyWithValue(&secp256k1types.PubKey{Key: []byte("foo")}) - pubkeyAnyPulsar := newAny(t, &secp256k1.PubKey{Key: []byte("foo")}) - dec10bz, _ := math.LegacyNewDec(10).Marshal() - int123bz, _ := math.NewInt(123).Marshal() + dec5point4 := math.LegacyMustNewDecFromStr("5.4") + failingBaseAccount := authtypes.NewBaseAccountWithAddress(addr1) + failingBaseAccount.AccountNumber = stdmath.MaxUint64 cases := map[string]struct { - gogo gogoproto.Message - pulsar proto.Message - pulsarMarshalFails bool - - // this will fail in cases where a lossy encoding of an empty array to protobuf occurs. the unmarshalled bytes - // represent the array as nil, and a subsequent marshal to JSON represent the array as null instead of empty. - roundTripUnequal bool - - // pulsar does not support marshaling a math.Dec as anything except a string. Therefore, we cannot unmarshal - // a pulsar encoded Math.dec (the string representation of a Decimal) into a gogo Math.dec (expecting an int64). - protoUnmarshalFails bool + gogo gogoproto.Message + fails bool }{ - "auth/params": {gogo: &authtypes.Params{TxSigLimit: 10}, pulsar: &authapi.Params{TxSigLimit: 10}}, - "auth/module_account": { + "auth/params": { + gogo: &authtypes.Params{TxSigLimit: 10}, + }, + "auth/module_account_nil_permissions": { gogo: &authtypes.ModuleAccount{ - BaseAccount: authtypes.NewBaseAccountWithAddress(addr1), Permissions: []string{}, + BaseAccount: authtypes.NewBaseAccountWithAddress( + addr1, + ), }, - pulsar: &authapi.ModuleAccount{ - BaseAccount: &authapi.BaseAccount{Address: addr1.String()}, Permissions: []string{}, + }, + "auth/module_account/max_uint64": { + gogo: &authtypes.ModuleAccount{ + BaseAccount: failingBaseAccount, }, - roundTripUnequal: true, + fails: true, + }, + "auth/module_account_empty_permissions": { + gogo: &authtypes.ModuleAccount{ + BaseAccount: authtypes.NewBaseAccountWithAddress( + addr1, + ), + // empty set and nil are indistinguishable from the protoreflect API since they both + // marshal to zero proto bytes, there empty set is not supported. + Permissions: []string{}, + }, + fails: true, }, "auth/base_account": { - gogo: &authtypes.BaseAccount{Address: addr1.String(), PubKey: pubkeyAny}, - pulsar: &authapi.BaseAccount{Address: addr1.String(), PubKey: pubkeyAnyPulsar}, + gogo: &authtypes.BaseAccount{Address: addr1.String(), PubKey: pubkeyAny, AccountNumber: 1, Sequence: 2}, }, "authz/msg_grant": { gogo: &authztypes.MsgGrant{ + Granter: addr1.String(), Grantee: addr1.String(), Grant: authztypes.Grant{Expiration: &now, Authorization: genericAuth}, }, - pulsar: &authzapi.MsgGrant{ - Grant: &authzapi.Grant{Expiration: timestamppb.New(now), Authorization: genericAuthPulsar}, - }, }, "authz/msg_update_params": { - gogo: &authtypes.MsgUpdateParams{Params: authtypes.Params{TxSigLimit: 10}}, - pulsar: &authapi.MsgUpdateParams{Params: &authapi.Params{TxSigLimit: 10}}, + gogo: &authtypes.MsgUpdateParams{Params: authtypes.Params{TxSigLimit: 10}}, }, "authz/msg_exec/empty_msgs": { - gogo: &authztypes.MsgExec{Msgs: []*codectypes.Any{}}, - pulsar: &authzapi.MsgExec{Msgs: []*anypb.Any{}}, + gogo: &authztypes.MsgExec{Msgs: []*codectypes.Any{}}, }, "distribution/delegator_starting_info": { - gogo: &disttypes.DelegatorStartingInfo{}, - pulsar: &distapi.DelegatorStartingInfo{}, + gogo: &disttypes.DelegatorStartingInfo{Stake: math.LegacyNewDec(10)}, }, "distribution/delegator_starting_info/non_zero_dec": { - gogo: &disttypes.DelegatorStartingInfo{Stake: math.LegacyNewDec(10)}, - pulsar: &distapi.DelegatorStartingInfo{Stake: "10.000000000000000000"}, - protoUnmarshalFails: true, + gogo: &disttypes.DelegatorStartingInfo{Stake: math.LegacyNewDec(10)}, }, "distribution/delegation_delegator_reward": { - gogo: &disttypes.DelegationDelegatorReward{}, - pulsar: &distapi.DelegationDelegatorReward{}, + gogo: &disttypes.DelegationDelegatorReward{}, }, "distribution/msg_withdraw_delegator_reward": { - gogo: &disttypes.MsgWithdrawDelegatorReward{DelegatorAddress: "foo"}, - pulsar: &distapi.MsgWithdrawDelegatorReward{DelegatorAddress: "foo"}, + gogo: &disttypes.MsgWithdrawDelegatorReward{DelegatorAddress: "foo"}, }, "crypto/ed25519": { - gogo: &ed25519types.PubKey{Key: []byte("key")}, - pulsar: &ed25519.PubKey{Key: []byte("key")}, + gogo: &ed25519types.PubKey{Key: []byte("key")}, }, "crypto/secp256k1": { - gogo: &secp256k1types.PubKey{Key: []byte("key")}, - pulsar: &secp256k1.PubKey{Key: []byte("key")}, + gogo: &secp256k1types.PubKey{Key: []byte("key")}, }, "crypto/legacy_amino_pubkey": { - gogo: &multisig.LegacyAminoPubKey{PubKeys: []*codectypes.Any{pubkeyAny}}, - pulsar: &multisigapi.LegacyAminoPubKey{PublicKeys: []*anypb.Any{pubkeyAnyPulsar}}, + gogo: &multisig.LegacyAminoPubKey{PubKeys: []*codectypes.Any{pubkeyAny}}, }, - "crypto/legacy_amino_pubkey/empty": { - gogo: &multisig.LegacyAminoPubKey{}, - pulsar: &multisigapi.LegacyAminoPubKey{}, + "crypto/legacy_amino_pubkey_empty": { + gogo: &multisig.LegacyAminoPubKey{}, }, "consensus/evidence_params/duration": { - gogo: &gov_v1beta1_types.VotingParams{VotingPeriod: 1e9 + 7}, - pulsar: &gov_v1beta1_api.VotingParams{VotingPeriod: &durationpb.Duration{Seconds: 1, Nanos: 7}}, + gogo: &gov_v1beta1_types.VotingParams{VotingPeriod: 1e9 + 7}, }, "consensus/evidence_params/big_duration": { - gogo: &gov_v1beta1_types.VotingParams{VotingPeriod: time.Duration(rapidproto.MaxDurationSeconds*1e9) + 999999999}, - pulsar: &gov_v1beta1_api.VotingParams{VotingPeriod: &durationpb.Duration{ - Seconds: rapidproto.MaxDurationSeconds, Nanos: 999999999, - }}, + gogo: &gov_v1beta1_types.VotingParams{ + VotingPeriod: time.Duration(rapidproto.MaxDurationSeconds*1e9) + 999999999, + }, }, "consensus/evidence_params/too_big_duration": { - gogo: &gov_v1beta1_types.VotingParams{VotingPeriod: time.Duration(rapidproto.MaxDurationSeconds*1e9) + 999999999}, - pulsar: &gov_v1beta1_api.VotingParams{VotingPeriod: &durationpb.Duration{ - Seconds: rapidproto.MaxDurationSeconds + 1, Nanos: 999999999, - }}, - pulsarMarshalFails: true, + gogo: &gov_v1beta1_types.VotingParams{ + VotingPeriod: time.Duration(rapidproto.MaxDurationSeconds*1e9) + 999999999, + }, }, // amino.dont_omitempty + empty/nil lists produce some surprising results "bank/send_authorization/empty_coins": { - gogo: &banktypes.SendAuthorization{SpendLimit: []types.Coin{}}, - pulsar: &bankapi.SendAuthorization{SpendLimit: []*v1beta1.Coin{}}, + gogo: &banktypes.SendAuthorization{SpendLimit: []types.Coin{}}, }, "bank/send_authorization/nil_coins": { - gogo: &banktypes.SendAuthorization{SpendLimit: nil}, - pulsar: &bankapi.SendAuthorization{SpendLimit: nil}, + gogo: &banktypes.SendAuthorization{SpendLimit: nil}, }, "bank/send_authorization/empty_list": { - gogo: &banktypes.SendAuthorization{AllowList: []string{}}, - pulsar: &bankapi.SendAuthorization{AllowList: []string{}}, + gogo: &banktypes.SendAuthorization{AllowList: []string{}}, }, "bank/send_authorization/nil_list": { - gogo: &banktypes.SendAuthorization{AllowList: nil}, - pulsar: &bankapi.SendAuthorization{AllowList: nil}, + gogo: &banktypes.SendAuthorization{AllowList: nil}, }, "bank/msg_multi_send/nil_everything": { - gogo: &banktypes.MsgMultiSend{}, - pulsar: &bankapi.MsgMultiSend{}, + gogo: &banktypes.MsgMultiSend{}, }, "gov/v1_msg_submit_proposal": { - gogo: &gov_v1_types.MsgSubmitProposal{}, - pulsar: &gov_v1_api.MsgSubmitProposal{}, + gogo: &gov_v1_types.MsgSubmitProposal{}, }, - "slashing/params/empty_dec": { - gogo: &slashingtypes.Params{DowntimeJailDuration: 1e9 + 7}, - pulsar: &slashingapi.Params{DowntimeJailDuration: &durationpb.Duration{Seconds: 1, Nanos: 7}}, - }, - // This test cases demonstrates the expected contract and proper way to set a cosmos.Dec field represented - // as bytes in protobuf message, namely: - // dec10bz, _ := types.NewDec(10).Marshal() "slashing/params/dec": { gogo: &slashingtypes.Params{ - DowntimeJailDuration: 1e9 + 7, - MinSignedPerWindow: math.LegacyNewDec(10), - }, - pulsar: &slashingapi.Params{ - DowntimeJailDuration: &durationpb.Duration{Seconds: 1, Nanos: 7}, - MinSignedPerWindow: dec10bz, + DowntimeJailDuration: 1e9 + 7, + MinSignedPerWindow: math.LegacyNewDec(10), + SlashFractionDoubleSign: math.LegacyZeroDec(), + SlashFractionDowntime: math.LegacyZeroDec(), }, }, "staking/msg_update_params": { gogo: &stakingtypes.MsgUpdateParams{ Params: stakingtypes.Params{ - UnbondingTime: 0, - KeyRotationFee: types.Coin{}, - }, - }, - pulsar: &stakingapi.MsgUpdateParams{ - Params: &stakingapi.Params{ - UnbondingTime: &durationpb.Duration{Seconds: 0}, - KeyRotationFee: &v1beta1.Coin{}, + UnbondingTime: 0, + KeyRotationFee: types.Coin{}, + MinCommissionRate: math.LegacyZeroDec(), }, }, }, "staking/create_validator": { - gogo: &stakingtypes.MsgCreateValidator{Pubkey: pubkeyAny}, - pulsar: &stakingapi.MsgCreateValidator{ - Pubkey: pubkeyAnyPulsar, - Description: &stakingapi.Description{}, - Commission: &stakingapi.CommissionRates{}, - Value: &v1beta1.Coin{}, + gogo: &stakingtypes.MsgCreateValidator{ + Pubkey: pubkeyAny, + Commission: stakingtypes.CommissionRates{ + Rate: dec5point4, + MaxRate: math.LegacyZeroDec(), + MaxChangeRate: math.LegacyZeroDec(), + }, + MinSelfDelegation: math.NewIntFromUint64(10), }, }, "staking/msg_cancel_unbonding_delegation_response": { - gogo: &stakingtypes.MsgCancelUnbondingDelegationResponse{}, - pulsar: &stakingapi.MsgCancelUnbondingDelegationResponse{}, + gogo: &stakingtypes.MsgCancelUnbondingDelegationResponse{}, }, "staking/stake_authorization_empty": { - gogo: &stakingtypes.StakeAuthorization{}, - pulsar: &stakingapi.StakeAuthorization{}, + gogo: &stakingtypes.StakeAuthorization{}, }, "staking/stake_authorization_allow": { gogo: &stakingtypes.StakeAuthorization{ + MaxTokens: &types.Coin{Denom: "foo", Amount: math.NewInt(123)}, Validators: &stakingtypes.StakeAuthorization_AllowList{ - AllowList: &stakingtypes.StakeAuthorization_Validators{Address: []string{"foo"}}, + AllowList: &stakingtypes.StakeAuthorization_Validators{ + Address: []string{"foo"}, + }, }, + AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, }, - pulsar: &stakingapi.StakeAuthorization{ - Validators: &stakingapi.StakeAuthorization_AllowList{ - AllowList: &stakingapi.StakeAuthorization_Validators{Address: []string{"foo"}}, + }, + "staking/stake_authorization_deny": { + gogo: &stakingtypes.StakeAuthorization{ + MaxTokens: &types.Coin{Denom: "foo", Amount: math.NewInt(123)}, + Validators: &stakingtypes.StakeAuthorization_DenyList{ + DenyList: &stakingtypes.StakeAuthorization_Validators{}, }, + AuthorizationType: stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE, }, + // to be fixed in https://github.com/cosmos/cosmos-sdk/pull/21782 + // TODO remove once merged + fails: true, }, "vesting/base_account_empty": { - gogo: &vestingtypes.BaseVestingAccount{BaseAccount: &authtypes.BaseAccount{}}, - pulsar: &vestingapi.BaseVestingAccount{BaseAccount: &authapi.BaseAccount{}}, + gogo: &vestingtypes.BaseVestingAccount{BaseAccount: &authtypes.BaseAccount{}}, }, "vesting/base_account_pubkey": { - gogo: &vestingtypes.BaseVestingAccount{BaseAccount: &authtypes.BaseAccount{PubKey: pubkeyAny}}, - pulsar: &vestingapi.BaseVestingAccount{BaseAccount: &authapi.BaseAccount{PubKey: pubkeyAnyPulsar}}, + gogo: &vestingtypes.BaseVestingAccount{ + BaseAccount: &authtypes.BaseAccount{PubKey: pubkeyAny}, + }, }, "math/int_as_string": { - gogo: &gogo_testpb.IntAsString{IntAsString: math.NewInt(123)}, - pulsar: &pulsar_testpb.IntAsString{IntAsString: "123"}, + gogo: &gogo_testpb.IntAsString{IntAsString: math.NewInt(123)}, }, "math/int_as_string/empty": { - gogo: &gogo_testpb.IntAsString{}, - pulsar: &pulsar_testpb.IntAsString{}, + gogo: &gogo_testpb.IntAsString{}, }, "math/int_as_bytes": { - gogo: &gogo_testpb.IntAsBytes{IntAsBytes: math.NewInt(123)}, - pulsar: &pulsar_testpb.IntAsBytes{IntAsBytes: int123bz}, + gogo: &gogo_testpb.IntAsBytes{IntAsBytes: math.NewInt(123)}, }, "math/int_as_bytes/empty": { - gogo: &gogo_testpb.IntAsBytes{}, - pulsar: &pulsar_testpb.IntAsBytes{}, + gogo: &gogo_testpb.IntAsBytes{}, }, } for name, tc := range cases { t.Run(name, func(t *testing.T) { - gogoBytes, err := encCfg.Amino.MarshalJSON(tc.gogo) - require.NoError(t, err) - - pulsarBytes, err := aj.Marshal(tc.pulsar) - if tc.pulsarMarshalFails { - require.Error(t, err) - return - } - require.NoError(t, err) - - fmt.Printf("pulsar: %s\n", string(pulsarBytes)) - fmt.Printf(" gogo: %s\n", string(gogoBytes)) - require.Equal(t, string(gogoBytes), string(pulsarBytes)) - - pulsarProtoBytes, err := proto.Marshal(tc.pulsar) - require.NoError(t, err) - - gogoType := reflect.TypeOf(tc.gogo).Elem() - newGogo := reflect.New(gogoType).Interface().(gogoproto.Message) - - err = encCfg.Codec.Unmarshal(pulsarProtoBytes, newGogo) - if tc.protoUnmarshalFails { - require.Error(t, err) - return - } + legacyBytes := fixture.MarshalLegacyAminoJSON(t, tc.gogo) + dynamicBytes, err := aj.Marshal(fixture.DynamicMessage(t, tc.gogo)) require.NoError(t, err) - newGogoBytes, err := encCfg.Amino.MarshalJSON(newGogo) - require.NoError(t, err) - if tc.roundTripUnequal { - require.NotEqual(t, string(gogoBytes), string(newGogoBytes)) + t.Logf("legacy: %s\n", string(legacyBytes)) + t.Logf(" sut: %s\n", string(dynamicBytes)) + if tc.fails { + require.NotEqual(t, string(legacyBytes), string(dynamicBytes)) return } - require.Equal(t, string(gogoBytes), string(newGogoBytes)) + require.Equal(t, string(legacyBytes), string(dynamicBytes)) // test amino json signer handler equivalence - msg, ok := tc.gogo.(legacytx.LegacyMsg) - if !ok { + if !proto.HasExtension(fixture.MessageDescriptor(t, tc.gogo).Options(), msgv1.E_Signer) { // not signable return } - - handlerOptions := signing_testutil.HandlerArgumentOptions{ - ChainID: "test-chain", - Memo: "sometestmemo", - Msg: tc.pulsar, - AccNum: 1, - AccSeq: 2, - SignerAddress: "signerAddress", - Fee: &txv1beta1.Fee{ - Amount: []*v1beta1.Coin{{Denom: "uatom", Amount: "1000"}}, - }, - } - - signerData, txData, err := signing_testutil.MakeHandlerArguments(handlerOptions) - require.NoError(t, err) - - handler := aminojson.NewSignModeHandler(aminojson.SignModeHandlerOptions{}) - signBz, err := handler.GetSignBytes(context.Background(), signerData, txData) - require.NoError(t, err) - - legacyHandler := tx.NewSignModeLegacyAminoJSONHandler() - txBuilder := encCfg.TxConfig.NewTxBuilder() - require.NoError(t, txBuilder.SetMsgs([]types.Msg{msg}...)) - txBuilder.SetMemo(handlerOptions.Memo) - txBuilder.SetFeeAmount(types.Coins{types.NewInt64Coin("uatom", 1000)}) - theTx := txBuilder.GetTx() - - legacySigningData := signing.SignerData{ - ChainID: handlerOptions.ChainID, - Address: handlerOptions.SignerAddress, - AccountNumber: handlerOptions.AccNum, - Sequence: handlerOptions.AccSeq, - } - legacySignBz, err := legacyHandler.GetSignBytes(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, - legacySigningData, theTx) - require.NoError(t, err) - require.Equal(t, string(legacySignBz), string(signBz)) + fixture.RequireLegacyAminoEquivalent(t, tc.gogo) }) } } func TestSendAuthorization(t *testing.T) { - encCfg := testutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, auth.AppModule{}, authzmodule.AppModule{}, - distribution.AppModule{}, bank.AppModule{}) + encCfg := testutil.MakeTestEncodingConfig( + codectestutil.CodecOptions{}, + auth.AppModule{}, + authzmodule.AppModule{}, + distribution.AppModule{}, + bank.AppModule{}, + ) aj := aminojson.NewEncoder(aminojson.EncoderOptions{}) diff --git a/tests/integration/tx/context_test.go b/tests/integration/tx/context_test.go index ffe21c2053cb..08124b79e3e6 100644 --- a/tests/integration/tx/context_test.go +++ b/tests/integration/tx/context_test.go @@ -3,30 +3,20 @@ package tx import ( "testing" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - "cosmossdk.io/depinject" "cosmossdk.io/log" _ "cosmossdk.io/x/accounts" "cosmossdk.io/x/tx/signing" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal" "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal/pulsar/testpb" "github.com/cosmos/cosmos-sdk/testutil/configurator" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + "github.com/stretchr/testify/require" ) -func ProvideCustomGetSigners() signing.CustomGetSigner { - return signing.CustomGetSigner{ - MsgType: proto.MessageName(&testpb.TestRepeatedFields{}), - Fn: func(msg proto.Message) ([][]byte, error) { - testMsg := msg.(*testpb.TestRepeatedFields) - // arbitrary logic - signer := testMsg.NullableDontOmitempty[1].Value - return [][]byte{[]byte(signer)}, nil - }, - } +func ProvideCustomGetSigner() signing.CustomGetSigner { + return internal.TestRepeatedFieldsSigner } func TestDefineCustomGetSigners(t *testing.T) { @@ -41,7 +31,7 @@ func TestDefineCustomGetSigners(t *testing.T) { configurator.ConsensusModule(), ), depinject.Supply(log.NewNopLogger()), - depinject.Provide(ProvideCustomGetSigners), + depinject.Provide(ProvideCustomGetSigner), ), &interfaceRegistry, ) diff --git a/tests/integration/tx/internal/util.go b/tests/integration/tx/internal/util.go new file mode 100644 index 000000000000..e3f6a5828997 --- /dev/null +++ b/tests/integration/tx/internal/util.go @@ -0,0 +1,221 @@ +package internal + +import ( + "bytes" + "context" + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/types/dynamicpb" + + "cosmossdk.io/core/transaction" + "cosmossdk.io/x/tx/signing" + "cosmossdk.io/x/tx/signing/aminojson" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/std" + "github.com/cosmos/cosmos-sdk/tests/integration/tx/internal/pulsar/testpb" + "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + signingtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/cosmos/cosmos-sdk/x/auth/tx" + gogoproto "github.com/cosmos/gogoproto/proto" +) + +var TestRepeatedFieldsSigner = signing.CustomGetSigner{ + MsgType: proto.MessageName(&testpb.TestRepeatedFields{}), + Fn: func(msg proto.Message) ([][]byte, error) { + testMsg := msg.(*testpb.TestRepeatedFields) + // arbitrary logic + signer := testMsg.NullableDontOmitempty[1].Value + return [][]byte{[]byte(signer)}, nil + }, +} + +type noOpAddressCodec struct{} + +func (a noOpAddressCodec) StringToBytes(text string) ([]byte, error) { + return []byte(text), nil +} + +func (a noOpAddressCodec) BytesToString(bz []byte) (string, error) { + return string(bz), nil +} + +type SigningFixture struct { + txConfig client.TxConfig + legacy *codec.LegacyAmino + protoCodec *codec.ProtoCodec + options SigningFixtureOptions + registry codectypes.InterfaceRegistry +} + +type SigningFixtureOptions struct { + DoNotSortFields bool +} + +func NewSigningFixture( + t *testing.T, + options SigningFixtureOptions, + modules ...module.AppModule, +) *SigningFixture { + t.Helper() + // set up transaction and signing infra + addressCodec, valAddressCodec := noOpAddressCodec{}, noOpAddressCodec{} + customGetSigners := []signing.CustomGetSigner{TestRepeatedFieldsSigner} + interfaceRegistry, _, err := codec.ProvideInterfaceRegistry( + addressCodec, + valAddressCodec, + customGetSigners, + ) + require.NoError(t, err) + protoCodec := codec.ProvideProtoCodec(interfaceRegistry) + signingOptions := &signing.Options{ + FileResolver: interfaceRegistry, + AddressCodec: addressCodec, + ValidatorAddressCodec: valAddressCodec, + } + for _, customGetSigner := range customGetSigners { + signingOptions.DefineCustomGetSigners(customGetSigner.MsgType, customGetSigner.Fn) + } + txConfig, err := tx.NewTxConfigWithOptions( + protoCodec, + tx.ConfigOptions{ + EnabledSignModes: []signingtypes.SignMode{ + signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, + }, + SigningOptions: signingOptions, + }) + require.NoError(t, err) + + legacyAminoCodec := codec.NewLegacyAmino() + mb := module.NewManager(modules...) + std.RegisterLegacyAminoCodec(legacyAminoCodec) + std.RegisterInterfaces(interfaceRegistry) + mb.RegisterLegacyAminoCodec(legacyAminoCodec) + mb.RegisterInterfaces(interfaceRegistry) + + return &SigningFixture{ + txConfig: txConfig, + legacy: legacyAminoCodec, + options: options, + protoCodec: protoCodec, + registry: interfaceRegistry, + } +} + +func (s *SigningFixture) RequireLegacyAminoEquivalent(t *testing.T, msg transaction.Msg) { + t.Helper() + // create tx envelope + txBuilder := s.txConfig.NewTxBuilder() + err := txBuilder.SetMsgs([]types.Msg{msg}...) + require.NoError(t, err) + builtTx := txBuilder.GetTx() + + // round trip it to simulate application usage + txBz, err := s.txConfig.TxEncoder()(builtTx) + require.NoError(t, err) + theTx, err := s.txConfig.TxDecoder()(txBz) + require.NoError(t, err) + + // create signing envelope + signerData := signing.SignerData{ + Address: "sender-address", + ChainID: "test-chain", + AccountNumber: 0, + Sequence: 0, + } + adaptableTx, ok := theTx.(authsigning.V2AdaptableTx) + require.True(t, ok) + + legacytx.RegressionTestingAminoCodec = s.legacy + defer func() { + legacytx.RegressionTestingAminoCodec = nil + }() + legacyAminoSignHandler := tx.NewSignModeLegacyAminoJSONHandler() + legacyBz, err := legacyAminoSignHandler.GetSignBytes( + signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, + authsigning.SignerData{ + ChainID: signerData.ChainID, + Address: signerData.Address, + AccountNumber: signerData.AccountNumber, + Sequence: signerData.Sequence, + }, + theTx) + require.NoError(t, err) + + handler := aminojson.NewSignModeHandler(aminojson.SignModeHandlerOptions{}) + signBz, err := handler.GetSignBytes( + context.Background(), + signerData, + adaptableTx.GetSigningTxData(), + ) + require.NoError(t, err) + + require.Truef(t, + bytes.Equal(legacyBz, signBz), + "legacy: %s\n x/tx: %s", string(legacyBz), string(signBz)) +} + +func (s *SigningFixture) MarshalLegacyAminoJSON(t *testing.T, o any) []byte { + t.Helper() + bz, err := s.legacy.MarshalJSON(o) + require.NoError(t, err) + if s.options.DoNotSortFields { + return bz + } + sortedBz, err := sortJson(bz) + require.NoError(t, err) + return sortedBz +} + +func (s *SigningFixture) UnmarshalGogoProto(bz []byte, ptr transaction.Msg) error { + return s.protoCodec.Unmarshal(bz, ptr) +} + +func (s *SigningFixture) MessageDescriptor(t *testing.T, msg transaction.Msg) protoreflect.MessageDescriptor { + t.Helper() + typeName := gogoproto.MessageName(msg) + msgDesc, err := s.registry.FindDescriptorByName(protoreflect.FullName(typeName)) + require.NoError(t, err) + return msgDesc.(protoreflect.MessageDescriptor) +} + +// DynamicMessage is identical to the Decoder implementation in +// https://github.com/cosmos/cosmos-sdk/blob/6d2f6ff068c81c5783e01319beaa51c7dbb43edd/x/tx/decode/decode.go#L136 +// It is duplicated here to test dynamic message implementations specifically. +// The code path linked above is also covered in this package. +func (s *SigningFixture) DynamicMessage(t *testing.T, msg transaction.Msg) proto.Message { + t.Helper() + msgDesc := s.MessageDescriptor(t, msg) + protoBz, err := gogoproto.Marshal(msg) + require.NoError(t, err) + dynamicMsg := dynamicpb.NewMessageType(msgDesc).New().Interface() + err = proto.Unmarshal(protoBz, dynamicMsg) + require.NoError(t, err) + return dynamicMsg +} + +// sortJson sorts the JSON bytes by way of the side effect of unmarshalling and remarshalling +// the JSON using encoding/json. This hacky way of sorting JSON fields was used by the legacy +// amino JSON encoding x/auth/migrations/legacytx.StdSignBytes. It is used here ensure the x/tx +// JSON encoding is equivalent to the legacy amino JSON encoding. +func sortJson(bz []byte) ([]byte, error) { + var c any + err := json.Unmarshal(bz, &c) + if err != nil { + return nil, err + } + js, err := json.Marshal(c) + if err != nil { + return nil, err + } + return js, nil +} diff --git a/tests/systemtests/authz_test.go b/tests/systemtests/authz_test.go new file mode 100644 index 000000000000..da66aef5d267 --- /dev/null +++ b/tests/systemtests/authz_test.go @@ -0,0 +1,867 @@ +//go:build system_test + +package systemtests + +import ( + "fmt" + "net/http" + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" +) + +const ( + msgSendTypeURL = `/cosmos.bank.v1beta1.MsgSend` + msgDelegateTypeURL = `/cosmos.staking.v1beta1.MsgDelegate` + msgVoteTypeURL = `/cosmos.gov.v1.MsgVote` + msgUndelegateTypeURL = `/cosmos.staking.v1beta1.MsgUndelegate` + msgRedelegateTypeURL = `/cosmos.staking.v1beta1.MsgBeginRedelegate` + sendAuthzTypeURL = `/cosmos.bank.v1beta1.SendAuthorization` + genericAuthzTypeURL = `/cosmos.authz.v1beta1.GenericAuthorization` + testDenom = "stake" +) + +func TestAuthzGrantTxCmd(t *testing.T) { + // scenario: test authz grant command + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address which will be used as granter + granterAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, granterAddr) + + // add grantee keys which will be used for each valid transaction + grantee1Addr := cli.AddKey("grantee1") + grantee2Addr := cli.AddKey("grantee2") + require.NotEqual(t, granterAddr, grantee2Addr) + grantee3Addr := cli.AddKey("grantee3") + require.NotEqual(t, granterAddr, grantee3Addr) + grantee4Addr := cli.AddKey("grantee4") + require.NotEqual(t, granterAddr, grantee4Addr) + grantee5Addr := cli.AddKey("grantee5") + require.NotEqual(t, granterAddr, grantee5Addr) + grantee6Addr := cli.AddKey("grantee6") + require.NotEqual(t, granterAddr, grantee6Addr) + + sut.StartChain(t) + + // query validator operator address + rsp := cli.CustomQuery("q", "staking", "validators") + valOperAddr := gjson.Get(rsp, "validators.#.operator_address").Array()[0].String() + + grantCmdArgs := []string{"tx", "authz", "grant", "--from", granterAddr} + expirationTime := time.Now().Add(time.Hour).Unix() + + // test grant command + testCases := []struct { + name string + grantee string + cmdArgs []string + expErrMsg string + queryTx bool + }{ + { + "invalid authorization type", + grantee1Addr, + []string{"spend"}, + "invalid authorization type", + false, + }, + { + "send authorization without spend-limit", + grantee1Addr, + []string{"send"}, + "spend-limit should be greater than zero", + false, + }, + { + "generic authorization without msg type", + grantee1Addr, + []string{"generic"}, + "msg type cannot be empty", + true, + }, + { + "delegate authorization without allow or deny list", + grantee1Addr, + []string{"delegate"}, + "both allowed & deny list cannot be empty", + false, + }, + { + "delegate authorization with invalid allowed validator address", + grantee1Addr, + []string{"delegate", "--allowed-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "delegate authorization with invalid deny validator address", + grantee1Addr, + []string{"delegate", "--deny-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "unbond authorization without allow or deny list", + grantee1Addr, + []string{"unbond"}, + "both allowed & deny list cannot be empty", + false, + }, + { + "unbond authorization with invalid allowed validator address", + grantee1Addr, + []string{"unbond", "--allowed-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "unbond authorization with invalid deny validator address", + grantee1Addr, + []string{"unbond", "--deny-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "redelegate authorization without allow or deny list", + grantee1Addr, + []string{"redelegate"}, + "both allowed & deny list cannot be empty", + false, + }, + { + "redelegate authorization with invalid allowed validator address", + grantee1Addr, + []string{"redelegate", "--allowed-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "redelegate authorization with invalid deny validator address", + grantee1Addr, + []string{"redelegate", "--deny-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "valid send authorization", + grantee1Addr, + []string{"send", "--spend-limit=1000" + testDenom}, + "", + false, + }, + { + "valid send authorization with expiration", + grantee2Addr, + []string{"send", "--spend-limit=1000" + testDenom, fmt.Sprintf("--expiration=%d", expirationTime)}, + "", + false, + }, + { + "valid generic authorization", + grantee3Addr, + []string{"generic", "--msg-type=" + msgVoteTypeURL}, + "", + false, + }, + { + "valid delegate authorization", + grantee4Addr, + []string{"delegate", "--allowed-validators=" + valOperAddr}, + "", + false, + }, + { + "valid unbond authorization", + grantee5Addr, + []string{"unbond", "--deny-validators=" + valOperAddr}, + "", + false, + }, + { + "valid redelegate authorization", + grantee6Addr, + []string{"redelegate", "--allowed-validators=" + valOperAddr}, + "", + false, + }, + } + + grantsCount := 0 + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cmd := append(append(grantCmdArgs, tc.grantee), tc.cmdArgs...) + if tc.expErrMsg != "" { + if tc.queryTx { + rsp := cli.Run(cmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, tc.expErrMsg) + } else { + assertErr := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { + require.Len(t, gotOutputs, 1) + output := gotOutputs[0].(string) + require.Contains(t, output, tc.expErrMsg) + return false + } + _ = cli.WithRunErrorMatcher(assertErr).Run(cmd...) + } + return + } + rsp := cli.RunAndWait(cmd...) + RequireTxSuccess(t, rsp) + + // query granter-grantee grants + resp := cli.CustomQuery("q", "authz", "grants", granterAddr, tc.grantee) + grants := gjson.Get(resp, "grants").Array() + // check grants length equal to 1 to confirm grant created successfully + require.Len(t, grants, 1) + grantsCount++ + }) + } + + // query grants-by-granter + resp := cli.CustomQuery("q", "authz", "grants-by-granter", granterAddr) + grants := gjson.Get(resp, "grants").Array() + require.Len(t, grants, grantsCount) +} + +func TestAuthzExecSendAuthorization(t *testing.T) { + // scenario: test authz exec send authorization + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address which will be used as granter + granterAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, granterAddr) + + // add grantee keys which will be used for each valid transaction + granteeAddr := cli.AddKey("grantee") + require.NotEqual(t, granterAddr, granteeAddr) + allowedAddr := cli.AddKey("allowed") + require.NotEqual(t, granteeAddr, allowedAddr) + notAllowedAddr := cli.AddKey("notAllowed") + require.NotEqual(t, granteeAddr, notAllowedAddr) + newAccount := cli.AddKey("newAccount") + require.NotEqual(t, granteeAddr, newAccount) + + var initialAmount int64 = 10000000 + initialBalance := fmt.Sprintf("%d%s", initialAmount, testDenom) + sut.ModifyGenesisCLI(t, + []string{"genesis", "add-genesis-account", granteeAddr, initialBalance}, + []string{"genesis", "add-genesis-account", allowedAddr, initialBalance}, + []string{"genesis", "add-genesis-account", newAccount, initialBalance}, + ) + sut.StartChain(t) + + // query balances + granterBal := cli.QueryBalance(granterAddr, testDenom) + granteeBal := cli.QueryBalance(granteeAddr, testDenom) + require.Equal(t, initialAmount, granteeBal) + allowedAddrBal := cli.QueryBalance(allowedAddr, testDenom) + require.Equal(t, initialAmount, allowedAddrBal) + + var spendLimitAmount int64 = 1000 + expirationTime := time.Now().Add(time.Second * 10).Unix() + + // test exec send authorization + + // create send authorization grant + rsp := cli.RunAndWait("tx", "authz", "grant", granteeAddr, "send", + "--spend-limit="+fmt.Sprintf("%d%s", spendLimitAmount, testDenom), + "--allow-list="+allowedAddr, + "--expiration="+fmt.Sprintf("%d", expirationTime), + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + // reduce fees of above tx from granter balance + granterBal-- + + testCases := []struct { + name string + grantee string + toAddr string + amount int64 + expErrMsg string + }{ + { + "valid exec transaction", + granteeAddr, + allowedAddr, + 20, + "", + }, + { + "send to not allowed address", + granteeAddr, + notAllowedAddr, + 10, + "cannot send to", + }, + { + "amount greater than spend limit", + granteeAddr, + allowedAddr, + spendLimitAmount + 5, + "requested amount is more than spend limit", + }, + { + "no grant found", + newAccount, + granteeAddr, + 20, + "authorization not found", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // msg send + cmd := msgSendExec(t, granterAddr, tc.grantee, tc.toAddr, testDenom, tc.amount) + if tc.expErrMsg != "" { + rsp := cli.Run(cmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, tc.expErrMsg) + return + } + rsp := cli.RunAndWait(cmd...) + RequireTxSuccess(t, rsp) + + // check granter balance equals to granterBal - transferredAmount + expGranterBal := granterBal - tc.amount + require.Equal(t, expGranterBal, cli.QueryBalance(granterAddr, testDenom)) + granterBal = expGranterBal + + // check allowed addr balance equals to allowedAddrBal + transferredAmount + expAllowAddrBal := allowedAddrBal + tc.amount + require.Equal(t, expAllowAddrBal, cli.QueryBalance(allowedAddr, testDenom)) + allowedAddrBal = expAllowAddrBal + }) + } + + // test grant expiry + time.Sleep(time.Second * 10) + + execSendCmd := msgSendExec(t, granterAddr, granteeAddr, allowedAddr, testDenom, 10) + rsp = cli.Run(execSendCmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, "authorization not found") +} + +func TestAuthzExecGenericAuthorization(t *testing.T) { + // scenario: test authz exec generic authorization + // given a running chain + + cli, granterAddr, granteeAddr := setupChain(t) + + allowedAddr := cli.AddKey("allowedAddr") + require.NotEqual(t, granterAddr, allowedAddr) + + // query balances + granterBal := cli.QueryBalance(granterAddr, testDenom) + + expirationTime := time.Now().Add(time.Second * 5).Unix() + execSendCmd := msgSendExec(t, granterAddr, granteeAddr, allowedAddr, testDenom, 10) + + // create generic authorization grant + rsp := cli.RunAndWait("tx", "authz", "grant", granteeAddr, "generic", + "--msg-type="+msgSendTypeURL, + "--expiration="+fmt.Sprintf("%d", expirationTime), + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + granterBal-- + + rsp = cli.RunAndWait(execSendCmd...) + RequireTxSuccess(t, rsp) + // check granter balance equals to granterBal - transferredAmount + expGranterBal := granterBal - 10 + require.Equal(t, expGranterBal, cli.QueryBalance(granterAddr, testDenom)) + + time.Sleep(time.Second * 5) + + // check grants after expiration + resp := cli.CustomQuery("q", "authz", "grants", granterAddr, granteeAddr) + grants := gjson.Get(resp, "grants").Array() + require.Len(t, grants, 0) +} + +func TestAuthzExecDelegateAuthorization(t *testing.T) { + // scenario: test authz exec delegate authorization + // given a running chain + + cli, granterAddr, granteeAddr := setupChain(t) + + // query balances + granterBal := cli.QueryBalance(granterAddr, testDenom) + + // query validator operator address + rsp := cli.CustomQuery("q", "staking", "validators") + validators := gjson.Get(rsp, "validators.#.operator_address").Array() + require.GreaterOrEqual(t, len(validators), 2) + val1Addr := validators[0].String() + val2Addr := validators[1].String() + + var spendLimitAmount int64 = 1000 + require.Greater(t, granterBal, spendLimitAmount) + + rsp = cli.RunAndWait("tx", "authz", "grant", granteeAddr, "delegate", + "--spend-limit="+fmt.Sprintf("%d%s", spendLimitAmount, testDenom), + "--allowed-validators="+val1Addr, + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + // reduce fees of above tx from granter balance + granterBal-- + + delegateTestCases := []struct { + name string + grantee string + valAddr string + amount int64 + expErrMsg string + }{ + { + "valid txn: (delegate half tokens)", + granteeAddr, + val1Addr, + spendLimitAmount / 2, + "", + }, + { + "amount greater than spend limit", + granteeAddr, + val1Addr, + spendLimitAmount + 5, + "negative coin amount", + }, + { + "delegate to not allowed address", + granteeAddr, + val2Addr, + 10, + "cannot delegate", + }, + { + "valid txn: (delegate remaining half tokens)", + granteeAddr, + val1Addr, + spendLimitAmount / 2, + "", + }, + { + "no authorization found as grant prunes", + granteeAddr, + val1Addr, + spendLimitAmount / 2, + "authorization not found", + }, + } + + execCmdArgs := []string{"tx", "authz", "exec"} + + for _, tc := range delegateTestCases { + t.Run(tc.name, func(t *testing.T) { + delegateTx := fmt.Sprintf(`{"@type":"%s","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%d"}}`, + msgDelegateTypeURL, granterAddr, tc.valAddr, testDenom, tc.amount) + execMsg := WriteToTempJSONFile(t, delegateTx) + + cmd := append(append(execCmdArgs, execMsg.Name()), "--from="+tc.grantee) + if tc.expErrMsg != "" { + rsp := cli.Run(cmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, tc.expErrMsg) + return + } + rsp := cli.RunAndWait(cmd...) + RequireTxSuccess(t, rsp) + + // check granter balance equals to granterBal - transferredAmount + expGranterBal := granterBal - tc.amount + require.Equal(t, expGranterBal, cli.QueryBalance(granterAddr, testDenom)) + granterBal = expGranterBal + }) + } +} + +func TestAuthzExecUndelegateAuthorization(t *testing.T) { + // scenario: test authz exec undelegate authorization + // given a running chain + + cli, granterAddr, granteeAddr := setupChain(t) + + // query validator operator address + rsp := cli.CustomQuery("q", "staking", "validators") + validators := gjson.Get(rsp, "validators.#.operator_address").Array() + require.GreaterOrEqual(t, len(validators), 2) + val1Addr := validators[0].String() + val2Addr := validators[1].String() + + // delegate some tokens + rsp = cli.RunAndWait("tx", "staking", "delegate", val1Addr, "10000"+testDenom, "--from="+granterAddr) + RequireTxSuccess(t, rsp) + + // query delegated tokens count + resp := cli.CustomQuery("q", "staking", "delegation", granterAddr, val1Addr) + delegatedAmount := gjson.Get(resp, "delegation_response.balance.amount").Int() + + rsp = cli.RunAndWait("tx", "authz", "grant", granteeAddr, "unbond", + "--allowed-validators="+val1Addr, + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + + undelegateTestCases := []struct { + name string + grantee string + valAddr string + amount int64 + expErrMsg string + }{ + { + "valid transaction", + granteeAddr, + val1Addr, + 10, + "", + }, + { + "undelegate to not allowed address", + granteeAddr, + val2Addr, + 10, + "cannot delegate/undelegate", + }, + } + + for _, tc := range undelegateTestCases { + t.Run(tc.name, func(t *testing.T) { + undelegateTx := fmt.Sprintf(`{"@type":"%s","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%d"}}`, + msgUndelegateTypeURL, granterAddr, tc.valAddr, testDenom, tc.amount) + execMsg := WriteToTempJSONFile(t, undelegateTx) + + cmd := []string{"tx", "authz", "exec", execMsg.Name(), "--from=" + tc.grantee} + if tc.expErrMsg != "" { + rsp := cli.Run(cmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, tc.expErrMsg) + return + } + rsp := cli.RunAndWait(cmd...) + RequireTxSuccess(t, rsp) + + // query delegation and check balance reduced + expectedAmount := delegatedAmount - tc.amount + resp = cli.CustomQuery("q", "staking", "delegation", granterAddr, val1Addr) + delegatedAmount = gjson.Get(resp, "delegation_response.balance.amount").Int() + require.Equal(t, expectedAmount, delegatedAmount) + }) + } + + // revoke existing grant + rsp = cli.RunAndWait("tx", "authz", "revoke", granteeAddr, msgUndelegateTypeURL, "--from", granterAddr) + RequireTxSuccess(t, rsp) + + // check grants between granter and grantee after revoking + resp = cli.CustomQuery("q", "authz", "grants", granterAddr, granteeAddr) + grants := gjson.Get(resp, "grants").Array() + require.Len(t, grants, 0) +} + +func TestAuthzExecRedelegateAuthorization(t *testing.T) { + // scenario: test authz exec redelegate authorization + // given a running chain + + cli, granterAddr, granteeAddr := setupChain(t) + + // query validator operator address + rsp := cli.CustomQuery("q", "staking", "validators") + validators := gjson.Get(rsp, "validators.#.operator_address").Array() + require.GreaterOrEqual(t, len(validators), 2) + val1Addr := validators[0].String() + val2Addr := validators[1].String() + + // delegate some tokens + rsp = cli.RunAndWait("tx", "staking", "delegate", val1Addr, "10000"+testDenom, "--from="+granterAddr) + RequireTxSuccess(t, rsp) + + // test exec redelegate authorization + rsp = cli.RunAndWait("tx", "authz", "grant", granteeAddr, "redelegate", + fmt.Sprintf("--allowed-validators=%s,%s", val1Addr, val2Addr), + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + + var redelegationAmount int64 = 10 + + redelegateTx := fmt.Sprintf(`{"@type":"%s","delegator_address":"%s","validator_src_address":"%s","validator_dst_address":"%s","amount":{"denom":"%s","amount":"%d"}}`, + msgRedelegateTypeURL, granterAddr, val1Addr, val2Addr, testDenom, redelegationAmount) + execMsg := WriteToTempJSONFile(t, redelegateTx) + + redelegateCmd := []string{"tx", "authz", "exec", execMsg.Name(), "--from=" + granteeAddr, "--gas=auto"} + rsp = cli.RunAndWait(redelegateCmd...) + RequireTxSuccess(t, rsp) + + // query new delegation and check balance increased + resp := cli.CustomQuery("q", "staking", "delegation", granterAddr, val2Addr) + delegatedAmount := gjson.Get(resp, "delegation_response.balance.amount").Int() + require.GreaterOrEqual(t, delegatedAmount, redelegationAmount) + + // revoke all existing grants + rsp = cli.RunAndWait("tx", "authz", "revoke-all", "--from", granterAddr) + RequireTxSuccess(t, rsp) + + // check grants after revoking + resp = cli.CustomQuery("q", "authz", "grants-by-granter", granterAddr) + grants := gjson.Get(resp, "grants").Array() + require.Len(t, grants, 0) +} + +func TestAuthzGRPCQueries(t *testing.T) { + // scenario: test authz grpc gateway queries + // given a running chain + + cli, granterAddr, grantee1Addr := setupChain(t) + + grantee2Addr := cli.AddKey("grantee2") + require.NotEqual(t, granterAddr, grantee2Addr) + require.NotEqual(t, grantee1Addr, grantee2Addr) + + // create few grants + rsp := cli.RunAndWait("tx", "authz", "grant", grantee1Addr, "send", + "--spend-limit=10000"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + grant1 := fmt.Sprintf(`"authorization":{"@type":"%s","spend_limit":[{"denom":"%s","amount":"10000"}],"allow_list":[]},"expiration":null`, sendAuthzTypeURL, testDenom) + + rsp = cli.RunAndWait("tx", "authz", "grant", grantee2Addr, "send", + "--spend-limit=1000"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + grant2 := fmt.Sprintf(`"authorization":{"@type":"%s","spend_limit":[{"denom":"%s","amount":"1000"}],"allow_list":[]},"expiration":null`, sendAuthzTypeURL, testDenom) + + rsp = cli.RunAndWait("tx", "authz", "grant", grantee2Addr, "generic", + "--msg-type="+msgVoteTypeURL, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + grant3 := fmt.Sprintf(`"authorization":{"@type":"%s","msg":"%s"},"expiration":null`, genericAuthzTypeURL, msgVoteTypeURL) + + rsp = cli.RunAndWait("tx", "authz", "grant", grantee2Addr, "generic", + "--msg-type="+msgDelegateTypeURL, + "--from", grantee1Addr) + RequireTxSuccess(t, rsp) + grant4 := fmt.Sprintf(`"authorization":{"@type":"%s","msg":"%s"},"expiration":null`, genericAuthzTypeURL, msgDelegateTypeURL) + + baseurl := sut.APIAddress() + + // test query grant grpc endpoint + grantURL := baseurl + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s&msg_type_url=%s" + + bech32FailOutput := `{"code":2, "message":"decoding bech32 failed: invalid separator index -1", "details":[]}` + emptyStrOutput := `{"code":2, "message":"empty address string is not allowed", "details":[]}` + invalidMsgTypeOutput := `{"code":2, "message":"codespace authz code 2: authorization not found: authorization not found for invalidMsg type", "details":[]}` + expGrantOutput := fmt.Sprintf(`{"grants":[{%s}],"pagination":null}`, grant1) + + grantTestCases := []RestTestCase{ + { + "invalid granter address", + fmt.Sprintf(grantURL, "invalid_granter", grantee1Addr, msgSendTypeURL), + http.StatusInternalServerError, + bech32FailOutput, + }, + { + "invalid grantee address", + fmt.Sprintf(grantURL, granterAddr, "invalid_grantee", msgSendTypeURL), + http.StatusInternalServerError, + bech32FailOutput, + }, + { + "with empty granter", + fmt.Sprintf(grantURL, "", grantee1Addr, msgSendTypeURL), + http.StatusInternalServerError, + emptyStrOutput, + }, + { + "with empty grantee", + fmt.Sprintf(grantURL, granterAddr, "", msgSendTypeURL), + http.StatusInternalServerError, + emptyStrOutput, + }, + { + "invalid msg-type", + fmt.Sprintf(grantURL, granterAddr, grantee1Addr, "invalidMsg"), + http.StatusInternalServerError, + invalidMsgTypeOutput, + }, + { + "valid grant query", + fmt.Sprintf(grantURL, granterAddr, grantee1Addr, msgSendTypeURL), + http.StatusOK, + expGrantOutput, + }, + } + + RunRestQueries(t, grantTestCases) + + // test query grants grpc endpoint + grantsURL := baseurl + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s" + + grantsTestCases := []RestTestCase{ + { + "expect single grant", + fmt.Sprintf(grantsURL, granterAddr, grantee1Addr), + http.StatusOK, + fmt.Sprintf(`{"grants":[{%s}],"pagination":{"next_key":null,"total":"1"}}`, grant1), + }, + { + "expect two grants", + fmt.Sprintf(grantsURL, granterAddr, grantee2Addr), + http.StatusOK, + fmt.Sprintf(`{"grants":[{%s},{%s}],"pagination":{"next_key":null,"total":"2"}}`, grant2, grant3), + }, + { + "expect single grant with pagination", + fmt.Sprintf(grantsURL+"&pagination.limit=1", granterAddr, grantee2Addr), + http.StatusOK, + fmt.Sprintf(`{"grants":[{%s}],"pagination":{"next_key":"L2Nvc21vcy5nb3YudjEuTXNnVm90ZQ==","total":"0"}}`, grant2), + }, + { + "expect single grant with pagination limit and offset", + fmt.Sprintf(grantsURL+"&pagination.limit=1&pagination.offset=1", granterAddr, grantee2Addr), + http.StatusOK, + fmt.Sprintf(`{"grants":[{%s}],"pagination":{"next_key":null,"total":"0"}}`, grant3), + }, + { + "expect two grants with pagination", + fmt.Sprintf(grantsURL+"&pagination.limit=2", granterAddr, grantee2Addr), + http.StatusOK, + fmt.Sprintf(`{"grants":[{%s},{%s}],"pagination":{"next_key":null,"total":"0"}}`, grant2, grant3), + }, + } + + RunRestQueries(t, grantsTestCases) + + // test query grants by granter grpc endpoint + grantsByGranterURL := baseurl + "/cosmos/authz/v1beta1/grants/granter/%s" + decodingFailedOutput := `{"code":2, "message":"decoding bech32 failed: invalid character in string: ' '", "details":[]}` + noAuthorizationsOutput := `{"grants":[],"pagination":{"next_key":null,"total":"0"}}` + granterQueryOutput := fmt.Sprintf(`{"grants":[{"granter":"%s","grantee":"%s",%s}],"pagination":{"next_key":null,"total":"1"}}`, + grantee1Addr, grantee2Addr, grant4) + + granterTestCases := []RestTestCase{ + { + "invalid granter account address", + fmt.Sprintf(grantsByGranterURL, "invalid address"), + http.StatusInternalServerError, + decodingFailedOutput, + }, + { + "no authorizations found from granter", + fmt.Sprintf(grantsByGranterURL, grantee2Addr), + http.StatusOK, + noAuthorizationsOutput, + }, + { + "valid granter query", + fmt.Sprintf(grantsByGranterURL, grantee1Addr), + http.StatusOK, + granterQueryOutput, + }, + } + + RunRestQueries(t, granterTestCases) + + // test query grants by grantee grpc endpoint + grantsByGranteeURL := baseurl + "/cosmos/authz/v1beta1/grants/grantee/%s" + grantee1GrantsOutput := fmt.Sprintf(`{"grants":[{"granter":"%s","grantee":"%s",%s}],"pagination":{"next_key":null,"total":"1"}}`, granterAddr, grantee1Addr, grant1) + + granteeTestCases := []RestTestCase{ + { + "invalid grantee account address", + fmt.Sprintf(grantsByGranteeURL, "invalid address"), + http.StatusInternalServerError, + decodingFailedOutput, + }, + { + "no authorizations found from grantee", + fmt.Sprintf(grantsByGranteeURL, granterAddr), + http.StatusOK, + noAuthorizationsOutput, + }, + { + "valid grantee query", + fmt.Sprintf(grantsByGranteeURL, grantee1Addr), + http.StatusOK, + grantee1GrantsOutput, + }, + } + + RunRestQueries(t, granteeTestCases) +} + +func setupChain(t *testing.T) (*CLIWrapper, string, string) { + t.Helper() + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + require.GreaterOrEqual(t, cli.nodesCount, 2) + + // get validators' address which will be used as granter and grantee + granterAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, granterAddr) + granteeAddr := cli.GetKeyAddr("node1") + require.NotEmpty(t, granteeAddr) + + sut.StartChain(t) + + return cli, granterAddr, granteeAddr +} + +func msgSendExec(t *testing.T, granter, grantee, toAddr, denom string, amount int64) []string { + t.Helper() + + bankTx := fmt.Sprintf(`{ + "@type": "%s", + "from_address": "%s", + "to_address": "%s", + "amount": [ + { + "denom": "%s", + "amount": "%d" + } + ] + }`, msgSendTypeURL, granter, toAddr, denom, amount) + execMsg := WriteToTempJSONFile(t, bankTx) + + execSendCmd := []string{"tx", "authz", "exec", execMsg.Name(), "--from=" + grantee} + return execSendCmd +} + +// Write the given string to a new temporary json file. +// Returns an file for the test to use. +func WriteToTempJSONFile(tb testing.TB, s string) *os.File { + tb.Helper() + + tmpFile, err := os.CreateTemp(tb.TempDir(), "test-*.json") + require.NoError(tb, err) + + // Write to the temporary file + _, err = tmpFile.WriteString(s) + require.NoError(tb, err) + + // Close the file after writing + err = tmpFile.Close() + require.NoError(tb, err) + + return tmpFile +} diff --git a/tests/systemtests/bank_test.go b/tests/systemtests/bank_test.go index ae654fcba457..d776bc06a874 100644 --- a/tests/systemtests/bank_test.go +++ b/tests/systemtests/bank_test.go @@ -4,15 +4,13 @@ package systemtests import ( "fmt" + "net/http" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tidwall/gjson" "github.com/tidwall/sjson" - - "github.com/cosmos/cosmos-sdk/testutil" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func TestBankSendTxCmd(t *testing.T) { @@ -23,7 +21,7 @@ func TestBankSendTxCmd(t *testing.T) { cli := NewCLIWrapper(t, sut, verbose) // get validator address - valAddr := gjson.Get(cli.Keys("keys", "list"), "1.address").String() + valAddr := cli.GetKeyAddr("node0") require.NotEmpty(t, valAddr) // add new key @@ -53,14 +51,14 @@ func TestBankSendTxCmd(t *testing.T) { insufficientCmdArgs = append(insufficientCmdArgs, fmt.Sprintf("%d%s", valBalance, denom), "--fees=10stake") rsp = cli.Run(insufficientCmdArgs...) RequireTxFailure(t, rsp) - require.Contains(t, rsp, sdkerrors.ErrInsufficientFunds.Error()) + require.Contains(t, rsp, "insufficient funds") // test tx bank send with unauthorized signature assertUnauthorizedErr := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { require.Len(t, gotOutputs, 1) code := gjson.Get(gotOutputs[0].(string), "code") require.True(t, code.Exists()) - require.Equal(t, int64(sdkerrors.ErrUnauthorized.ABCICode()), code.Int()) + require.Greater(t, code.Int(), int64(0)) return false } invalidCli := cli @@ -131,28 +129,24 @@ func TestBankMultiSendTxCmd(t *testing.T) { testCases := []struct { name string cmdArgs []string - expectErr bool expectedCode uint32 expErrMsg string }{ { "valid transaction", append(multiSendCmdArgs, "--fees=1stake"), - false, 0, "", }, { "not enough arguments", []string{"tx", "bank", "multi-send", account1Addr, account2Addr, "1000stake", "--from=" + account1Addr}, - true, 0, "only received 3", }, { "chain-id shouldn't be used with offline and generate-only flags", append(multiSendCmdArgs, "--generate-only", "--offline", "-a=0", "-s=4"), - true, 0, "chain ID cannot be used", }, @@ -160,7 +154,7 @@ func TestBankMultiSendTxCmd(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - if tc.expectErr { + if tc.expErrMsg != "" { assertErr := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { require.Len(t, gotOutputs, 1) output := gotOutputs[0].(string) @@ -173,24 +167,24 @@ func TestBankMultiSendTxCmd(t *testing.T) { return false // always abort } _ = cli.WithRunErrorMatcher(assertErr).Run(tc.cmdArgs...) - } else { - rsp := cli.Run(tc.cmdArgs...) - txResult, found := cli.AwaitTxCommitted(rsp) - require.True(t, found) - RequireTxSuccess(t, txResult) - // check account1 balance equals to account1Bal - transferredAmount*no_of_accounts - fees - expAcc1Balance := account1Bal - (1000 * 2) - 1 - require.Equal(t, expAcc1Balance, cli.QueryBalance(account1Addr, denom)) - account1Bal = expAcc1Balance - // check account2 balance equals to account2Bal + transferredAmount - expAcc2Balance := account2Bal + 1000 - require.Equal(t, expAcc2Balance, cli.QueryBalance(account2Addr, denom)) - account2Bal = expAcc2Balance - // check account3 balance equals to account3Bal + transferredAmount - expAcc3Balance := account3Bal + 1000 - require.Equal(t, expAcc3Balance, cli.QueryBalance(account3Addr, denom)) - account3Bal = expAcc3Balance + return } + rsp := cli.Run(tc.cmdArgs...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + // check account1 balance equals to account1Bal - transferredAmount*no_of_accounts - fees + expAcc1Balance := account1Bal - (1000 * 2) - 1 + require.Equal(t, expAcc1Balance, cli.QueryBalance(account1Addr, denom)) + account1Bal = expAcc1Balance + // check account2 balance equals to account2Bal + transferredAmount + expAcc2Balance := account2Bal + 1000 + require.Equal(t, expAcc2Balance, cli.QueryBalance(account2Addr, denom)) + account2Bal = expAcc2Balance + // check account3 balance equals to account3Bal + transferredAmount + expAcc3Balance := account3Bal + 1000 + require.Equal(t, expAcc3Balance, cli.QueryBalance(account3Addr, denom)) + account3Bal = expAcc3Balance }) } } @@ -224,7 +218,7 @@ func TestBankGRPCQueries(t *testing.T) { // start chain sut.StartChain(t) - baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + baseurl := sut.APIAddress() // test supply grpc endpoint supplyUrl := baseurl + "/cosmos/bank/v1beta1/supply" @@ -238,10 +232,11 @@ func TestBankGRPCQueries(t *testing.T) { blockHeight := sut.CurrentHeight() supplyTestCases := []struct { - name string - url string - headers map[string]string - expOut string + name string + url string + headers map[string]string + expHttpCode int + expOut string }{ { "test GRPC total supply", @@ -249,12 +244,14 @@ func TestBankGRPCQueries(t *testing.T) { map[string]string{ blockHeightHeader: fmt.Sprintf("%d", blockHeight), }, + http.StatusOK, expTotalSupplyOutput, }, { "test GRPC total supply of a specific denom", supplyUrl + "/by_denom?denom=" + newDenom, map[string]string{}, + http.StatusOK, specificDenomOutput, }, { @@ -263,87 +260,75 @@ func TestBankGRPCQueries(t *testing.T) { map[string]string{ blockHeightHeader: fmt.Sprintf("%d", blockHeight+5), }, + http.StatusInternalServerError, "invalid height", }, { "test GRPC total supply of a bogus denom", supplyUrl + "/by_denom?denom=foobar", map[string]string{}, + http.StatusOK, + // http.StatusNotFound, bogusDenomOutput, }, } for _, tc := range supplyTestCases { t.Run(tc.name, func(t *testing.T) { - resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers) - require.NoError(t, err) + resp := GetRequestWithHeaders(t, tc.url, tc.headers, tc.expHttpCode) require.Contains(t, string(resp), tc.expOut) }) } // test denom metadata endpoint denomMetadataUrl := baseurl + "/cosmos/bank/v1beta1/denoms_metadata" - dmTestCases := []struct { - name string - url string - expOut string - }{ + dmTestCases := []RestTestCase{ { "test GRPC client metadata", denomMetadataUrl, - bankDenomMetadata, + http.StatusOK, + fmt.Sprintf(`{"metadatas":%s,"pagination":{"next_key":null,"total":"2"}}`, bankDenomMetadata), }, { "test GRPC client metadata of a specific denom", denomMetadataUrl + "/uatom", - atomDenomMetadata, + http.StatusOK, + fmt.Sprintf(`{"metadata":%s}`, atomDenomMetadata), }, { "test GRPC client metadata of a bogus denom", denomMetadataUrl + "/foobar", - `"details":[]`, + http.StatusNotFound, + `{"code":5, "message":"client metadata for denom foobar", "details":[]}`, }, } - for _, tc := range dmTestCases { - t.Run(tc.name, func(t *testing.T) { - resp, err := testutil.GetRequest(tc.url) - require.NoError(t, err) - require.Contains(t, string(resp), tc.expOut) - }) - } + RunRestQueries(t, dmTestCases) // test bank balances endpoint balanceUrl := baseurl + "/cosmos/bank/v1beta1/balances/" allBalancesOutput := `{"balances":[` + specificDenomOutput + `,{"denom":"stake","amount":"10000000"}],"pagination":{"next_key":null,"total":"2"}}` - balanceTestCases := []struct { - name string - url string - expOut string - }{ + balanceTestCases := []RestTestCase{ { "test GRPC total account balance", balanceUrl + account1Addr, + http.StatusOK, allBalancesOutput, }, { "test GRPC account balance of a specific denom", fmt.Sprintf("%s%s/by_denom?denom=%s", balanceUrl, account1Addr, newDenom), - specificDenomOutput, + http.StatusOK, + fmt.Sprintf(`{"balance":%s}`, specificDenomOutput), }, { "test GRPC account balance of a bogus denom", fmt.Sprintf("%s%s/by_denom?denom=foobar", balanceUrl, account1Addr), - bogusDenomOutput, + http.StatusOK, + fmt.Sprintf(`{"balance":%s}`, bogusDenomOutput), }, } - for _, tc := range balanceTestCases { - t.Run(tc.name, func(t *testing.T) { - resp, err := testutil.GetRequest(tc.url) - require.NoError(t, err) - require.Contains(t, string(resp), tc.expOut) - }) - } + RunRestQueries(t, balanceTestCases) } diff --git a/tests/systemtests/bankv2_test.go b/tests/systemtests/bankv2_test.go index 275b50161f51..b753ee0be430 100644 --- a/tests/systemtests/bankv2_test.go +++ b/tests/systemtests/bankv2_test.go @@ -50,10 +50,9 @@ func TestBankV2SendTxCmd(t *testing.T) { valBalanceAfer := gjson.Get(valRaw, "balance.amount").Int() // TODO: Make DeductFee ante handler work with bank/v2 - require.Equal(t, valBalanceAfer, valBalance - transferAmount) + require.Equal(t, valBalanceAfer, valBalance-transferAmount) receiverRaw := cli.CustomQuery("q", "bankv2", "balance", receiverAddr, denom) receiverBalance := gjson.Get(receiverRaw, "balance.amount").Int() require.Equal(t, receiverBalance, transferAmount) - } diff --git a/tests/systemtests/cometbft_client_test.go b/tests/systemtests/cometbft_client_test.go new file mode 100644 index 000000000000..0c9fd62bb5bd --- /dev/null +++ b/tests/systemtests/cometbft_client_test.go @@ -0,0 +1,325 @@ +//go:build system_test + +package systemtests + +import ( + "context" + "fmt" + "net/url" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/tidwall/gjson" + + "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + qtypes "github.com/cosmos/cosmos-sdk/types/query" +) + +func TestQueryNodeInfo(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetNodeInfo(context.Background(), &cmtservice.GetNodeInfoRequest{}) + assert.NoError(t, err) + + v := NewCLIWrapper(t, sut, true).Version() + assert.Equal(t, res.ApplicationVersion.Version, v) + + // TODO: we should be adding a way to distinguish a v2. Eventually we should skip some v2 system depending on the consensus engine we want to test + restRes := GetRequest(t, mustV(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/node_info"))) + assert.NoError(t, err) + assert.Equal(t, gjson.GetBytes(restRes, "application_version.version").String(), res.ApplicationVersion.Version) +} + +func TestQuerySyncing(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetSyncing(context.Background(), &cmtservice.GetSyncingRequest{}) + assert.NoError(t, err) + + restRes := GetRequest(t, mustV(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/syncing"))) + assert.Equal(t, gjson.GetBytes(restRes, "syncing").Bool(), res.Syncing) +} + +func TestQueryLatestBlock(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetLatestBlock(context.Background(), &cmtservice.GetLatestBlockRequest{}) + assert.NoError(t, err) + assert.Contains(t, res.SdkBlock.Header.ProposerAddress, "cosmosvalcons") + + _ = GetRequest(t, mustV(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/blocks/latest"))) +} + +func TestQueryBlockByHeight(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + sut.AwaitNBlocks(t, 2, time.Second*25) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetBlockByHeight(context.Background(), &cmtservice.GetBlockByHeightRequest{Height: 2}) + assert.NoError(t, err) + assert.Equal(t, res.SdkBlock.Header.Height, int64(2)) + assert.Contains(t, res.SdkBlock.Header.ProposerAddress, "cosmosvalcons") + + restRes := GetRequest(t, mustV(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/blocks/2"))) + assert.Equal(t, gjson.GetBytes(restRes, "sdk_block.header.height").Int(), int64(2)) + assert.Contains(t, gjson.GetBytes(restRes, "sdk_block.header.proposer_address").String(), "cosmosvalcons") +} + +func TestQueryLatestValidatorSet(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + vals := sut.RPCClient(t).Validators() + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetLatestValidatorSet(context.Background(), &cmtservice.GetLatestValidatorSetRequest{ + Pagination: nil, + }) + assert.NoError(t, err) + assert.Equal(t, len(res.Validators), len(vals)) + + // with pagination + res, err = qc.GetLatestValidatorSet(context.Background(), &cmtservice.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{ + Offset: 0, + Limit: 2, + }}) + assert.NoError(t, err) + assert.Equal(t, len(res.Validators), 2) + + restRes := GetRequest(t, mustV(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=0&pagination.limit=2"))) + assert.Equal(t, len(gjson.GetBytes(restRes, "validators").Array()), 2) +} + +func TestLatestValidatorSet(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + vals := sut.RPCClient(t).Validators() + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + testCases := []struct { + name string + req *cmtservice.GetLatestValidatorSetRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "cannot be nil"}, + {"no pagination", &cmtservice.GetLatestValidatorSetRequest{}, false, ""}, + {"with pagination", &cmtservice.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{Offset: 0, Limit: uint64(len(vals))}}, false, ""}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.GetLatestValidatorSet(context.Background(), tc.req) + if tc.expErr { + assert.Error(t, err) + assert.Contains(t, err.Error(), tc.expErrMsg) + } else { + assert.NoError(t, err) + assert.Equal(t, len(res.Validators), len(vals)) + content, ok := res.Validators[0].PubKey.GetCachedValue().(cryptotypes.PubKey) + assert.True(t, ok) + assert.Equal(t, content.Address(), vals[0].PubKey.Address()) + } + }) + } +} + +func TestLatestValidatorSet_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + + vals := sut.RPCClient(t).Validators() + + testCases := []struct { + name string + url string + expErr bool + expErrMsg string + }{ + {"no pagination", "/cosmos/base/tendermint/v1beta1/validatorsets/latest", false, ""}, + {"pagination invalid fields", "/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=-1&pagination.limit=-2", true, "strconv.ParseUint"}, + {"with pagination", "/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=0&pagination.limit=2", false, ""}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rsp := GetRequest(t, mustV(url.JoinPath(baseurl, tc.url))) + if tc.expErr { + errMsg := gjson.GetBytes(rsp, "message").String() + assert.Contains(t, errMsg, tc.expErrMsg) + } else { + assert.Equal(t, len(vals), int(gjson.GetBytes(rsp, "pagination.total").Int())) + } + }) + } +} + +func TestValidatorSetByHeight(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + vals := sut.RPCClient(t).Validators() + + testCases := []struct { + name string + req *cmtservice.GetValidatorSetByHeightRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "request cannot be nil"}, + {"empty request", &cmtservice.GetValidatorSetByHeightRequest{}, true, "height must be greater than 0"}, + {"no pagination", &cmtservice.GetValidatorSetByHeightRequest{Height: 1}, false, ""}, + {"with pagination", &cmtservice.GetValidatorSetByHeightRequest{Height: 1, Pagination: &qtypes.PageRequest{Offset: 0, Limit: uint64(len(vals))}}, false, ""}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.GetValidatorSetByHeight(context.Background(), tc.req) + if tc.expErr { + assert.Error(t, err) + assert.Contains(t, err.Error(), tc.expErrMsg) + } else { + assert.NoError(t, err) + assert.Equal(t, len(res.Validators), len(vals)) + } + }) + } +} + +func TestValidatorSetByHeight_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + vals := sut.RPCClient(t).Validators() + + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + + block := sut.AwaitNextBlock(t, time.Second*3) + testCases := []struct { + name string + url string + expErr bool + expErrMsg string + }{ + {"invalid height", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d", baseurl, -1), true, "height must be greater than 0"}, + {"no pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d", baseurl, block), false, ""}, + {"pagination invalid fields", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d?pagination.offset=-1&pagination.limit=-2", baseurl, block), true, "strconv.ParseUint"}, + {"with pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d?pagination.limit=2", baseurl, 1), false, ""}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rsp := GetRequest(t, tc.url) + if tc.expErr { + errMsg := gjson.GetBytes(rsp, "message").String() + assert.Contains(t, errMsg, tc.expErrMsg) + } else { + assert.Equal(t, len(vals), int(gjson.GetBytes(rsp, "pagination.total").Int())) + } + }) + } +} + +func TestABCIQuery(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + cdc := codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) + testCases := []struct { + name string + req *cmtservice.ABCIQueryRequest + expectErr bool + expectedCode uint32 + validQuery bool + }{ + { + name: "valid request with proof", + req: &cmtservice.ABCIQueryRequest{ + Path: "/store/gov/key", + Data: []byte{0x03}, + Prove: true, + }, + validQuery: true, + }, + { + name: "valid request without proof", + req: &cmtservice.ABCIQueryRequest{ + Path: "/store/gov/key", + Data: []byte{0x03}, + Prove: false, + }, + validQuery: true, + }, + { + name: "request with invalid path", + req: &cmtservice.ABCIQueryRequest{ + Path: "/foo/bar", + Data: []byte{0x03}, + }, + expectErr: true, + }, + { + name: "request with invalid path recursive", + req: &cmtservice.ABCIQueryRequest{ + Path: "/cosmos.base.tendermint.v1beta1.Service/ABCIQuery", + Data: cdc.MustMarshal(&cmtservice.ABCIQueryRequest{ + Path: "/cosmos.base.tendermint.v1beta1.Service/ABCIQuery", + }), + }, + expectErr: true, + }, + { + name: "request with invalid broadcast tx path", + req: &cmtservice.ABCIQueryRequest{ + Path: "/cosmos.tx.v1beta1.Service/BroadcastTx", + Data: []byte{0x00}, + }, + expectErr: true, + }, + { + name: "request with invalid data", + req: &cmtservice.ABCIQueryRequest{ + Path: "/store/gov/key", + Data: []byte{0x0044, 0x00}, + }, + validQuery: false, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.ABCIQuery(context.Background(), tc.req) + if tc.expectErr { + assert.Error(t, err) + assert.Nil(t, res) + } else { + assert.NoError(t, err) + assert.NotNil(t, res) + assert.Equal(t, res.Code, tc.expectedCode) + } + + if tc.validQuery { + assert.Greater(t, res.Height, int64(0)) + assert.Greater(t, len(res.Key), 0) + assert.Greater(t, len(res.Value), 0) + } + }) + } +} diff --git a/tests/systemtests/fraud_test.go b/tests/systemtests/fraud_test.go index a383669eeff6..0479f526cc2d 100644 --- a/tests/systemtests/fraud_test.go +++ b/tests/systemtests/fraud_test.go @@ -11,8 +11,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tidwall/gjson" - - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" ) func TestValidatorDoubleSign(t *testing.T) { @@ -27,43 +25,37 @@ func TestValidatorDoubleSign(t *testing.T) { // Check the validator is in the active set rsp := cli.CustomQuery("q", "staking", "validators") t.Log(rsp) - nodePowerBefore := QueryCometValidatorPowerForNode(t, sut, 0) + validatorPubKey := LoadValidatorPubKeyForNode(t, sut, 0) + rpc, pkBz := sut.RPCClient(t), validatorPubKey.Bytes() + + nodePowerBefore := QueryCometValidatorPower(rpc, pkBz) require.NotEmpty(t, nodePowerBefore) t.Logf("nodePowerBefore: %v", nodePowerBefore) - var validatorPubKey cryptotypes.PubKey newNode := sut.AddFullnode(t, func(nodeNumber int, nodePath string) { valKeyFile := filepath.Join(WorkDir, nodePath, "config", "priv_validator_key.json") _ = os.Remove(valKeyFile) - _, err := copyFile(filepath.Join(WorkDir, sut.nodePath(0), "config", "priv_validator_key.json"), valKeyFile) - require.NoError(t, err) - validatorPubKey = LoadValidatorPubKeyForNode(t, sut, nodeNumber) + _ = MustCopyFile(filepath.Join(WorkDir, sut.nodePath(0), "config", "priv_validator_key.json"), valKeyFile) }) sut.AwaitNodeUp(t, fmt.Sprintf("http://%s:%d", newNode.IP, newNode.RPCPort)) // let's wait some blocks to have evidence and update persisted - rpc := sut.RPCClient(t) - pkBz := validatorPubKey.Bytes() - for i := 0; i < 20; i++ { + var nodePowerAfter int64 = -1 + for i := 0; i < 30; i++ { sut.AwaitNextBlock(t) - if QueryCometValidatorPower(rpc, pkBz) == 0 { + if nodePowerAfter = QueryCometValidatorPower(rpc, pkBz); nodePowerAfter == 0 { break } + t.Logf("wait %d", sut.CurrentHeight()) } - sut.AwaitNextBlock(t) - // then comet status updated - nodePowerAfter := QueryCometValidatorPowerForNode(t, sut, 0) require.Empty(t, nodePowerAfter) - t.Logf("nodePowerAfter: %v", nodePowerAfter) // and sdk status updated byzantineOperatorAddr := cli.GetKeyAddrPrefix("node0", "val") rsp = cli.CustomQuery("q", "staking", "validator", byzantineOperatorAddr) assert.True(t, gjson.Get(rsp, "validator.jailed").Bool(), rsp) - t.Log("let's run for some blocks to confirm all good") - for i := 0; i < 10; i++ { - sut.AwaitNextBlock(t) - } + // let's run for some blocks to confirm all good + sut.AwaitNBlocks(t, 5) } diff --git a/tests/systemtests/go.mod b/tests/systemtests/go.mod index 5d4949952111..6203d6d05d05 100644 --- a/tests/systemtests/go.mod +++ b/tests/systemtests/go.mod @@ -20,12 +20,13 @@ require ( github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/grpc v1.67.0 // indirect + google.golang.org/grpc v1.67.1 ) require ( cosmossdk.io/math v1.3.0 github.com/cometbft/cometbft v0.38.8 + github.com/cometbft/cometbft/api v1.0.0-rc.1 github.com/creachadair/tomledit v0.0.26 github.com/tidwall/gjson v1.14.2 github.com/tidwall/sjson v1.2.5 @@ -124,7 +125,7 @@ require ( github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -153,7 +154,7 @@ require ( golang.org/x/term v0.24.0 // indirect golang.org/x/text v0.18.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/tests/systemtests/go.sum b/tests/systemtests/go.sum index af10f89276c4..746009230523 100644 --- a/tests/systemtests/go.sum +++ b/tests/systemtests/go.sum @@ -129,6 +129,8 @@ github.com/cometbft/cometbft v0.38.8 h1:XyJ9Cu3xqap6xtNxiemrO8roXZ+KS2Zlu7qQ0w1t github.com/cometbft/cometbft v0.38.8/go.mod h1:xOoGZrtUT+A5izWfHSJgl0gYZUE7lu7Z2XIS1vWG/QQ= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= +github.com/cometbft/cometbft/api v1.0.0-rc.1 h1:GtdXwDGlqwHYs16A4egjwylfYOMYyEacLBrs3Zvpt7g= +github.com/cometbft/cometbft/api v1.0.0-rc.1/go.mod h1:NDFKiBBD8HJC6QQLAoUI99YhsiRZtg2+FJWfk6A6m6o= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -615,8 +617,8 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -947,8 +949,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -966,8 +968,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/tests/systemtests/gov_test.go b/tests/systemtests/gov_test.go new file mode 100644 index 000000000000..092773dc2053 --- /dev/null +++ b/tests/systemtests/gov_test.go @@ -0,0 +1,415 @@ +//go:build system_test + +package systemtests + +import ( + "encoding/base64" + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + + "cosmossdk.io/math" + + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TestSubmitProposal(t *testing.T) { + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address + valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String() + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + // get gov module address + resp := cli.CustomQuery("q", "auth", "module-account", "gov") + govAddress := gjson.Get(resp, "account.value.address").String() + + invalidProp := `{ + "title": "", + "description": "Where is the title!?", + "type": "Text", + "deposit": "-324foocoin" +}` + + invalidPropFile := StoreTempFile(t, []byte(invalidProp)) + defer invalidPropFile.Close() + + // Create a valid new proposal JSON. + propMetadata := []byte{42} + validProp := fmt.Sprintf(` +{ + "messages": [ + { + "@type": "/cosmos.gov.v1.MsgExecLegacyContent", + "authority": "%s", + "content": { + "@type": "/cosmos.gov.v1beta1.TextProposal", + "title": "My awesome title", + "description": "My awesome description" + } + } + ], + "title": "My awesome title", + "summary": "My awesome description", + "metadata": "%s", + "deposit": "%s" +}`, govAddress, base64.StdEncoding.EncodeToString(propMetadata), sdk.NewCoin("stake", math.NewInt(100000))) + validPropFile := StoreTempFile(t, []byte(validProp)) + defer validPropFile.Close() + + testCases := []struct { + name string + args []string + expectErr bool + errMsg string + }{ + { + "invalid proposal", + []string{ + "tx", "gov", "submit-proposal", + invalidPropFile.Name(), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, + "invalid character in coin string", + }, + { + "valid proposal", + []string{ + "tx", "gov", "submit-proposal", + validPropFile.Name(), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.expectErr { + assertOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { + require.Contains(t, gotOutputs[0], tc.errMsg) + return false + } + + cli.WithRunErrorMatcher(assertOutput).Run(tc.args...) + } else { + rsp := cli.Run(tc.args...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + } + }) + } +} + +func TestSubmitLegacyProposal(t *testing.T) { + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address + valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String() + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + invalidProp := `{ + "title": "", + "description": "Where is the title!?", + "type": "Text", + "deposit": "-324foocoin" + }` + invalidPropFile := StoreTempFile(t, []byte(invalidProp)) + defer invalidPropFile.Close() + + validProp := fmt.Sprintf(`{ + "title": "Text Proposal", + "description": "Hello, World!", + "type": "Text", + "deposit": "%s" + }`, sdk.NewCoin("stake", math.NewInt(154310))) + validPropFile := StoreTempFile(t, []byte(validProp)) + defer validPropFile.Close() + + testCases := []struct { + name string + args []string + expectErr bool + errMsg string + }{ + { + "invalid proposal (file)", + []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s=%s", "proposal", invalidPropFile.Name()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, + "proposal title is required", + }, + { + "invalid proposal", + []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s='Where is the title!?'", "description"), + fmt.Sprintf("--%s=%s", "type", "Text"), + fmt.Sprintf("--%s=%s", "deposit", sdk.NewCoin("stake", math.NewInt(10000)).String()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, + "proposal title is required", + }, + { + "valid transaction (file)", + []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s=%s", "proposal", validPropFile.Name()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, + "", + }, + { + "valid transaction", + []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s='Text Proposal'", "title"), + fmt.Sprintf("--%s='Where is the title!?'", "description"), + fmt.Sprintf("--%s=%s", "type", "Text"), + fmt.Sprintf("--%s=%s", "deposit", sdk.NewCoin("stake", math.NewInt(100000)).String()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.expectErr { + assertOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { + fmt.Println("gotOut", gotOutputs) + require.Contains(t, gotOutputs[0], tc.errMsg) + return false + } + + cli.WithRunErrorMatcher(assertOutput).Run(tc.args...) + } else { + rsp := cli.Run(tc.args...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + } + }) + } +} + +func TestNewCmdWeightedVote(t *testing.T) { + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address + valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String() + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + // Submit a new proposal for voting + proposalArgs := []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s='Text Proposal'", "title"), + fmt.Sprintf("--%s='Where is the title!?'", "description"), + fmt.Sprintf("--%s=%s", "type", "Text"), + fmt.Sprintf("--%s=%s", "deposit", sdk.NewCoin("stake", math.NewInt(10_000_000)).String()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + } + rsp := cli.Run(proposalArgs...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + + proposalsResp := cli.CustomQuery("q", "gov", "proposals") + proposals := gjson.Get(proposalsResp, "proposals.#.id").Array() + require.NotEmpty(t, proposals) + + proposal1 := cli.CustomQuery("q", "gov", "proposal", "1") + fmt.Println("first proposal", proposal1) + + testCases := []struct { + name string + args []string + expectErr bool + expectedCode uint32 + broadcasted bool + errMsg string + }{ + { + "vote for invalid proposal", + []string{ + "tx", "gov", "weighted-vote", + "10", + "yes", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, 3, true, + "inactive proposal", + }, + { + "valid vote", + []string{ + "tx", "gov", "weighted-vote", + "1", + "yes", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, 0, true, + "", + }, + { + "valid vote with metadata", + []string{ + "tx", "gov", "weighted-vote", + "1", + "yes", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--metadata=%s", "AQ=="), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, 0, true, + "", + }, + { + "invalid valid split vote string", + []string{ + "tx", "gov", "weighted-vote", + "1", + "yes/0.6,no/0.3,abstain/0.05,no_with_veto/0.05", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, 0, false, + "is not a valid vote option", + }, + { + "valid split vote", + []string{ + "tx", "gov", "weighted-vote", + "1", + "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, 0, true, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if !tc.broadcasted { + assertOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { + require.Contains(t, gotOutputs[0], tc.errMsg) + return false + } + cli.WithRunErrorMatcher(assertOutput).Run(tc.args...) + } else { + rsp := cli.Run(tc.args...) + if tc.expectErr { + RequireTxFailure(t, rsp) + } else { + cli.AwaitTxCommitted(rsp) + } + } + }) + } +} + +func TestQueryDeposit(t *testing.T) { + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address + valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String() + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + // Submit a new proposal for voting + proposalArgs := []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s='Text Proposal'", "title"), + fmt.Sprintf("--%s='Where is the title!?'", "description"), + fmt.Sprintf("--%s=%s", "type", "Text"), + fmt.Sprintf("--%s=%s", "deposit", sdk.NewCoin("stake", math.NewInt(10_000_000)).String()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + } + rsp := cli.Run(proposalArgs...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + + // Query initial deposit + resp := cli.CustomQuery("q", "gov", "deposit", "1", valAddr) + depositAmount := gjson.Get(resp, "deposit.amount.0.amount").Int() + require.Equal(t, depositAmount, int64(10_000_000)) + + resp = cli.CustomQuery("q", "gov", "deposits", "1") + deposits := gjson.Get(resp, "deposits").Array() + require.Equal(t, len(deposits), 1) + + time.Sleep(time.Second * 8) + resp = cli.CustomQuery("q", "gov", "deposits", "1") + deposits = gjson.Get(resp, "deposits").Array() + require.Equal(t, len(deposits), 0) +} diff --git a/tests/systemtests/io_utils.go b/tests/systemtests/io_utils.go new file mode 100644 index 000000000000..a9cd1094fba6 --- /dev/null +++ b/tests/systemtests/io_utils.go @@ -0,0 +1,65 @@ +package systemtests + +import ( + "bytes" + "fmt" + "io" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +// MustCopyFile copies the file from the source path `src` to the destination path `dest` and returns an open file handle to `dest`. +func MustCopyFile(src, dest string) *os.File { + in, err := os.Open(src) + if err != nil { + panic(fmt.Sprintf("failed to open %q: %v", src, err)) + } + defer in.Close() + + out, err := os.Create(dest) + if err != nil { + panic(fmt.Sprintf("failed to create %q: %v", dest, err)) + } + defer out.Close() + + _, err = io.Copy(out, in) + if err != nil { + panic(fmt.Sprintf("failed to copy from %q to %q: %v", src, dest, err)) + } + return out +} + +// MustCopyFilesInDir copies all files (excluding directories) from the source directory `src` to the destination directory `dest`. +func MustCopyFilesInDir(src, dest string) { + err := os.MkdirAll(dest, 0o750) + if err != nil { + panic(fmt.Sprintf("failed to create %q: %v", dest, err)) + } + + fs, err := os.ReadDir(src) + if err != nil { + panic(fmt.Sprintf("failed to read dir %q: %v", src, err)) + } + + for _, f := range fs { + if f.IsDir() { + continue + } + _ = MustCopyFile(filepath.Join(src, f.Name()), filepath.Join(dest, f.Name())) + } +} + +// StoreTempFile creates a temporary file in the test's temporary directory with the provided content. +// It returns a pointer to the created file. Errors during the process are handled with test assertions. +func StoreTempFile(t *testing.T, content []byte) *os.File { + t.Helper() + out, err := os.CreateTemp(t.TempDir(), "") + require.NoError(t, err) + _, err = io.Copy(out, bytes.NewReader(content)) + require.NoError(t, err) + require.NoError(t, out.Close()) + return out +} diff --git a/tests/systemtests/rest_cli.go b/tests/systemtests/rest_cli.go new file mode 100644 index 000000000000..2ae879e1a242 --- /dev/null +++ b/tests/systemtests/rest_cli.go @@ -0,0 +1,56 @@ +package systemtests + +import ( + "io" + "net/http" + "testing" + + "github.com/stretchr/testify/require" +) + +type RestTestCase struct { + name string + url string + expCode int + expOut string +} + +// RunRestQueries runs given Rest testcases by making requests and +// checking response with expected output +func RunRestQueries(t *testing.T, testCases []RestTestCase) { + t.Helper() + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resp := GetRequestWithHeaders(t, tc.url, nil, tc.expCode) + require.JSONEq(t, tc.expOut, string(resp)) + }) + } +} + +func GetRequest(t *testing.T, url string) []byte { + t.Helper() + return GetRequestWithHeaders(t, url, nil, http.StatusOK) +} + +func GetRequestWithHeaders(t *testing.T, url string, headers map[string]string, expCode int) []byte { + t.Helper() + req, err := http.NewRequest("GET", url, nil) + require.NoError(t, err) + + for key, value := range headers { + req.Header.Set(key, value) + } + + httpClient := &http.Client{} + res, err := httpClient.Do(req) + require.NoError(t, err) + defer func() { + _ = res.Body.Close() + }() + require.Equal(t, expCode, res.StatusCode, "status code should be %d, got: %d", expCode, res.StatusCode) + + body, err := io.ReadAll(res.Body) + require.NoError(t, err) + return body +} diff --git a/tests/systemtests/rpc_client.go b/tests/systemtests/rpc_client.go index d1acfd780ff4..4714715be600 100644 --- a/tests/systemtests/rpc_client.go +++ b/tests/systemtests/rpc_client.go @@ -2,11 +2,23 @@ package systemtests import ( "context" + "errors" + "reflect" + "strconv" "testing" + abci "github.com/cometbft/cometbft/api/cometbft/abci/v1" + rpcclient "github.com/cometbft/cometbft/rpc/client" client "github.com/cometbft/cometbft/rpc/client/http" cmtypes "github.com/cometbft/cometbft/types" "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" ) // RPCClient is a test helper to interact with a node via the RPC endpoint. @@ -31,3 +43,71 @@ func (r RPCClient) Validators() []*cmtypes.Validator { require.NoError(r.t, err) return v.Validators } + +func (r RPCClient) Invoke(ctx context.Context, method string, req, reply interface{}, opts ...grpc.CallOption) error { + if reflect.ValueOf(req).IsNil() { + return errors.New("request cannot be nil") + } + + ir := types.NewInterfaceRegistry() + cryptocodec.RegisterInterfaces(ir) + cdc := codec.NewProtoCodec(ir).GRPCCodec() + + reqBz, err := cdc.Marshal(req) + if err != nil { + return err + } + + var height int64 + md, _ := metadata.FromOutgoingContext(ctx) + if heights := md.Get(grpctypes.GRPCBlockHeightHeader); len(heights) > 0 { + height, err := strconv.ParseInt(heights[0], 10, 64) + if err != nil { + return err + } + if height < 0 { + return errors.New("height must be greater than or equal to 0") + } + } + + abciReq := abci.QueryRequest{ + Path: method, + Data: reqBz, + Height: height, + } + + abciOpts := rpcclient.ABCIQueryOptions{ + Height: height, + Prove: abciReq.Prove, + } + + result, err := r.client.ABCIQueryWithOptions(ctx, abciReq.Path, abciReq.Data, abciOpts) + if err != nil { + return err + } + + if !result.Response.IsOK() { + return errors.New(result.Response.String()) + } + + err = cdc.Unmarshal(result.Response.Value, reply) + if err != nil { + return err + } + + md = metadata.Pairs(grpctypes.GRPCBlockHeightHeader, strconv.FormatInt(result.Response.Height, 10)) + for _, callOpt := range opts { + header, ok := callOpt.(grpc.HeaderCallOption) + if !ok { + continue + } + + *header.HeaderAddr = md + } + + return types.UnpackInterfaces(reply, ir) +} + +func (r RPCClient) NewStream(ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) { + return nil, errors.New("not implemented") +} diff --git a/tests/systemtests/snapshots_test.go b/tests/systemtests/snapshots_test.go index 42569a031799..d80eb530f413 100644 --- a/tests/systemtests/snapshots_test.go +++ b/tests/systemtests/snapshots_test.go @@ -4,13 +4,13 @@ package systemtests import ( "fmt" - "github.com/stretchr/testify/require" "os" "testing" + + "github.com/stretchr/testify/require" ) func TestSnapshots(t *testing.T) { - sut.ResetChain(t) cli := NewCLIWrapper(t, sut, verbose) sut.StartChain(t) diff --git a/tests/systemtests/system.go b/tests/systemtests/system.go index d76d482b89e2..7aa00f7cfbf3 100644 --- a/tests/systemtests/system.go +++ b/tests/systemtests/system.go @@ -53,6 +53,7 @@ type SystemUnderTest struct { // since Tendermint consensus does not allow specifying it directly. blockTime time.Duration rpcAddr string + apiAddr string initialNodesCount int nodesCount int minGasPrice string @@ -86,6 +87,7 @@ func NewSystemUnderTest(execBinary string, verbose bool, nodesCount int, blockTi outputDir: "./testnet", blockTime: blockTime, rpcAddr: "tcp://localhost:26657", + apiAddr: fmt.Sprintf("http://localhost:%d", apiPortStart), initialNodesCount: nodesCount, outBuff: ring.New(100), errBuff: ring.New(100), @@ -132,6 +134,11 @@ func (s *SystemUnderTest) SetupChain() { if err != nil { panic(fmt.Sprintf("failed set block max gas: %s", err)) } + // Short period for gov + genesisBz, err = sjson.SetRawBytes(genesisBz, "app_state.gov.params.voting_period", []byte(fmt.Sprintf(`"%s"`, "8s"))) + if err != nil { + panic(fmt.Sprintf("failed set block max gas: %s", err)) + } s.withEachNodeHome(func(i int, home string) { if err := saveGenesis(home, genesisBz); err != nil { panic(err) @@ -140,15 +147,11 @@ func (s *SystemUnderTest) SetupChain() { // backup genesis dest := filepath.Join(WorkDir, s.nodePath(0), "config", "genesis.json.orig") - if _, err := copyFile(src, dest); err != nil { - panic(fmt.Sprintf("copy failed :%#+v", err)) - } + MustCopyFile(src, dest) // backup keyring src = filepath.Join(WorkDir, s.nodePath(0), "keyring-test") dest = filepath.Join(WorkDir, s.outputDir, "keyring-test") - if err := copyFilesInDir(src, dest); err != nil { - panic(fmt.Sprintf("copy files from dir :%#+v", err)) - } + MustCopyFilesInDir(src, dest) } func (s *SystemUnderTest) StartChain(t *testing.T, xargs ...string) { @@ -478,7 +481,7 @@ func (s *SystemUnderTest) modifyGenesisJSON(t *testing.T, mutators ...GenesisMut for _, m := range mutators { current = m(current) } - out := storeTempFile(t, current) + out := StoreTempFile(t, current) defer os.Remove(out.Name()) s.setGenesis(t, out.Name()) s.MarkDirty() @@ -633,6 +636,10 @@ func (s *SystemUnderTest) RPCClient(t *testing.T) RPCClient { return NewRPCClient(t, s.rpcAddr) } +func (s *SystemUnderTest) APIAddress() string { + return s.apiAddr +} + func (s *SystemUnderTest) AllPeers(t *testing.T) []string { t.Helper() result := make([]string, s.nodesCount) @@ -701,8 +708,7 @@ func (s *SystemUnderTest) AddFullnode(t *testing.T, beforeStart ...func(nodeNumb for _, tomlFile := range []string{"config.toml", "app.toml"} { configFile := filepath.Join(configPath, tomlFile) _ = os.Remove(configFile) - _, err := copyFile(filepath.Join(WorkDir, s.nodePath(0), "config", tomlFile), configFile) - require.NoError(t, err) + _ = MustCopyFile(filepath.Join(WorkDir, s.nodePath(0), "config", tomlFile), configFile) } // start node allNodes := s.AllNodes(t) @@ -938,54 +944,6 @@ func restoreOriginalKeyring(t *testing.T, s *SystemUnderTest) { require.NoError(t, os.RemoveAll(dest)) for i := 0; i < s.initialNodesCount; i++ { src := filepath.Join(WorkDir, s.nodePath(i), "keyring-test") - require.NoError(t, copyFilesInDir(src, dest)) - } -} - -// copyFile copy source file to dest file path -func copyFile(src, dest string) (*os.File, error) { - in, err := os.Open(src) - if err != nil { - return nil, err - } - defer in.Close() - out, err := os.Create(dest) - if err != nil { - return nil, err - } - defer out.Close() - - _, err = io.Copy(out, in) - return out, err -} - -// copyFilesInDir copy files in src dir to dest path -func copyFilesInDir(src, dest string) error { - err := os.MkdirAll(dest, 0o750) - if err != nil { - return fmt.Errorf("mkdirs: %w", err) + MustCopyFilesInDir(src, dest) } - fs, err := os.ReadDir(src) - if err != nil { - return fmt.Errorf("read dir: %w", err) - } - for _, f := range fs { - if f.IsDir() { - continue - } - if _, err := copyFile(filepath.Join(src, f.Name()), filepath.Join(dest, f.Name())); err != nil { - return fmt.Errorf("copy file: %q: %w", f.Name(), err) - } - } - return nil -} - -func storeTempFile(t *testing.T, content []byte) *os.File { - t.Helper() - out, err := os.CreateTemp(t.TempDir(), "genesis") - require.NoError(t, err) - _, err = io.Copy(out, bytes.NewReader(content)) - require.NoError(t, err) - require.NoError(t, out.Close()) - return out } diff --git a/tests/systemtests/testnet_init.go b/tests/systemtests/testnet_init.go index 21f237ec78ca..bdb2a85d25da 100644 --- a/tests/systemtests/testnet_init.go +++ b/tests/systemtests/testnet_init.go @@ -162,7 +162,6 @@ func (s ModifyConfigYamlInitializer) Initialize() { EditToml(filepath.Join(nodeDir, "app.toml"), func(doc *tomledit.Document) { UpdatePort(doc, apiPortStart+i, "api", "address") UpdatePort(doc, grpcPortStart+i, "grpc", "address") - SetBool(doc, true, "grpc-web", "enable") }) } } diff --git a/tests/systemtests/unordered_tx_test.go b/tests/systemtests/unordered_tx_test.go index 6b1a9c743e7d..579552efe0e7 100644 --- a/tests/systemtests/unordered_tx_test.go +++ b/tests/systemtests/unordered_tx_test.go @@ -12,7 +12,8 @@ import ( ) func TestUnorderedTXDuplicate(t *testing.T) { - t.Skip("The unordered tx antehanlder is missing in v2") + t.Skip("The unordered tx handling is not wired in v2") + // scenario: test unordered tx duplicate // given a running chain with a tx in the unordered tx pool // when a new tx with the same hash is broadcasted diff --git a/testutil/network/network.go b/testutil/network/network.go index bfdedb23e358..2bc85a10bd52 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -493,7 +493,7 @@ func New(l Logger, baseDir string, cfg Config) (NetworkI, error) { sdk.ValAddress(addr).String(), valPubKeys[i], sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens), - stakingtypes.NewDescription(nodeDirName, "", "", "", ""), + stakingtypes.NewDescription(nodeDirName, "", "", "", "", stakingtypes.Metadata{}), stakingtypes.NewCommissionRates(commission, sdkmath.LegacyOneDec(), sdkmath.LegacyOneDec()), sdkmath.OneInt(), ) diff --git a/tools/confix/Makefile b/tools/confix/Makefile index 417b7a7c4933..5c29441e29de 100644 --- a/tools/confix/Makefile +++ b/tools/confix/Makefile @@ -4,9 +4,11 @@ all: confix condiff test confix: go build -mod=readonly ./cmd/confix + @echo "confix binary has been successfully built in tools/confix/confix" condiff: go build -mod=readonly ./cmd/condiff + @echo "condiff binary has been successfully built in tools/confix/condiff" test: go test -mod=readonly -race ./... diff --git a/tools/confix/README.md b/tools/confix/README.md index 64b2f49b3dc7..00851ede1923 100644 --- a/tools/confix/README.md +++ b/tools/confix/README.md @@ -23,7 +23,7 @@ import "cosmossdk.io/tools/confix/cmd" Find the following line: ```go -initRootCmd(rootCmd, encodingConfig) +initRootCmd(rootCmd, moduleManager) ``` After that line, add the following: @@ -39,10 +39,10 @@ An implementation example can be found in `simapp`. The command will be available as `simd config`. -```tip +:::tip Using confix directly in the application can have less features than using it standalone. This is because confix is versioned with the SDK, while `latest` is the standalone version. -``` +::: ### Using Confix Standalone @@ -138,7 +138,7 @@ confix view ~/.simapp/config/client.toml # views the current app client conf ### Maintainer -At each SDK modification of the default configuration, add the default SDK config under `data/v0.XX-app.toml`. +At each SDK modification of the default configuration, add the default SDK config under `data/vXX-app.toml`. This allows users to use the tool standalone. ### Compatibility @@ -149,7 +149,8 @@ The recommended standalone version is `latest`, which is using the latest develo | ----------- | -------------- | | v0.50 | v0.1.x | | v0.52 | v0.2.x | +| v2 | v0.2.x | ## Credits -This project is based on the [CometBFT RFC 019](https://github.com/cometbft/cometbft/blob/5013bc3f4a6d64dcc2bf02ccc002ebc9881c62e4/docs/rfc/rfc-019-config-version.md) and their own implementation of [confix](https://github.com/cometbft/cometbft/blob/v0.36.x/scripts/confix/confix.go). +This project is based on the [CometBFT RFC 019](https://github.com/cometbft/cometbft/blob/5013bc3f4a6d64dcc2bf02ccc002ebc9881c62e4/docs/rfc/rfc-019-config-version.md) and their never released own implementation of [confix](https://github.com/cometbft/cometbft/blob/v0.36.x/scripts/confix/confix.go). diff --git a/tools/confix/data/v0.52-app.toml b/tools/confix/data/v0.52-app.toml index d6e3cf95ab01..f97f48044502 100644 --- a/tools/confix/data/v0.52-app.toml +++ b/tools/confix/data/v0.52-app.toml @@ -66,7 +66,7 @@ index-events = [] # IavlCacheSize set the size of the iavl tree cache (in number of nodes). iavl-cache-size = 781250 -# IAVLDisableFastNode enables or disables the fast node feature of IAVL. +# IAVLDisableFastNode enables or disables the fast node feature of IAVL. # Default is false. iavl-disable-fastnode = false @@ -223,9 +223,3 @@ stop-node-on-err = true # Note, this configuration only applies to SDK built-in app-side mempool # implementations. max-txs = -1 - -[custom] - -# That field will be parsed by server.InterceptConfigsPreRunHandler and held by viper. -# Do not forget to add quotes around the value if it is a string. -custom-field = "anything" diff --git a/tools/confix/data/v2-app.toml b/tools/confix/data/v2-app.toml index 8f7f7f9940d2..c4f19348ce52 100644 --- a/tools/confix/data/v2-app.toml +++ b/tools/confix/data/v2-app.toml @@ -16,6 +16,11 @@ trace = false # standalone starts the application without the CometBFT node. The node should be started separately. standalone = false +# mempool defines the configuration for the SDK built-in app-side mempool implementations. +[comet.mempool] +# max-txs defines the maximum number of transactions that can be in the mempool. A value of 0 indicates an unbounded mempool, a negative value disables the app-side mempool. +max-txs = -1 + [grpc] # Enable defines if the gRPC server should be enabled. enable = true @@ -37,27 +42,53 @@ minimum-gas-prices = '0stake' app-db-backend = 'goleveldb' [store.options] -# State storage database type. Currently we support: 0 for SQLite, 1 for Pebble -ss-type = 0 -# State commitment database type. Currently we support:0 for iavl, 1 for iavl v2 -sc-type = 0 +# SState storage database type. Currently we support: "sqlite", "pebble" and "rocksdb" +ss-type = 'sqlite' +# State commitment database type. Currently we support: "iavl" and "iavl-v2" +sc-type = 'iavl' # Pruning options for state storage [store.options.ss-pruning-option] # Number of recent heights to keep on disk. keep-recent = 2 # Height interval at which pruned heights are removed from disk. -interval = 1 +interval = 100 # Pruning options for state commitment [store.options.sc-pruning-option] # Number of recent heights to keep on disk. keep-recent = 2 # Height interval at which pruned heights are removed from disk. -interval = 1 +interval = 100 [store.options.iavl-config] # CacheSize set the size of the iavl tree cache. cache-size = 100000 # If true, the tree will work like no fast storage and always not upgrade fast storage. skip-fast-storage-upgrade = true + +[telemetry] +# Enable enables the application telemetry functionality. When enabled, an in-memory sink is also enabled by default. Operators may also enabled other sinks such as Prometheus. +enable = true +# Address defines the metrics server address to bind to. +address = 'localhost:1338' +# Prefixed with keys to separate services. +service-name = '' +# Enable prefixing gauge values with hostname. +enable-hostname = false +# Enable adding hostname to labels. +enable-hostname-label = false +# Enable adding service to labels. +enable-service-label = false +# PrometheusRetentionTime, when positive, enables a Prometheus metrics sink. It defines the retention duration in seconds. +prometheus-retention-time = 0 +# GlobalLabels defines a global set of name/value label tuples applied to all metrics emitted using the wrapper functions defined in telemetry package. +# Example: +# [["chain_id", "cosmoshub-1"]] +global-labels = [] +# MetricsSink defines the type of metrics backend to use. Default is in memory +metrics-sink = '' +# StatsdAddr defines the address of a statsd server to send metrics to. Only utilized if MetricsSink is set to "statsd" or "dogstatsd". +stats-addr = '' +# DatadogHostname defines the hostname to use when emitting metrics to Datadog. Only utilized if MetricsSink is set to "dogstatsd". +data-dog-hostname = '' diff --git a/tools/confix/go.mod b/tools/confix/go.mod index f2e0c66f02b2..e6800c66e46b 100644 --- a/tools/confix/go.mod +++ b/tools/confix/go.mod @@ -117,7 +117,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -148,8 +148,8 @@ require ( golang.org/x/text v0.18.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/grpc v1.67.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect + google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/tools/confix/go.sum b/tools/confix/go.sum index fd35d2de9106..32242dcba2a9 100644 --- a/tools/confix/go.sum +++ b/tools/confix/go.sum @@ -618,8 +618,8 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -946,8 +946,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -965,8 +965,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/tools/confix/migrations.go b/tools/confix/migrations.go index 86bf1affee24..77fc4a671cb4 100644 --- a/tools/confix/migrations.go +++ b/tools/confix/migrations.go @@ -55,6 +55,8 @@ var v2KeyChanges = v2KeyChangesMap{ }, "iavl-cache-size": []string{"store.options.iavl-config.cache-size"}, "iavl-disable-fastnode": []string{"store.options.iavl-config.skip-fast-storage-upgrade"}, + "telemetry.enabled": []string{"telemetry.enable"}, + "mempool.max-txs": []string{"comet.mempool.max-txs"}, // Add other key mappings as needed } diff --git a/tools/cosmovisor/CHANGELOG.md b/tools/cosmovisor/CHANGELOG.md index a4c78e469c45..3db3e4ea9954 100644 --- a/tools/cosmovisor/CHANGELOG.md +++ b/tools/cosmovisor/CHANGELOG.md @@ -36,20 +36,28 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] +### Features + +* [#21972](https://github.com/cosmos/cosmos-sdk/pull/21972) Add `prepare-upgrade` command + ### Improvements * [#21462](https://github.com/cosmos/cosmos-sdk/pull/21462) Pass `stdin` to binary. +### Features + +* [#21932](https://github.com/cosmos/cosmos-sdk/pull/21932) Add `cosmovisor show-upgrade-info` command to display the upgrade-info.json into stdout. + ## v1.6.0 - 2024-08-12 ## Improvements * Bump `cosmossdk.io/x/upgrade` to v0.1.4 (including go-getter vulnerability fix) * [#19995](https://github.com/cosmos/cosmos-sdk/pull/19995): - * `init command` writes the configuration to the config file only at the default path `DAEMON_HOME/cosmovisor/config.toml`. - * Provide `--cosmovisor-config` flag with value as args to provide the path to the configuration file in the `run` command. `run --cosmovisor-config (other cmds with flags) ...`. - * Add `--cosmovisor-config` flag to provide `config.toml` path to the configuration file in root command used by `add-upgrade` and `config` subcommands. - * `config command` now displays the configuration from the config file if it is provided. If the config file is not provided, it will display the configuration from the environment variables. + * `init command` writes the configuration to the config file only at the default path `DAEMON_HOME/cosmovisor/config.toml`. + * Provide `--cosmovisor-config` flag with value as args to provide the path to the configuration file in the `run` command. `run --cosmovisor-config (other cmds with flags) ...`. + * Add `--cosmovisor-config` flag to provide `config.toml` path to the configuration file in root command used by `add-upgrade` and `config` subcommands. + * `config command` now displays the configuration from the config file if it is provided. If the config file is not provided, it will display the configuration from the environment variables. ## Bug Fixes diff --git a/tools/cosmovisor/Makefile b/tools/cosmovisor/Makefile index b5a7be601e9c..94a02976acf3 100644 --- a/tools/cosmovisor/Makefile +++ b/tools/cosmovisor/Makefile @@ -4,6 +4,7 @@ all: cosmovisor test cosmovisor: go build -mod=readonly ./cmd/cosmovisor + @echo "cosmovisor binary has been successfully built in tools/cosmovisor/cosmovisor" test: go test -mod=readonly -race ./... diff --git a/tools/cosmovisor/README.md b/tools/cosmovisor/README.md index db15ab0a5d64..3b5f722c5d1b 100644 --- a/tools/cosmovisor/README.md +++ b/tools/cosmovisor/README.md @@ -7,21 +7,21 @@ sidebar_position: 1 `cosmovisor` is a process manager for Cosmos SDK application binaries that automates application binary switch at chain upgrades. It polls the `upgrade-info.json` file that is created by the x/upgrade module at upgrade height, and then can automatically download the new binary, stop the current binary, switch from the old binary to the new one, and finally restart the node with the new binary. -* [Cosmovisor](#cosmovisor) - * [Design](#design) - * [Contributing](#contributing) - * [Setup](#setup) +* [Design](#design) +* [Contributing](#contributing) +* [Setup](#setup) * [Installation](#installation) * [Command Line Arguments And Environment Variables](#command-line-arguments-and-environment-variables) * [Folder Layout](#folder-layout) - * [Usage](#usage) +* [Usage](#usage) * [Initialization](#initialization) * [Detecting Upgrades](#detecting-upgrades) * [Adding Upgrade Binary](#adding-upgrade-binary) * [Auto-Download](#auto-download) - * [Example: SimApp Upgrade](#example-simapp-upgrade) + * [Preparing for an Upgrade](#preparing-for-an-upgrade) +* [Example: SimApp Upgrade](#example-simapp-upgrade) * [Chain Setup](#chain-setup) - * [Prepare Cosmovisor and Start the Chain](#prepare-cosmovisor-and-start-the-chain) + * [Prepare Cosmovisor and Start the Chain](#prepare-cosmovisor-and-start-the-chain) * [Update App](#update-app) ## Design @@ -263,6 +263,38 @@ The result will look something like the following: `29139e1381b8177aec909fab9a75 You can also use `sha512sum` if you would prefer to use longer hashes, or `md5sum` if you would prefer to use broken hashes. Whichever you choose, make sure to set the hash algorithm properly in the checksum argument to the URL. +### Preparing for an Upgrade + +To prepare for an upgrade, use the `prepare-upgrade` command: + +```shell +cosmovisor prepare-upgrade +``` + +This command performs the following actions: + +1. Retrieves upgrade information directly from the blockchain about the next scheduled upgrade. +2. Downloads the new binary specified in the upgrade plan. +3. Verifies the binary's checksum (if required by configuration). +4. Places the new binary in the appropriate directory for Cosmovisor to use during the upgrade. + +The `prepare-upgrade` command provides detailed logging throughout the process, including: + +* The name and height of the upcoming upgrade +* The URL from which the new binary is being downloaded +* Confirmation of successful download and verification +* The path where the new binary has been placed + +Example output: + +```bash +INFO Preparing for upgrade name=v1.0.0 height=1000000 +INFO Downloading upgrade binary url=https://example.com/binary/v1.0.0?checksum=sha256:339911508de5e20b573ce902c500ee670589073485216bee8b045e853f24bce8 +INFO Upgrade preparation complete name=v1.0.0 height=1000000 +``` + +*Note: The current way of downloading manually and placing the binary at the right place would still work.* + ## Example: SimApp Upgrade The following instructions provide a demonstration of `cosmovisor` using the simulation application (`simapp`) shipped with the Cosmos SDK's source code. The following commands are to be run from within the `cosmos-sdk` repository. diff --git a/tools/cosmovisor/args.go b/tools/cosmovisor/args.go index be94fbadaf6c..6c6b5b7b0572 100644 --- a/tools/cosmovisor/args.go +++ b/tools/cosmovisor/args.go @@ -33,6 +33,7 @@ const ( EnvDataBackupPath = "DAEMON_DATA_BACKUP_DIR" EnvInterval = "DAEMON_POLL_INTERVAL" EnvPreupgradeMaxRetries = "DAEMON_PREUPGRADE_MAX_RETRIES" + EnvGRPCAddress = "DAEMON_GRPC_ADDRESS" EnvDisableLogs = "COSMOVISOR_DISABLE_LOGS" EnvColorLogs = "COSMOVISOR_COLOR_LOGS" EnvTimeFormatLogs = "COSMOVISOR_TIMEFORMAT_LOGS" @@ -63,6 +64,7 @@ type Config struct { UnsafeSkipBackup bool `toml:"unsafe_skip_backup" mapstructure:"unsafe_skip_backup" default:"false"` DataBackupPath string `toml:"daemon_data_backup_dir" mapstructure:"daemon_data_backup_dir"` PreUpgradeMaxRetries int `toml:"daemon_preupgrade_max_retries" mapstructure:"daemon_preupgrade_max_retries" default:"0"` + GRPCAddress string `toml:"daemon_grpc_address" mapstructure:"daemon_grpc_address"` DisableLogs bool `toml:"cosmovisor_disable_logs" mapstructure:"cosmovisor_disable_logs" default:"false"` ColorLogs bool `toml:"cosmovisor_color_logs" mapstructure:"cosmovisor_color_logs" default:"true"` TimeFormatLogs string `toml:"cosmovisor_timeformat_logs" mapstructure:"cosmovisor_timeformat_logs" default:"kitchen"` @@ -282,6 +284,11 @@ func GetConfigFromEnv(skipValidate bool) (*Config, error) { errs = append(errs, fmt.Errorf("%s could not be parsed to int: %w", EnvPreupgradeMaxRetries, err)) } + cfg.GRPCAddress = os.Getenv(EnvGRPCAddress) + if cfg.GRPCAddress == "" { + cfg.GRPCAddress = "localhost:9090" + } + if !skipValidate { errs = append(errs, cfg.validate()...) if len(errs) > 0 { diff --git a/tools/cosmovisor/cmd/cosmovisor/help.go b/tools/cosmovisor/cmd/cosmovisor/help.go index ba9c32afcbb5..6d6df59cef7b 100644 --- a/tools/cosmovisor/cmd/cosmovisor/help.go +++ b/tools/cosmovisor/cmd/cosmovisor/help.go @@ -18,7 +18,7 @@ the proposal. Cosmovisor interprets that data to perform an update: switch a cur and restart the App. Configuration of Cosmovisor is done through environment variables, which are -documented in: https://docs.cosmos.network/main/tooling/cosmovisor`, +documented in: https://docs.cosmos.network/main/build/tooling/cosmovisor`, cosmovisor.EnvName, cosmovisor.EnvHome, ) } diff --git a/tools/cosmovisor/cmd/cosmovisor/help_test.go b/tools/cosmovisor/cmd/cosmovisor/help_test.go index fe4e5d78c93b..48d7aa148436 100644 --- a/tools/cosmovisor/cmd/cosmovisor/help_test.go +++ b/tools/cosmovisor/cmd/cosmovisor/help_test.go @@ -12,7 +12,7 @@ func TestGetHelpText(t *testing.T) { expectedPieces := []string{ "Cosmovisor", cosmovisor.EnvName, cosmovisor.EnvHome, - "https://docs.cosmos.network/main/tooling/cosmovisor", + "https://docs.cosmos.network/main/build/tooling/cosmovisor", } actual := GetHelpText() diff --git a/tools/cosmovisor/cmd/cosmovisor/prepare_upgrade.go b/tools/cosmovisor/cmd/cosmovisor/prepare_upgrade.go new file mode 100644 index 000000000000..f15e88803a67 --- /dev/null +++ b/tools/cosmovisor/cmd/cosmovisor/prepare_upgrade.go @@ -0,0 +1,126 @@ +package main + +import ( + "context" + "crypto/tls" + "fmt" + "path/filepath" + "strings" + "time" + + "github.com/spf13/cobra" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" + + "cosmossdk.io/tools/cosmovisor" + "cosmossdk.io/x/upgrade/plan" + upgradetypes "cosmossdk.io/x/upgrade/types" +) + +func NewPrepareUpgradeCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "prepare-upgrade", + Short: "Prepare for the next upgrade", + Long: `Prepare for the next upgrade by downloading and verifying the upgrade binary. +This command will query the chain for the current upgrade plan and download the specified binary. +gRPC must be enabled on the node for this command to work.`, + RunE: prepareUpgradeHandler, + SilenceUsage: false, + Args: cobra.NoArgs, + } + + return cmd +} + +func prepareUpgradeHandler(cmd *cobra.Command, _ []string) error { + configPath, err := cmd.Flags().GetString(cosmovisor.FlagCosmovisorConfig) + if err != nil { + return fmt.Errorf("failed to get config flag: %w", err) + } + + cfg, err := cosmovisor.GetConfigFromFile(configPath) + if err != nil { + return fmt.Errorf("failed to get config: %w", err) + } + + logger := cfg.Logger(cmd.OutOrStdout()) + + grpcAddress := cfg.GRPCAddress + logger.Info("Using gRPC address", "address", grpcAddress) + + upgradeInfo, err := queryUpgradeInfoFromChain(grpcAddress) + if err != nil { + return fmt.Errorf("failed to query upgrade info: %w", err) + } + + if upgradeInfo == nil { + logger.Info("No active upgrade plan found") + return nil + } + + logger.Info("Preparing for upgrade", "name", upgradeInfo.Name, "height", upgradeInfo.Height) + + upgradeInfoParsed, err := plan.ParseInfo(upgradeInfo.Info, plan.ParseOptionEnforceChecksum(cfg.DownloadMustHaveChecksum)) + if err != nil { + return fmt.Errorf("failed to parse upgrade info: %w", err) + } + + binaryURL, err := cosmovisor.GetBinaryURL(upgradeInfoParsed.Binaries) + if err != nil { + return fmt.Errorf("binary URL not found in upgrade plan. Cannot prepare for upgrade: %w", err) + } + + logger.Info("Downloading upgrade binary", "url", binaryURL) + + upgradeBin := filepath.Join(cfg.UpgradeBin(upgradeInfo.Name), cfg.Name) + if err := plan.DownloadUpgrade(filepath.Dir(upgradeBin), binaryURL, cfg.Name); err != nil { + return fmt.Errorf("failed to download and verify binary: %w", err) + } + + logger.Info("Upgrade preparation complete", "name", upgradeInfo.Name, "height", upgradeInfo.Height) + + return nil +} + +func queryUpgradeInfoFromChain(grpcAddress string) (*upgradetypes.Plan, error) { + if grpcAddress == "" { + return nil, fmt.Errorf("gRPC address is empty") + } + + grpcConn, err := getClient(grpcAddress) + if err != nil { + return nil, fmt.Errorf("failed to open gRPC client: %w", err) + } + defer grpcConn.Close() + + queryClient := upgradetypes.NewQueryClient(grpcConn) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + res, err := queryClient.CurrentPlan(ctx, &upgradetypes.QueryCurrentPlanRequest{}) + if err != nil { + return nil, fmt.Errorf("failed to query current upgrade plan: %w", err) + } + + return res.Plan, nil +} + +func getClient(endpoint string) (*grpc.ClientConn, error) { + var creds credentials.TransportCredentials + if strings.HasPrefix(endpoint, "https://") { + tlsConfig := &tls.Config{ + MinVersion: tls.VersionTLS12, + } + creds = credentials.NewTLS(tlsConfig) + } else { + creds = insecure.NewCredentials() + } + + opts := []grpc.DialOption{ + grpc.WithTransportCredentials(creds), + } + + return grpc.NewClient(endpoint, opts...) +} diff --git a/tools/cosmovisor/cmd/cosmovisor/root.go b/tools/cosmovisor/cmd/cosmovisor/root.go index d9f6094d593c..5cd31f8aea5b 100644 --- a/tools/cosmovisor/cmd/cosmovisor/root.go +++ b/tools/cosmovisor/cmd/cosmovisor/root.go @@ -19,6 +19,8 @@ func NewRootCmd() *cobra.Command { configCmd, NewVersionCmd(), NewAddUpgradeCmd(), + NewShowUpgradeInfoCmd(), + NewPrepareUpgradeCmd(), ) rootCmd.PersistentFlags().StringP(cosmovisor.FlagCosmovisorConfig, "c", "", "path to cosmovisor config file") diff --git a/tools/cosmovisor/cmd/cosmovisor/show_upgrade.go b/tools/cosmovisor/cmd/cosmovisor/show_upgrade.go new file mode 100644 index 000000000000..aa37fa36d4e7 --- /dev/null +++ b/tools/cosmovisor/cmd/cosmovisor/show_upgrade.go @@ -0,0 +1,42 @@ +package main + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + + "cosmossdk.io/tools/cosmovisor" +) + +func NewShowUpgradeInfoCmd() *cobra.Command { + return &cobra.Command{ + Use: "show-upgrade-info", + Short: "Display current upgrade-info.json from data directory", + SilenceUsage: false, + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + configPath, err := cmd.Flags().GetString(cosmovisor.FlagCosmovisorConfig) + if err != nil { + return fmt.Errorf("failed to get config flag: %w", err) + } + + cfg, err := cosmovisor.GetConfigFromFile(configPath) + if err != nil { + return err + } + + data, err := os.ReadFile(cfg.UpgradeInfoFilePath()) + if err != nil { + if os.IsNotExist(err) { + cmd.Printf("No upgrade info found at %s\n", cfg.UpgradeInfoFilePath()) + return nil + } + return fmt.Errorf("failed to read upgrade-info.json: %w", err) + } + + cmd.Println(string(data)) + return nil + }, + } +} diff --git a/tools/cosmovisor/go.mod b/tools/cosmovisor/go.mod index 9ae2df793f3e..d4b7d5328069 100644 --- a/tools/cosmovisor/go.mod +++ b/tools/cosmovisor/go.mod @@ -10,6 +10,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 + google.golang.org/grpc v1.67.1 ) require ( @@ -134,7 +135,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -165,7 +166,7 @@ require ( golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect @@ -174,8 +175,7 @@ require ( google.golang.org/api v0.192.0 // indirect google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/grpc v1.67.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/tools/cosmovisor/go.sum b/tools/cosmovisor/go.sum index 12625ab18f10..0fdc70f990e7 100644 --- a/tools/cosmovisor/go.sum +++ b/tools/cosmovisor/go.sum @@ -854,8 +854,8 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1142,8 +1142,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1516,8 +1516,8 @@ google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22du google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142/go.mod h1:G11eXq53iI5Q+kyNOmCvnzBaxEA2Q/Ik5Tj7nqBE8j4= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1559,8 +1559,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/tools/cosmovisor/testdata/download/cosmovisor/genesis/bin/autod b/tools/cosmovisor/testdata/download/cosmovisor/genesis/bin/autod index f2573651ad3f..c1b2348787ae 100755 --- a/tools/cosmovisor/testdata/download/cosmovisor/genesis/bin/autod +++ b/tools/cosmovisor/testdata/download/cosmovisor/genesis/bin/autod @@ -6,7 +6,13 @@ echo 'ERROR: UPGRADE "chain2" NEEDED at height: 49: zip_binary' # create upgrade info # this info contains directly information about binaries (in chain2->chain3 update we test with info containing a link to the file with an address for the new chain binary) -echo '{"name":"chain2","height":49,"info":"{\"binaries\":{\"linux/amd64\":\"https://github.com/cosmos/cosmos-sdk/raw/main/tools/cosmovisor/testdata/repo/chain2-zip_bin/autod.zip?checksum=sha256:13767eb0b57bf51a0f43d49f6277d5df97d4dec672dc39822d23a82fb8e70a7b\"}}"}' >$3 +cat > "$3" < $3 -echo '{"name":"chain3","height":936,"info":"https://github.com/cosmos/cosmos-sdk/raw/main/tools/cosmovisor/testdata/repo/ref_to_chain3-zip_dir.json?checksum=sha256:a95075f4dd83bc9f0f556ef73e64ce000f9bf3a6beeb9d4ae32f594b1417ef7a"}' >$3 +cat > "$3" < B[Execute Signature Verification Ante Handler] + B --> D{Is signer an x/accounts account?} + D -->|No| E[Continue with signature verification ante handler] + D -->|Yes| F{Does account handle MsgAuthenticate?} + F -->|No| G[Fail TX: Non-externally owned account] + F -->|Yes| H[Invoke signer account MsgAuthenticate] + E --> I[End] + G --> I + H --> I +``` + + +## Implementing the Authentication Interface + +To implement the Authentication interface, an account must handle the execution of `MsgAuthenticate`. Here's an example of how to do this: + +```go +package base + +import ( + "context" + "errors" + aa_interface_v1 "github.com/cosmos/cosmos-sdk/x/accounts/interfaces/account_abstraction/v1" + "github.com/cosmos/cosmos-sdk/x/accounts/std" +) + +// Account represents a base account structure +type Account struct { + // Account fields... +} + +// Authenticate implements the authentication flow for an abstracted base account. +func (a Account) Authenticate(ctx context.Context, msg *aa_interface_v1.MsgAuthenticate) (*aa_interface_v1.MsgAuthenticateResponse, error) { + if !accountstd.SenderIsAccountsModule(ctx) { + return nil, errors.New("unauthorized: only accounts module is allowed to call this") + } + // Implement your authentication logic here + // ... + return &aa_interface_v1.MsgAuthenticateResponse{}, nil +} + +// RegisterExecuteHandlers registers the execution handlers for the account. +func (a Account) RegisterExecuteHandlers(builder *accountstd.ExecuteBuilder) { + accountstd.RegisterExecuteHandler(builder, a.SwapPubKey) // Other handlers + accountstd.RegisterExecuteHandler(builder, a.Authenticate) // Implements the Authentication interface +} +``` + +### Key Implementation Points + +1. **Sender Verification**: Always verify that the sender is the x/accounts module. This prevents unauthorized accounts from triggering authentication. +2. **Authentication Safety**: Ensure your authentication mechanism is secure: + - Prevent replay attacks by making it impossible to reuse the same action with the same signature. + + +#### Implementation example + +Please find an example [here](./defaults/base/account.go). # Supporting Custom Accounts in the x/auth gRPC Server diff --git a/x/accounts/accountstd/exports.go b/x/accounts/accountstd/exports.go index 973a16c4b2cb..2ebe1acb82fb 100644 --- a/x/accounts/accountstd/exports.go +++ b/x/accounts/accountstd/exports.go @@ -34,6 +34,16 @@ type InitBuilder = implementation.InitBuilder // AccountCreatorFunc is the exported type of AccountCreatorFunc. type AccountCreatorFunc = implementation.AccountCreatorFunc +func DIAccount[A Interface](name string, constructor func(deps Dependencies) (A, error)) DepinjectAccount { + return DepinjectAccount{MakeAccount: AddAccount(name, constructor)} +} + +type DepinjectAccount struct { + MakeAccount AccountCreatorFunc +} + +func (DepinjectAccount) IsManyPerContainerType() {} + // Dependencies is the exported type of Dependencies. type Dependencies = implementation.Dependencies diff --git a/x/accounts/defaults/base/account.go b/x/accounts/defaults/base/account.go index 2bfd154a62ed..b227899aec75 100644 --- a/x/accounts/defaults/base/account.go +++ b/x/accounts/defaults/base/account.go @@ -33,6 +33,8 @@ var ( type Option func(a *Account) +func (Option) IsManyPerContainerType() {} + func NewAccount(name string, handlerMap *signing.HandlerMap, options ...Option) accountstd.AccountCreatorFunc { return func(deps accountstd.Dependencies) (string, accountstd.Interface, error) { acc := Account{ diff --git a/x/accounts/defaults/base/depinject/depinject.go b/x/accounts/defaults/base/depinject/depinject.go new file mode 100644 index 000000000000..6943b5dcaafd --- /dev/null +++ b/x/accounts/defaults/base/depinject/depinject.go @@ -0,0 +1,31 @@ +package basedepinject + +import ( + "cosmossdk.io/depinject" + "cosmossdk.io/x/accounts/accountstd" + "cosmossdk.io/x/accounts/defaults/base" + "cosmossdk.io/x/tx/signing" +) + +type Inputs struct { + depinject.In + + SignHandlersMap *signing.HandlerMap + Options []base.Option +} + +func ProvideAccount(in Inputs) accountstd.DepinjectAccount { + return accountstd.DepinjectAccount{MakeAccount: base.NewAccount("base", in.SignHandlersMap, in.Options...)} +} + +func ProvideSecp256K1PubKey() base.Option { + return base.WithSecp256K1PubKey() +} + +func ProvideCustomPubkey[T any, PT base.PubKeyG[T]]() base.Option { + return base.WithPubKey[T, PT]() +} + +func ProvideCustomPubKeyAndValidationFunc[T any, PT base.PubKeyG[T]](validateFn func(PT) error) base.Option { + return base.WithPubKeyWithValidationFunc(validateFn) +} diff --git a/x/accounts/defaults/base/go.mod b/x/accounts/defaults/base/go.mod index a65b80239cc2..ea0ef43187dc 100644 --- a/x/accounts/defaults/base/go.mod +++ b/x/accounts/defaults/base/go.mod @@ -5,7 +5,8 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 + cosmossdk.io/depinject v1.0.0 cosmossdk.io/x/accounts v0.0.0-20240913065641-0064ccbce64e cosmossdk.io/x/tx v0.13.3 github.com/cosmos/cosmos-sdk v0.53.0 @@ -19,11 +20,10 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 // indirect - cosmossdk.io/depinject v1.0.0 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.4.1 // indirect cosmossdk.io/math v1.3.0 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect @@ -120,7 +120,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -158,8 +158,8 @@ require ( golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/grpc v1.67.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect + google.golang.org/grpc v1.67.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect @@ -174,15 +174,7 @@ replace ( cosmossdk.io/collections => ../../../../collections // TODO tag new collections ASAP cosmossdk.io/store => ../../../../store cosmossdk.io/x/accounts => ../../. - cosmossdk.io/x/accounts/defaults/multisig => ../multisig - cosmossdk.io/x/auth => ../../../auth cosmossdk.io/x/bank => ../../../bank - cosmossdk.io/x/consensus => ../../../consensus - cosmossdk.io/x/distribution => ../../../distribution - cosmossdk.io/x/gov => ../../../gov - cosmossdk.io/x/mint => ../../../mint - cosmossdk.io/x/protocolpool => ../../../protocolpool - cosmossdk.io/x/slashing => ../../../slashing cosmossdk.io/x/staking => ../../../staking cosmossdk.io/x/tx => ../../../tx ) diff --git a/x/accounts/defaults/base/go.sum b/x/accounts/defaults/base/go.sum index b6b442434fe0..25dd6bf3bb3f 100644 --- a/x/accounts/defaults/base/go.sum +++ b/x/accounts/defaults/base/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -412,8 +412,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -634,8 +634,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -646,8 +646,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/accounts/defaults/lockup/depinject/depinject.go b/x/accounts/defaults/lockup/depinject/depinject.go new file mode 100644 index 000000000000..df26d6ce78aa --- /dev/null +++ b/x/accounts/defaults/lockup/depinject/depinject.go @@ -0,0 +1,31 @@ +package lockupdepinject + +import ( + "cosmossdk.io/x/accounts/accountstd" + "cosmossdk.io/x/accounts/defaults/lockup" +) + +func ProvideAllLockupAccounts() []accountstd.DepinjectAccount { + return []accountstd.DepinjectAccount{ + ProvidePeriodicLockingAccount(), + ProvideContinuousLockingAccount(), + ProvidePermanentLockingAccount(), + ProvideDelayedLockingAccount(), + } +} + +func ProvideContinuousLockingAccount() accountstd.DepinjectAccount { + return accountstd.DIAccount(lockup.CONTINUOUS_LOCKING_ACCOUNT, lockup.NewContinuousLockingAccount) +} + +func ProvidePeriodicLockingAccount() accountstd.DepinjectAccount { + return accountstd.DIAccount(lockup.PERIODIC_LOCKING_ACCOUNT, lockup.NewPeriodicLockingAccount) +} + +func ProvideDelayedLockingAccount() accountstd.DepinjectAccount { + return accountstd.DIAccount(lockup.DELAYED_LOCKING_ACCOUNT, lockup.NewDelayedLockingAccount) +} + +func ProvidePermanentLockingAccount() accountstd.DepinjectAccount { + return accountstd.DIAccount(lockup.PERMANENT_LOCKING_ACCOUNT, lockup.NewPermanentLockingAccount) +} diff --git a/x/accounts/defaults/lockup/go.mod b/x/accounts/defaults/lockup/go.mod index 53a5d0bd8552..2f66fafe70f0 100644 --- a/x/accounts/defaults/lockup/go.mod +++ b/x/accounts/defaults/lockup/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/x/accounts v0.0.0-20240226161501-23359a0b6d91 cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 cosmossdk.io/x/distribution v0.0.0-00010101000000-000000000000 @@ -22,7 +22,7 @@ require ( cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.4.1 cosmossdk.io/math v1.3.0 - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect cosmossdk.io/x/tx v0.13.3 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -98,7 +98,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -134,8 +134,8 @@ require ( golang.org/x/text v0.18.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/grpc v1.67.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect + google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.34.2 gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -151,13 +151,8 @@ replace ( cosmossdk.io/collections => ../../../../collections // TODO tag new collections ASAP cosmossdk.io/store => ../../../../store cosmossdk.io/x/accounts => ../../. - cosmossdk.io/x/accounts/defaults/multisig => ../multisig cosmossdk.io/x/bank => ../../../bank - cosmossdk.io/x/consensus => ../../../consensus cosmossdk.io/x/distribution => ../../../distribution - cosmossdk.io/x/gov => ../../../gov - cosmossdk.io/x/mint => ../../../mint - cosmossdk.io/x/protocolpool => ../../../protocolpool - cosmossdk.io/x/slashing => ../../../slashing cosmossdk.io/x/staking => ../../../staking + cosmossdk.io/x/tx => ../../../tx ) diff --git a/x/accounts/defaults/lockup/go.sum b/x/accounts/defaults/lockup/go.sum index 5ceb56777eaf..3609dca29bfb 100644 --- a/x/accounts/defaults/lockup/go.sum +++ b/x/accounts/defaults/lockup/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,10 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= -cosmossdk.io/x/tx v0.13.3 h1:Ha4mNaHmxBc6RMun9aKuqul8yHiL78EKJQ8g23Zf73g= -cosmossdk.io/x/tx v0.13.3/go.mod h1:I8xaHv0rhUdIvIdptKIqzYy27+n2+zBVaxO6fscFhys= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -361,8 +359,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -557,16 +555,16 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/accounts/defaults/multisig/account.go b/x/accounts/defaults/multisig/account.go index 62dbea15c3ba..e60476b33f6c 100644 --- a/x/accounts/defaults/multisig/account.go +++ b/x/accounts/defaults/multisig/account.go @@ -16,8 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" ) -var MULTISIG_ACCOUNT = "multisig-account" - var ( MembersPrefix = collections.NewPrefix(0) SequencePrefix = collections.NewPrefix(1) diff --git a/x/accounts/defaults/multisig/depinject/depinject.go b/x/accounts/defaults/multisig/depinject/depinject.go new file mode 100644 index 000000000000..785799b1a3dd --- /dev/null +++ b/x/accounts/defaults/multisig/depinject/depinject.go @@ -0,0 +1,10 @@ +package multisigdepinject + +import ( + "cosmossdk.io/x/accounts/accountstd" + "cosmossdk.io/x/accounts/defaults/multisig" +) + +func ProvideAccount() accountstd.DepinjectAccount { + return accountstd.DIAccount("multisig", multisig.NewAccount) +} diff --git a/x/accounts/defaults/multisig/go.mod b/x/accounts/defaults/multisig/go.mod index 6be3fc00bbd5..3d2600c39a02 100644 --- a/x/accounts/defaults/multisig/go.mod +++ b/x/accounts/defaults/multisig/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/math v1.3.0 cosmossdk.io/x/accounts v0.0.0-00010101000000-000000000000 cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 @@ -23,7 +23,7 @@ require ( cosmossdk.io/depinject v1.0.0 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.4.1 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect @@ -120,7 +120,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -158,8 +158,8 @@ require ( golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/grpc v1.67.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect + google.golang.org/grpc v1.67.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect @@ -175,12 +175,6 @@ replace ( cosmossdk.io/store => ../../../../store cosmossdk.io/x/accounts => ../../. cosmossdk.io/x/bank => ../../../bank - cosmossdk.io/x/consensus => ../../../consensus - cosmossdk.io/x/distribution => ../../../distribution - cosmossdk.io/x/gov => ../../../gov - cosmossdk.io/x/mint => ../../../mint - cosmossdk.io/x/protocolpool => ../../../protocolpool - cosmossdk.io/x/slashing => ../../../slashing cosmossdk.io/x/staking => ../../../staking cosmossdk.io/x/tx => ../../../tx ) diff --git a/x/accounts/defaults/multisig/go.sum b/x/accounts/defaults/multisig/go.sum index b6b442434fe0..25dd6bf3bb3f 100644 --- a/x/accounts/defaults/multisig/go.sum +++ b/x/accounts/defaults/multisig/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -412,8 +412,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -634,8 +634,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -646,8 +646,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/accounts/depinject.go b/x/accounts/depinject.go index 1110a0525a20..4bdcfdc6479c 100644 --- a/x/accounts/depinject.go +++ b/x/accounts/depinject.go @@ -1,19 +1,12 @@ package accounts import ( - "context" - modulev1 "cosmossdk.io/api/cosmos/accounts/module/v1" - signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" "cosmossdk.io/depinject/appconfig" "cosmossdk.io/x/accounts/accountstd" - baseaccount "cosmossdk.io/x/accounts/defaults/base" - "cosmossdk.io/x/accounts/defaults/lockup" - "cosmossdk.io/x/accounts/defaults/multisig" - "cosmossdk.io/x/tx/signing" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -39,8 +32,7 @@ type ModuleInputs struct { AddressCodec address.Codec Registry cdctypes.InterfaceRegistry - // TODO: Add a way to inject custom accounts. - // Currently only the base account is supported. + Accounts []accountstd.DepinjectAccount // at least one account must be provided } type ModuleOutputs struct { @@ -50,32 +42,19 @@ type ModuleOutputs struct { Module appmodule.AppModule } -var _ signing.SignModeHandler = directHandler{} - -type directHandler struct{} - -func (s directHandler) Mode() signingv1beta1.SignMode { - return signingv1beta1.SignMode_SIGN_MODE_DIRECT -} - -func (s directHandler) GetSignBytes(_ context.Context, _ signing.SignerData, _ signing.TxData) ([]byte, error) { - panic("not implemented") -} - func ProvideModule(in ModuleInputs) ModuleOutputs { - handler := directHandler{} - account := baseaccount.NewAccount("base", signing.NewHandlerMap(handler), baseaccount.WithSecp256K1PubKey()) - accountskeeper, err := NewKeeper( - in.Cdc, in.Environment, in.AddressCodec, in.Registry, account, - accountstd.AddAccount(lockup.CONTINUOUS_LOCKING_ACCOUNT, lockup.NewContinuousLockingAccount), - accountstd.AddAccount(lockup.PERIODIC_LOCKING_ACCOUNT, lockup.NewPeriodicLockingAccount), - accountstd.AddAccount(lockup.DELAYED_LOCKING_ACCOUNT, lockup.NewDelayedLockingAccount), - accountstd.AddAccount(lockup.PERMANENT_LOCKING_ACCOUNT, lockup.NewPermanentLockingAccount), - accountstd.AddAccount(multisig.MULTISIG_ACCOUNT, multisig.NewAccount), + accCreators := make([]accountstd.AccountCreatorFunc, len(in.Accounts)) + for i, acc := range in.Accounts { + accCreators[i] = acc.MakeAccount + } + + accountsKeeper, err := NewKeeper( + in.Cdc, in.Environment, in.AddressCodec, in.Registry, + accCreators..., ) if err != nil { panic(err) } - m := NewAppModule(in.Cdc, accountskeeper) - return ModuleOutputs{AccountsKeeper: accountskeeper, Module: m} + m := NewAppModule(in.Cdc, accountsKeeper) + return ModuleOutputs{AccountsKeeper: accountsKeeper, Module: m} } diff --git a/x/accounts/go.mod b/x/accounts/go.mod index acf653d3bd1b..3232de28c027 100644 --- a/x/accounts/go.mod +++ b/x/accounts/go.mod @@ -5,18 +5,16 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 - cosmossdk.io/x/accounts/defaults/base v0.0.0-00010101000000-000000000000 - cosmossdk.io/x/accounts/defaults/multisig v0.0.0-00010101000000-000000000000 cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 cosmossdk.io/x/tx v0.13.3 github.com/cosmos/cosmos-sdk v0.53.0 github.com/cosmos/gogoproto v1.7.0 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -33,10 +31,8 @@ require ( cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.4.1 // indirect cosmossdk.io/math v1.3.0 - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc // indirect - cosmossdk.io/x/accounts/defaults/lockup v0.0.0-20240417181816-5e7aae0db1f5 - cosmossdk.io/x/distribution v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -129,7 +125,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -166,7 +162,7 @@ require ( golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect @@ -181,13 +177,7 @@ replace ( cosmossdk.io/api => ../../api cosmossdk.io/collections => ../../collections cosmossdk.io/store => ../../store - cosmossdk.io/x/accounts/defaults/base => ./defaults/base // REMOVE this when - cosmossdk.io/x/accounts/defaults/lockup => ./defaults/lockup - cosmossdk.io/x/accounts/defaults/multisig => ./defaults/multisig cosmossdk.io/x/bank => ../bank - cosmossdk.io/x/distribution => ../distribution - cosmossdk.io/x/mint => ../mint - cosmossdk.io/x/slashing => ../slashing cosmossdk.io/x/staking => ../staking cosmossdk.io/x/tx => ../tx ) diff --git a/x/accounts/go.sum b/x/accounts/go.sum index 934d22e1cbe7..7588b565a0d7 100644 --- a/x/accounts/go.sum +++ b/x/accounts/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -412,8 +412,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -638,8 +638,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -650,8 +650,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/auth/ante/basic_test.go b/x/auth/ante/basic_test.go index fd0dc29c1f0c..1a5687b92f62 100644 --- a/x/auth/ante/basic_test.go +++ b/x/auth/ante/basic_test.go @@ -99,7 +99,7 @@ func TestValidateMemo(t *testing.T) { } func TestConsumeGasForTxSize(t *testing.T) { - t.Skip() // TODO(@julienrbrt) Fix after https://github.com/cosmos/cosmos-sdk/pull/20072 + t.Skip() // TO FIX BEFORE 0.52 FINAL. suite := SetupTestSuite(t, true) diff --git a/x/auth/autocli.go b/x/auth/autocli.go index 676a3e4af702..0dabf876a56f 100644 --- a/x/auth/autocli.go +++ b/x/auth/autocli.go @@ -38,7 +38,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { RpcMethod: "AccountAddressByID", Use: "address-by-acc-num ", Short: "Query account address by account number", - PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "id"}}, + PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "account_id"}}, }, { RpcMethod: "ModuleAccounts", diff --git a/x/auth/migrations/legacytx/stdtx_test.go b/x/auth/migrations/legacytx/stdtx_test.go index 83909d45d6ec..27156448d9ba 100644 --- a/x/auth/migrations/legacytx/stdtx_test.go +++ b/x/auth/migrations/legacytx/stdtx_test.go @@ -44,7 +44,7 @@ func TestStdSignBytes(t *testing.T) { Amount: []*basev1beta1.Coin{{Denom: "atom", Amount: "150"}}, GasLimit: 100000, } - msgStr := fmt.Sprintf(`{"type":"testpb/TestMsg","value":{"decField":"0","signers":["%s"]}}`, addr) + msgStr := fmt.Sprintf(`{"type":"testpb/TestMsg","value":{"decField":"0.000000000000000000","signers":["%s"]}}`, addr) tests := []struct { name string args args diff --git a/x/auth/tx/config/depinject.go b/x/auth/tx/config/depinject.go index bda9ca8735e7..239ab496517f 100644 --- a/x/auth/tx/config/depinject.go +++ b/x/auth/tx/config/depinject.go @@ -49,9 +49,10 @@ type ModuleInputs struct { type ModuleOutputs struct { depinject.Out - BaseAppOption runtime.BaseAppOption // This is only useful for chains using baseapp. - TxConfig client.TxConfig - TxConfigOptions tx.ConfigOptions + BaseAppOption runtime.BaseAppOption // This is only useful for chains using baseapp. + TxConfig client.TxConfig + TxConfigOptions tx.ConfigOptions + TxSigningHandlerMap *txsigning.HandlerMap } func ProvideProtoRegistry() txsigning.ProtoFileResolver { @@ -89,8 +90,9 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { app.SetTxDecoder(txConfig.TxDecoder()) app.SetTxEncoder(txConfig.TxEncoder()) }, - TxConfig: txConfig, - TxConfigOptions: txConfigOptions, + TxConfig: txConfig, + TxConfigOptions: txConfigOptions, + TxSigningHandlerMap: txConfig.SignModeHandler(), } } diff --git a/x/auth/vesting/types/period.go b/x/auth/vesting/types/period.go index 174bd3437a1e..f9c31a2601c4 100644 --- a/x/auth/vesting/types/period.go +++ b/x/auth/vesting/types/period.go @@ -42,7 +42,7 @@ func (p Periods) TotalAmount() sdk.Coins { // String implements the fmt.Stringer interface func (p Periods) String() string { - periodsListString := make([]string, len(p)) + periodsListString := make([]string, 0, len(p)) for _, period := range p { periodsListString = append(periodsListString, period.String()) } diff --git a/x/auth/vesting/types/period_test.go b/x/auth/vesting/types/period_test.go new file mode 100644 index 000000000000..636e6255a0d0 --- /dev/null +++ b/x/auth/vesting/types/period_test.go @@ -0,0 +1,49 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" +) + +func TestPeriodsString(t *testing.T) { + tests := []struct { + name string + periods types.Periods + want string + }{ + { + "empty slice", + nil, + "Vesting Periods:", + }, + { + "1 period", + types.Periods{ + {Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("feeatom", 500), sdk.NewInt64Coin("statom", 50)}}, + }, + "Vesting Periods:\n\t\t" + `length:43200 amount: amount:`, + }, + { + "many", + types.Periods{ + {Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 500), sdk.NewInt64Coin(stakeDenom, 50)}}, + {Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 250), sdk.NewInt64Coin(stakeDenom, 25)}}, + {Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin(feeDenom, 100), sdk.NewInt64Coin(stakeDenom, 15)}}, + }, + "Vesting Periods:\n\t\t" + `length:43200 amount: amount: , ` + + `length:21600 amount: amount: , ` + + `length:21600 amount: amount:`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.periods.String() + if got != tt.want { + t.Fatalf("Mismatch in values:\n\tGot: %q\n\tWant: %q", got, tt.want) + } + }) + } +} diff --git a/x/auth/vesting/types/vesting.pb.go b/x/auth/vesting/types/vesting.pb.go index c5c2a54a8295..86bedb042b1c 100644 --- a/x/auth/vesting/types/vesting.pb.go +++ b/x/auth/vesting/types/vesting.pb.go @@ -4,11 +4,11 @@ package types import ( - types "github.com/cosmos/cosmos-sdk/x/auth/types" fmt "fmt" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types1 "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + types "github.com/cosmos/cosmos-sdk/x/auth/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" diff --git a/x/authz/CHANGELOG.md b/x/authz/CHANGELOG.md index 6d3a4ccb1ea2..a898236bcdb1 100644 --- a/x/authz/CHANGELOG.md +++ b/x/authz/CHANGELOG.md @@ -37,6 +37,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* [#21632](https://github.com/cosmos/cosmos-sdk/pull/21632) `NewKeeper` now takes `address.Codec` instead of `authKeeper`. * [#21044](https://github.com/cosmos/cosmos-sdk/pull/21044) `k.DispatchActions` returns a slice of byte slices of proto marshaled anys instead of a slice of byte slices of `sdk.Result.Data`. * [#20502](https://github.com/cosmos/cosmos-sdk/pull/20502) `Accept` on the `Authorization` interface now expects the authz environment in the `context.Context`. This is already done when `Accept` is called by `k.DispatchActions`, but should be done manually if `Accept` is called directly. * [#19783](https://github.com/cosmos/cosmos-sdk/pull/19783) Removes the use of Accounts String() method diff --git a/x/authz/README.md b/x/authz/README.md index c4752c2eddc6..405bd5427e6a 100644 --- a/x/authz/README.md +++ b/x/authz/README.md @@ -38,12 +38,12 @@ The `x/authz` module defines interfaces and messages grant authorizations to per on behalf of one account to other accounts. The design is defined in the [ADR 030](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-030-authz-module.md). A *grant* is an allowance to execute a Msg by the grantee on behalf of the granter. -Authorization is an interface that must be implemented by a concrete authorization logic to validate and execute grants. Authorizations are extensible and can be defined for any Msg service method even outside of the module where the Msg method is defined. See the `SendAuthorization` example in the next section for more details. +Authorization is an interface that must be implemented by a concrete authorization logic to validate and execute grants. Authorizations are extensible and can be defined for any Msg service method, even if the Msg method is defined outside of the module. See the `SendAuthorization` example in the next section for more details. -**Note:** The authz module is different from the [auth (authentication)](../modules/auth/) module that is responsible for specifying the base transaction and account types. +**Note:** The authz module is different from the [auth (authentication)](../modules/auth/) module, which is responsible for specifying the base transaction and account types. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/authz/authorizations.go#L11-L25 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/authorizations.go#L14-L28 ``` ### Built-in Authorizations @@ -55,11 +55,11 @@ The Cosmos SDK `x/authz` module comes with following authorization types: `GenericAuthorization` implements the `Authorization` interface that gives unrestricted permission to execute the provided Msg on behalf of granter's account. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/authz.proto#L14-L22 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/proto/cosmos/authz/v1beta1/authz.proto#L14-L22 ``` ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/authz/generic_authorization.go#L16-L29 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/generic_authorization.go#L18-L34 ``` * `msg` stores Msg type URL. @@ -72,11 +72,11 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/authz/generic_authorizat * It takes an (optional) `AllowList` that specifies to which addresses a grantee can send token. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/authz.proto#L11-L30 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/bank/proto/cosmos/bank/v1beta1/authz.proto#L11-L29 ``` ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/bank/types/send_authorization.go#L29-L62 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/bank/types/send_authorization.go#L33-L73 ``` * `spend_limit` keeps track of how many coins are left in the authorization. @@ -84,21 +84,21 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/bank/types/send_authoriz #### StakeAuthorization -`StakeAuthorization` implements the `Authorization` interface for messages in the [staking module](https://docs.cosmos.network/main/build/modules/staking). It takes an `AuthorizationType` to specify whether you want to authorise delegating, undelegating or redelegating (i.e. these have to be authorised separately). It also takes an optional `MaxTokens` that keeps track of a limit to the amount of tokens that can be delegated/undelegated/redelegated. If left empty, the amount is unlimited. Additionally, this Msg takes an `AllowList` or a `DenyList`, which allows you to select which validators you allow or deny grantees to stake with. +`StakeAuthorization` implements the `Authorization` interface for messages in the [staking module](https://docs.cosmos.network/main/build/modules/staking). It takes an `AuthorizationType` to specify whether you want to authorize delegation, undelegation, redelegation or cancel unbonding delegation, each of which must be authorized separately. It also takes an optional `MaxTokens` that keeps track of a limit to the amount of tokens that can be delegated/undelegated/redelegated. If left empty, the amount is unlimited. Additionally, this Msg takes an `AllowList` or a `DenyList`, enabling you to specify which validators the grantee can or cannot stake with. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/staking/v1beta1/authz.proto#L11-L35 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/staking/proto/cosmos/staking/v1beta1/authz.proto#L11-L34 ``` ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/staking/types/authz.go#L15-L35 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/staking/types/authz.go#L78-L166 ``` ### Gas -In order to prevent DoS attacks, granting `StakeAuthorization`s with `x/authz` incurs gas. `StakeAuthorization` allows you to authorize another account to delegate, undelegate, or redelegate to validators. The authorizer can define a list of validators they allow or deny delegations to. The Cosmos SDK iterates over these lists and charge 10 gas for each validator in both of the lists. +To prevent DoS attacks, granting `StakeAuthorization`s with `x/authz` incurs gas. `StakeAuthorization` allows you to authorize another account to delegate, undelegate, or redelegate tokens to validators. The granter can define a list of validators for which they allow or deny delegations. The Cosmos SDK then iterates over these lists and charge 10 gas for each validator included in both lists. -Since the state maintaining a list for granter, grantee pair with same expiration, we are iterating over the list to remove the grant (in case of any revoke of particular `msgType`) from the list and we are charging 20 gas per iteration. +Since the state maintains a list of granter-grantee pairs with same expiration, we iterate over this list to remove the grant from the list (in case of any revoke of particular `msgType`), charging 20 gas for each iteration. ## State @@ -111,17 +111,17 @@ Grants are identified by combining granter address (the address bytes of the gra The grant object encapsulates an `Authorization` type and an expiration timestamp: ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/authz.proto#L24-L32 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/proto/cosmos/authz/v1beta1/authz.proto#L24-L32 ``` ### GrantQueue We are maintaining a queue for authz pruning. Whenever a grant is created, an item will be added to `GrantQueue` with a key of expiration, granter, grantee. -In `EndBlock` (which runs for every block) we continuously check and prune the expired grants by forming a prefix key with current blocktime that passed the stored expiration in `GrantQueue`, we iterate through all the matched records from `GrantQueue` and delete them from the `GrantQueue` & `Grant`s store. +In `EndBlock` (which runs for every block) we continuously check and prune the expired grants by forming a prefix key with current blocktime that passed the stored expiration in `GrantQueue`, we iterate through all the matched records from `GrantQueue` and delete maximum of 200 grants from the `GrantQueue` & `Grant`s store for each run. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/5f4ddc6f80f9707320eec42182184207fff3833a/x/authz/keeper/keeper.go#L378-L403 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/keeper/keeper.go#L479-L520 ``` * GrantQueue: `0x02 | expiration_bytes | granter_address_len (1 byte) | granter_address_bytes | grantee_address_len (1 byte) | grantee_address_bytes -> ProtocolBuffer(GrantQueueItem)` @@ -129,7 +129,7 @@ https://github.com/cosmos/cosmos-sdk/blob/5f4ddc6f80f9707320eec42182184207fff383 The `expiration_bytes` are the expiration date in UTC with the format `"2006-01-02T15:04:05.000000000"`. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/x/authz/keeper/keys.go#L77-L93 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/keeper/keys.go#L84-L100 ``` The `GrantQueueItem` object contains the list of type urls between granter and grantee that expire at the time indicated in the key. @@ -146,7 +146,7 @@ If there is already a grant for the `(granter, grantee, Authorization)` triple, An authorization grant for authz `MsgGrant` is not allowed and will return an error. This is for preventing user from accidentally authorizing their entire account to a different account. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/tx.proto#L35-L45 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/proto/cosmos/authz/v1beta1/tx.proto#L45-L55 ``` The message handling should fail if: @@ -161,7 +161,7 @@ The message handling should fail if: A grant can be removed with the `MsgRevoke` message. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/tx.proto#L69-L78 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/proto/cosmos/authz/v1beta1/tx.proto#L79-L88 ``` The message handling should fail if: @@ -176,7 +176,7 @@ NOTE: The `MsgExec` message removes a grant if the grant has expired. The `MsgRevokeAll` message revokes all grants issued by the specified granter. This is useful for quickly removing all authorizations granted by a single granter without specifying individual message types or grantees. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/tree/main/x/authz/proto/cosmos/authz/v1beta1/tx.proto#L93-L100 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/proto/cosmos/authz/v1beta1/tx.proto#L93-L100 ``` The message handling should fail if: @@ -189,7 +189,7 @@ The message handling should fail if: When a grantee wants to execute a transaction on behalf of a granter, they must send `MsgExec`. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/authz/v1beta1/tx.proto#L52-L63 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/authz/proto/cosmos/authz/v1beta1/tx.proto#L60-L72 ``` The message handling should fail if: @@ -314,6 +314,20 @@ Example: simd tx authz revoke cosmos1.. /cosmos.bank.v1beta1.MsgSend --from=cosmos1.. ``` +##### revoke-all + +The `revoke-all` command allows a granter to revoke all authorizations created by the granter. + +```bash +simd tx authz revoke-all --from=[granter] [flags] +``` + +Example: + +```bash +simd tx authz revoke-all --from=cosmos1.. +``` + ### gRPC A user can query the `authz` module using gRPC endpoints. @@ -335,27 +349,6 @@ grpcurl -plaintext \ cosmos.authz.v1beta1.Query/Grants ``` -Example Output: - -```bash -{ - "grants": [ - { - "authorization": { - "@type": "/cosmos.bank.v1beta1.SendAuthorization", - "spendLimit": [ - { - "denom":"stake", - "amount":"100" - } - ] - }, - "expiration": "2022-01-01T00:00:00Z" - } - ] -} -``` - ### REST A user can query the `authz` module using REST endpoints. @@ -369,25 +362,3 @@ Example: ```bash curl "localhost:1317/cosmos/authz/v1beta1/grants?granter=cosmos1..&grantee=cosmos1..&msg_type_url=/cosmos.bank.v1beta1.MsgSend" ``` - -Example Output: - -```bash -{ - "grants": [ - { - "authorization": { - "@type": "/cosmos.bank.v1beta1.SendAuthorization", - "spend_limit": [ - { - "denom": "stake", - "amount": "100" - } - ] - }, - "expiration": "2022-01-01T00:00:00Z" - } - ], - "pagination": null -} -``` diff --git a/x/authz/expected_keepers.go b/x/authz/expected_keepers.go index fad3b4b74467..b2ee6bd16fbf 100644 --- a/x/authz/expected_keepers.go +++ b/x/authz/expected_keepers.go @@ -3,18 +3,9 @@ package authz import ( "context" - "cosmossdk.io/core/address" - sdk "github.com/cosmos/cosmos-sdk/types" ) -// AccountKeeper defines the expected account keeper (noalias) -type AccountKeeper interface { - AddressCodec() address.Codec - GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI - NewAccountWithAddress(ctx context.Context, addr sdk.AccAddress) sdk.AccountI -} - // BankKeeper defines the expected interface needed to retrieve account balances. type BankKeeper interface { SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins diff --git a/x/authz/go.mod b/x/authz/go.mod index ea249f9ae63d..a40b44423b98 100644 --- a/x/authz/go.mod +++ b/x/authz/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.4.1 @@ -22,7 +22,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -30,7 +30,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/collections v0.4.0 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect @@ -119,7 +119,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -155,7 +155,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/x/authz/go.sum b/x/authz/go.sum index 934d22e1cbe7..7588b565a0d7 100644 --- a/x/authz/go.sum +++ b/x/authz/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -412,8 +412,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -638,8 +638,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -650,8 +650,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/authz/keeper/genesis.go b/x/authz/keeper/genesis.go index c669f2aa2622..45762713b61d 100644 --- a/x/authz/keeper/genesis.go +++ b/x/authz/keeper/genesis.go @@ -18,11 +18,11 @@ func (k Keeper) InitGenesis(ctx context.Context, data *authz.GenesisState) error continue } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(entry.Grantee) + grantee, err := k.addrCdc.StringToBytes(entry.Grantee) if err != nil { return err } - granter, err := k.authKeeper.AddressCodec().StringToBytes(entry.Granter) + granter, err := k.addrCdc.StringToBytes(entry.Granter) if err != nil { return err } @@ -44,11 +44,11 @@ func (k Keeper) InitGenesis(ctx context.Context, data *authz.GenesisState) error func (k Keeper) ExportGenesis(ctx context.Context) (*authz.GenesisState, error) { var entries []authz.GrantAuthorization err := k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant authz.Grant) (bool, error) { - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return false, err } - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return false, err } diff --git a/x/authz/keeper/genesis_test.go b/x/authz/keeper/genesis_test.go index 6cc9db972025..53b96a8f94be 100644 --- a/x/authz/keeper/genesis_test.go +++ b/x/authz/keeper/genesis_test.go @@ -4,7 +4,6 @@ import ( "testing" "time" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/suite" "cosmossdk.io/core/header" @@ -14,11 +13,10 @@ import ( storetypes "cosmossdk.io/store/types" "cosmossdk.io/x/authz/keeper" authzmodule "cosmossdk.io/x/authz/module" - authztestutil "cosmossdk.io/x/authz/testutil" bank "cosmossdk.io/x/bank/types" "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec/address" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/runtime" @@ -37,11 +35,10 @@ var ( type GenesisTestSuite struct { suite.Suite - ctx sdk.Context - keeper keeper.Keeper - baseApp *baseapp.BaseApp - accountKeeper *authztestutil.MockAccountKeeper - encCfg moduletestutil.TestEncodingConfig + ctx sdk.Context + keeper keeper.Keeper + baseApp *baseapp.BaseApp + encCfg moduletestutil.TestEncodingConfig } func (suite *GenesisTestSuite) SetupTest() { @@ -52,11 +49,6 @@ func (suite *GenesisTestSuite) SetupTest() { suite.encCfg = moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, authzmodule.AppModule{}) - // gomock initializations - ctrl := gomock.NewController(suite.T()) - suite.accountKeeper = authztestutil.NewMockAccountKeeper(ctrl) - suite.accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() - suite.baseApp = baseapp.NewBaseApp( "authz", log.NewNopLogger(), @@ -71,7 +63,8 @@ func (suite *GenesisTestSuite) SetupTest() { msr.SetInterfaceRegistry(suite.encCfg.InterfaceRegistry) env := runtime.NewEnvironment(storeService, coretesting.NewNopLogger(), runtime.EnvWithMsgRouterService(msr)) - suite.keeper = keeper.NewKeeper(env, suite.encCfg.Codec, suite.accountKeeper) + addrCdc := addresscodec.NewBech32Codec("cosmos") + suite.keeper = keeper.NewKeeper(env, suite.encCfg.Codec, addrCdc) } func (suite *GenesisTestSuite) TestImportExportGenesis() { diff --git a/x/authz/keeper/grpc_query.go b/x/authz/keeper/grpc_query.go index 89cb8ac67d65..f3bba8f1aed6 100644 --- a/x/authz/keeper/grpc_query.go +++ b/x/authz/keeper/grpc_query.go @@ -25,12 +25,12 @@ func (k Keeper) Grants(ctx context.Context, req *authz.QueryGrantsRequest) (*aut return nil, status.Errorf(codes.InvalidArgument, "empty request") } - granter, err := k.authKeeper.AddressCodec().StringToBytes(req.Granter) + granter, err := k.addrCdc.StringToBytes(req.Granter) if err != nil { return nil, err } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(req.Grantee) + grantee, err := k.addrCdc.StringToBytes(req.Grantee) if err != nil { return nil, err } @@ -95,7 +95,7 @@ func (k Keeper) GranterGrants(ctx context.Context, req *authz.QueryGranterGrants return nil, status.Errorf(codes.InvalidArgument, "empty request") } - granter, err := k.authKeeper.AddressCodec().StringToBytes(req.Granter) + granter, err := k.addrCdc.StringToBytes(req.Granter) if err != nil { return nil, err } @@ -116,7 +116,7 @@ func (k Keeper) GranterGrants(ctx context.Context, req *authz.QueryGranterGrants grantee := firstAddressFromGrantStoreKey(key) - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return nil, err } @@ -146,7 +146,7 @@ func (k Keeper) GranteeGrants(ctx context.Context, req *authz.QueryGranteeGrants return nil, status.Errorf(codes.InvalidArgument, "empty request") } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(req.Grantee) + grantee, err := k.addrCdc.StringToBytes(req.Grantee) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (k Keeper) GranteeGrants(ctx context.Context, req *authz.QueryGranteeGrants return nil, status.Error(codes.Internal, err.Error()) } - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return nil, err } diff --git a/x/authz/keeper/grpc_query_test.go b/x/authz/keeper/grpc_query_test.go index b8d5042a96c8..d4239b0f854c 100644 --- a/x/authz/keeper/grpc_query_test.go +++ b/x/authz/keeper/grpc_query_test.go @@ -21,9 +21,9 @@ func (suite *TestSuite) TestGRPCQueryAuthorization() { expAuthorization authz.Authorization ) - addr0, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[0]) + addr0, err := suite.addrCdc.BytesToString(addrs[0]) suite.Require().NoError(err) - addr1, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[1]) + addr1, err := suite.addrCdc.BytesToString(addrs[1]) suite.Require().NoError(err) testCases := []struct { @@ -137,7 +137,7 @@ func (suite *TestSuite) TestGRPCQueryGranterGrants() { require := suite.Require() queryClient, addrs := suite.queryClient, suite.addrs - addr0, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[0]) + addr0, err := suite.addrCdc.BytesToString(addrs[0]) suite.Require().NoError(err) testCases := []struct { @@ -209,9 +209,9 @@ func (suite *TestSuite) TestGRPCQueryGranteeGrants() { require := suite.Require() queryClient, addrs := suite.queryClient, suite.addrs - addr0, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[0]) + addr0, err := suite.addrCdc.BytesToString(addrs[0]) suite.Require().NoError(err) - addr2, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[2]) + addr2, err := suite.addrCdc.BytesToString(addrs[2]) suite.Require().NoError(err) testCases := []struct { @@ -299,7 +299,7 @@ func (suite *TestSuite) createSendAuthorization(grantee, granter sdk.AccAddress) func (suite *TestSuite) createSendAuthorizationWithAllowList(grantee, granter sdk.AccAddress) authz.Authorization { exp := suite.ctx.HeaderInfo().Time.Add(time.Hour) newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100)) - addr, err := suite.accountKeeper.AddressCodec().BytesToString(suite.addrs[5]) + addr, err := suite.addrCdc.BytesToString(suite.addrs[5]) suite.Require().NoError(err) authorization := &banktypes.SendAuthorization{SpendLimit: newCoins, AllowList: []string{addr}} err = suite.authzKeeper.SaveGrant(suite.ctx, grantee, granter, authorization, &exp) diff --git a/x/authz/keeper/keeper.go b/x/authz/keeper/keeper.go index ecfed97ee7cf..087f73aafcf3 100644 --- a/x/authz/keeper/keeper.go +++ b/x/authz/keeper/keeper.go @@ -9,6 +9,7 @@ import ( gogoproto "github.com/cosmos/gogoproto/proto" gogoprotoany "github.com/cosmos/gogoproto/types/any" + "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" corecontext "cosmossdk.io/core/context" errorsmod "cosmossdk.io/errors" @@ -30,16 +31,16 @@ const gasCostPerIteration = uint64(20) type Keeper struct { appmodule.Environment - cdc codec.Codec - authKeeper authz.AccountKeeper + cdc codec.Codec + addrCdc address.Codec } // NewKeeper constructs a message authorization Keeper -func NewKeeper(env appmodule.Environment, cdc codec.Codec, ak authz.AccountKeeper) Keeper { +func NewKeeper(env appmodule.Environment, cdc codec.Codec, addrCdc address.Codec) Keeper { return Keeper{ Environment: env, cdc: cdc, - authKeeper: ak, + addrCdc: addrCdc, } } @@ -206,11 +207,11 @@ func (k Keeper) SaveGrant(ctx context.Context, grantee, granter sdk.AccAddress, return err } - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return err } - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return err } @@ -229,12 +230,12 @@ func (k Keeper) DeleteGrant(ctx context.Context, grantee, granter sdk.AccAddress skey := grantStoreKey(grantee, granter, msgType) grant, found := k.getGrant(ctx, skey) if !found { - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return errorsmod.Wrapf(authz.ErrNoAuthorizationFound, "could not convert granter address to string") } - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return errorsmod.Wrapf(authz.ErrNoAuthorizationFound, "could not convert grantee address to string") @@ -255,11 +256,11 @@ func (k Keeper) DeleteGrant(ctx context.Context, grantee, granter sdk.AccAddress return err } - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return err } - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return err } @@ -291,7 +292,7 @@ func (k Keeper) DeleteAllGrants(ctx context.Context, granter sdk.AccAddress) err } } - grantAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + grantAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return err } diff --git a/x/authz/keeper/keeper_test.go b/x/authz/keeper/keeper_test.go index dcfd710fc264..f977ffef22fb 100644 --- a/x/authz/keeper/keeper_test.go +++ b/x/authz/keeper/keeper_test.go @@ -9,6 +9,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/suite" + "cosmossdk.io/core/address" "cosmossdk.io/core/header" coretesting "cosmossdk.io/core/testing" "cosmossdk.io/log" @@ -20,7 +21,7 @@ import ( banktypes "cosmossdk.io/x/bank/types" "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec/address" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" @@ -39,15 +40,15 @@ var ( type TestSuite struct { suite.Suite - ctx sdk.Context - addrs []sdk.AccAddress - authzKeeper authzkeeper.Keeper - accountKeeper *authztestutil.MockAccountKeeper - bankKeeper *authztestutil.MockBankKeeper - baseApp *baseapp.BaseApp - encCfg moduletestutil.TestEncodingConfig - queryClient authz.QueryClient - msgSrvr authz.MsgServer + ctx sdk.Context + addrs []sdk.AccAddress + authzKeeper authzkeeper.Keeper + bankKeeper *authztestutil.MockBankKeeper + baseApp *baseapp.BaseApp + encCfg moduletestutil.TestEncodingConfig + queryClient authz.QueryClient + msgSrvr authz.MsgServer + addrCdc address.Codec } func (s *TestSuite) SetupTest() { @@ -70,16 +71,13 @@ func (s *TestSuite) SetupTest() { // gomock initializations ctrl := gomock.NewController(s.T()) - s.accountKeeper = authztestutil.NewMockAccountKeeper(ctrl) - - s.accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() - s.bankKeeper = authztestutil.NewMockBankKeeper(ctrl) banktypes.RegisterInterfaces(s.encCfg.InterfaceRegistry) banktypes.RegisterMsgServer(s.baseApp.MsgServiceRouter(), s.bankKeeper) env := runtime.NewEnvironment(storeService, coretesting.NewNopLogger(), runtime.EnvWithQueryRouterService(s.baseApp.GRPCQueryRouter()), runtime.EnvWithMsgRouterService(s.baseApp.MsgServiceRouter())) - s.authzKeeper = authzkeeper.NewKeeper(env, s.encCfg.Codec, s.accountKeeper) + s.addrCdc = addresscodec.NewBech32Codec("cosmos") + s.authzKeeper = authzkeeper.NewKeeper(env, s.encCfg.Codec, s.addrCdc) queryHelper := baseapp.NewQueryServerTestHelper(s.ctx, s.encCfg.InterfaceRegistry) authz.RegisterQueryServer(queryHelper, s.authzKeeper) @@ -183,7 +181,7 @@ func (s *TestSuite) TestKeeperIter() { granteeAddr := addrs[1] granter2Addr := addrs[2] e := ctx.HeaderInfo().Time.AddDate(1, 0, 0) - sendAuthz := banktypes.NewSendAuthorization(coins100, nil, s.accountKeeper.AddressCodec()) + sendAuthz := banktypes.NewSendAuthorization(coins100, nil, s.addrCdc) err := s.authzKeeper.SaveGrant(ctx, granteeAddr, granterAddr, sendAuthz, &e) s.Require().NoError(err) @@ -207,7 +205,7 @@ func (s *TestSuite) TestKeeperGranterGrantsIter() { grantee2Addr := addrs[3] grantee3Addr := addrs[4] e := ctx.HeaderInfo().Time.AddDate(1, 0, 0) - sendAuthz := banktypes.NewSendAuthorization(coins100, nil, s.accountKeeper.AddressCodec()) + sendAuthz := banktypes.NewSendAuthorization(coins100, nil, s.addrCdc) err := s.authzKeeper.SaveGrant(ctx, granteeAddr, granterAddr, sendAuthz, &e) s.Require().NoError(err) @@ -238,13 +236,13 @@ func (s *TestSuite) TestDispatchAction() { granterAddr := addrs[0] granteeAddr := addrs[1] - granterStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[0]) + granterStrAddr, err := s.addrCdc.BytesToString(addrs[0]) s.Require().NoError(err) - granteeStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[1]) + granteeStrAddr, err := s.addrCdc.BytesToString(addrs[1]) s.Require().NoError(err) - recipientStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[2]) + recipientStrAddr, err := s.addrCdc.BytesToString(addrs[2]) s.Require().NoError(err) - a := banktypes.NewSendAuthorization(coins100, nil, s.accountKeeper.AddressCodec()) + a := banktypes.NewSendAuthorization(coins100, nil, s.addrCdc) testCases := []struct { name string @@ -402,11 +400,11 @@ func (s *TestSuite) TestDispatchedEvents() { addrs := s.addrs granterAddr := addrs[0] granteeAddr := addrs[1] - granterStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[0]) + granterStrAddr, err := s.addrCdc.BytesToString(addrs[0]) s.Require().NoError(err) - granteeStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[1]) + granteeStrAddr, err := s.addrCdc.BytesToString(addrs[1]) s.Require().NoError(err) - recipientStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[2]) + recipientStrAddr, err := s.addrCdc.BytesToString(addrs[2]) s.Require().NoError(err) expiration := s.ctx.HeaderInfo().Time.Add(1 * time.Second) // must be in the future @@ -505,7 +503,7 @@ func (s *TestSuite) TestGetAuthorization() { genAuthMulti := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgMultiSend{})) genAuthSend := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgSend{})) - sendAuth := banktypes.NewSendAuthorization(coins10, nil, s.accountKeeper.AddressCodec()) + sendAuth := banktypes.NewSendAuthorization(coins10, nil, s.addrCdc) start := s.ctx.HeaderInfo().Time expired := start.Add(time.Duration(1) * time.Second) diff --git a/x/authz/keeper/msg_server.go b/x/authz/keeper/msg_server.go index 1722a4f0bb14..ecacf6e50521 100644 --- a/x/authz/keeper/msg_server.go +++ b/x/authz/keeper/msg_server.go @@ -20,12 +20,12 @@ func (k Keeper) Grant(ctx context.Context, msg *authz.MsgGrant) (*authz.MsgGrant return nil, authz.ErrGranteeIsGranter } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(msg.Grantee) + grantee, err := k.addrCdc.StringToBytes(msg.Grantee) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid grantee address: %s", err) } - granter, err := k.authKeeper.AddressCodec().StringToBytes(msg.Granter) + granter, err := k.addrCdc.StringToBytes(msg.Granter) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid granter address: %s", err) } @@ -64,12 +64,12 @@ func (k Keeper) Revoke(ctx context.Context, msg *authz.MsgRevoke) (*authz.MsgRev return nil, authz.ErrGranteeIsGranter } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(msg.Grantee) + grantee, err := k.addrCdc.StringToBytes(msg.Grantee) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid grantee address: %s", err) } - granter, err := k.authKeeper.AddressCodec().StringToBytes(msg.Granter) + granter, err := k.addrCdc.StringToBytes(msg.Granter) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid granter address: %s", err) } @@ -87,7 +87,7 @@ func (k Keeper) Revoke(ctx context.Context, msg *authz.MsgRevoke) (*authz.MsgRev // RevokeAll implements the MsgServer.RevokeAll method. func (k Keeper) RevokeAll(ctx context.Context, msg *authz.MsgRevokeAll) (*authz.MsgRevokeAllResponse, error) { - granter, err := k.authKeeper.AddressCodec().StringToBytes(msg.Granter) + granter, err := k.addrCdc.StringToBytes(msg.Granter) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid granter address: %s", err) } @@ -105,7 +105,7 @@ func (k Keeper) Exec(ctx context.Context, msg *authz.MsgExec) (*authz.MsgExecRes return nil, errors.New("empty address string is not allowed") } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(msg.Grantee) + grantee, err := k.addrCdc.StringToBytes(msg.Grantee) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid grantee address: %s", err) } diff --git a/x/authz/keeper/msg_server_test.go b/x/authz/keeper/msg_server_test.go index 2958e45a9915..fe19fb4247da 100644 --- a/x/authz/keeper/msg_server_test.go +++ b/x/authz/keeper/msg_server_test.go @@ -3,23 +3,17 @@ package keeper_test import ( "time" - "github.com/golang/mock/gomock" - "cosmossdk.io/core/header" sdkmath "cosmossdk.io/math" "cosmossdk.io/x/authz" banktypes "cosmossdk.io/x/bank/types" - "github.com/cosmos/cosmos-sdk/codec/address" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func (suite *TestSuite) createAccounts() []sdk.AccAddress { addrs := simtestutil.CreateIncrementalAccounts(2) - suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), suite.addrs[0]).Return(authtypes.NewBaseAccountWithAddress(suite.addrs[0])).AnyTimes() - suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), suite.addrs[1]).Return(authtypes.NewBaseAccountWithAddress(suite.addrs[1])).AnyTimes() return addrs } @@ -28,17 +22,15 @@ func (suite *TestSuite) TestGrant() { addrs := suite.createAccounts() curBlockTime := ctx.HeaderInfo().Time - suite.accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() - oneHour := curBlockTime.Add(time.Hour) oneYear := curBlockTime.AddDate(1, 0, 0) coins := sdk.NewCoins(sdk.NewCoin("steak", sdkmath.NewInt(10))) grantee, granter := addrs[0], addrs[1] - granterStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(granter) + granterStrAddr, err := suite.addrCdc.BytesToString(granter) suite.Require().NoError(err) - granteeStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(grantee) + granteeStrAddr, err := suite.addrCdc.BytesToString(grantee) suite.Require().NoError(err) testCases := []struct { @@ -50,7 +42,7 @@ func (suite *TestSuite) TestGrant() { { name: "identical grantee and granter", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granteeStrAddr, @@ -64,7 +56,7 @@ func (suite *TestSuite) TestGrant() { { name: "invalid granter", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: "invalid", @@ -78,7 +70,7 @@ func (suite *TestSuite) TestGrant() { { name: "invalid grantee", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -107,7 +99,7 @@ func (suite *TestSuite) TestGrant() { name: "invalid grant, past time", malleate: func() *authz.MsgGrant { pTime := curBlockTime.Add(-time.Hour) - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneHour) // we only need the authorization + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneHour) // we only need the authorization suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -125,14 +117,10 @@ func (suite *TestSuite) TestGrant() { name: "grantee account does not exist on chain: valid grant", malleate: func() *authz.MsgGrant { newAcc := sdk.AccAddress("valid") - suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), newAcc).Return(nil).AnyTimes() - acc := authtypes.NewBaseAccountWithAddress(newAcc) - suite.accountKeeper.EXPECT().NewAccountWithAddress(gomock.Any(), newAcc).Return(acc).AnyTimes() - - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) - addr, err := suite.accountKeeper.AddressCodec().BytesToString(newAcc) + addr, err := suite.addrCdc.BytesToString(newAcc) suite.Require().NoError(err) return &authz.MsgGrant{ @@ -145,7 +133,7 @@ func (suite *TestSuite) TestGrant() { { name: "valid grant", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -157,7 +145,7 @@ func (suite *TestSuite) TestGrant() { { name: "valid grant, same grantee, granter pair but different msgType", malleate: func() *authz.MsgGrant { - g, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneHour) + g, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneHour) suite.Require().NoError(err) _, err = suite.msgSrvr.Grant(suite.ctx, &authz.MsgGrant{ Granter: granterStrAddr, @@ -178,7 +166,7 @@ func (suite *TestSuite) TestGrant() { { name: "valid grant with allow list", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, []sdk.AccAddress{granter}, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, []sdk.AccAddress{granter}, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -190,7 +178,7 @@ func (suite *TestSuite) TestGrant() { { name: "valid grant with nil expiration time", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), nil) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), nil) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -232,9 +220,9 @@ func (suite *TestSuite) TestRevoke() { addrs := suite.createAccounts() grantee, granter := addrs[0], addrs[1] - granterStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(granter) + granterStrAddr, err := suite.addrCdc.BytesToString(granter) suite.Require().NoError(err) - granteeStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(grantee) + granteeStrAddr, err := suite.addrCdc.BytesToString(grantee) suite.Require().NoError(err) testCases := []struct { @@ -334,9 +322,9 @@ func (suite *TestSuite) TestExec() { addrs := suite.createAccounts() grantee, granter := addrs[0], addrs[1] - granterStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(granter) + granterStrAddr, err := suite.addrCdc.BytesToString(granter) suite.Require().NoError(err) - granteeStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(grantee) + granteeStrAddr, err := suite.addrCdc.BytesToString(grantee) suite.Require().NoError(err) coins := sdk.NewCoins(sdk.NewCoin("steak", sdkmath.NewInt(10))) @@ -402,15 +390,15 @@ func (suite *TestSuite) TestExec() { func (suite *TestSuite) TestPruneExpiredGrants() { addrs := suite.createAccounts() - addr0, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[0]) + addr0, err := suite.addrCdc.BytesToString(addrs[0]) suite.Require().NoError(err) - addr1, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[1]) + addr1, err := suite.addrCdc.BytesToString(addrs[1]) suite.Require().NoError(err) timeNow := suite.ctx.BlockTime() expiration := timeNow.Add(time.Hour) coins := sdk.NewCoins(sdk.NewCoin("steak", sdkmath.NewInt(10))) - grant, err := authz.NewGrant(timeNow, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &expiration) + grant, err := authz.NewGrant(timeNow, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &expiration) suite.Require().NoError(err) _, err = suite.msgSrvr.Grant(suite.ctx, &authz.MsgGrant{ @@ -454,7 +442,7 @@ func (suite *TestSuite) TestRevokeAllGrants() { addrs := simtestutil.CreateIncrementalAccounts(3) grantee, grantee2, granter := addrs[0], addrs[1], addrs[2] - granterStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(granter) + granterStrAddr, err := suite.addrCdc.BytesToString(granter) suite.Require().NoError(err) testCases := []struct { diff --git a/x/authz/module/abci_test.go b/x/authz/module/abci_test.go index 58811ba6294e..4696a1194ee9 100644 --- a/x/authz/module/abci_test.go +++ b/x/authz/module/abci_test.go @@ -4,7 +4,6 @@ import ( "testing" "time" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "cosmossdk.io/core/header" @@ -14,7 +13,6 @@ import ( "cosmossdk.io/x/authz" "cosmossdk.io/x/authz/keeper" authzmodule "cosmossdk.io/x/authz/module" - authztestutil "cosmossdk.io/x/authz/testutil" banktypes "cosmossdk.io/x/bank/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -25,7 +23,6 @@ import ( simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func TestExpiredGrantsQueue(t *testing.T) { @@ -57,22 +54,13 @@ func TestExpiredGrantsQueue(t *testing.T) { smallCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 10)) sendAuthz := banktypes.NewSendAuthorization(smallCoins, nil, codectestutil.CodecOptions{}.GetAddressCodec()) - ctrl := gomock.NewController(t) - accountKeeper := authztestutil.NewMockAccountKeeper(ctrl) - accountKeeper.EXPECT().GetAccount(gomock.Any(), granter).Return(authtypes.NewBaseAccountWithAddress(granter)).AnyTimes() - accountKeeper.EXPECT().GetAccount(gomock.Any(), grantee1).Return(authtypes.NewBaseAccountWithAddress(grantee1)).AnyTimes() - accountKeeper.EXPECT().GetAccount(gomock.Any(), grantee2).Return(authtypes.NewBaseAccountWithAddress(grantee2)).AnyTimes() - accountKeeper.EXPECT().GetAccount(gomock.Any(), grantee3).Return(authtypes.NewBaseAccountWithAddress(grantee3)).AnyTimes() - accountKeeper.EXPECT().GetAccount(gomock.Any(), grantee4).Return(authtypes.NewBaseAccountWithAddress(grantee4)).AnyTimes() - - accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() - + addrCdc := address.NewBech32Codec("cosmos") env := runtime.NewEnvironment(storeService, coretesting.NewNopLogger(), runtime.EnvWithQueryRouterService(baseApp.GRPCQueryRouter()), runtime.EnvWithMsgRouterService(baseApp.MsgServiceRouter())) - authzKeeper := keeper.NewKeeper(env, encCfg.Codec, accountKeeper) + authzKeeper := keeper.NewKeeper(env, encCfg.Codec, addrCdc) save := func(grantee sdk.AccAddress, exp *time.Time) { err := authzKeeper.SaveGrant(ctx, grantee, granter, sendAuthz, exp) - addr, _ := accountKeeper.AddressCodec().BytesToString(grantee) + addr, _ := addrCdc.BytesToString(grantee) require.NoError(t, err, "Grant from %s", addr) } save(grantee1, &expiration) @@ -88,7 +76,7 @@ func TestExpiredGrantsQueue(t *testing.T) { err := authzmodule.BeginBlocker(ctx, authzKeeper) require.NoError(t, err) - addr, err := accountKeeper.AddressCodec().BytesToString(granter) + addr, err := addrCdc.BytesToString(granter) require.NoError(t, err) res, err := queryClient.GranterGrants(ctx.Context(), &authz.QueryGranterGrantsRequest{ Granter: addr, diff --git a/x/authz/module/depinject.go b/x/authz/module/depinject.go index 911bca8c1daa..4a9368053c93 100644 --- a/x/authz/module/depinject.go +++ b/x/authz/module/depinject.go @@ -2,10 +2,10 @@ package module import ( modulev1 "cosmossdk.io/api/cosmos/authz/module/v1" + "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" "cosmossdk.io/depinject/appconfig" - "cosmossdk.io/x/authz" "cosmossdk.io/x/authz/keeper" "github.com/cosmos/cosmos-sdk/codec" @@ -27,10 +27,10 @@ func init() { type ModuleInputs struct { depinject.In - Cdc codec.Codec - AccountKeeper authz.AccountKeeper - Registry cdctypes.InterfaceRegistry - Environment appmodule.Environment + Cdc codec.Codec + AddressCodec address.Codec + Registry cdctypes.InterfaceRegistry + Environment appmodule.Environment } type ModuleOutputs struct { @@ -41,7 +41,7 @@ type ModuleOutputs struct { } func ProvideModule(in ModuleInputs) ModuleOutputs { - k := keeper.NewKeeper(in.Environment, in.Cdc, in.AccountKeeper) + k := keeper.NewKeeper(in.Environment, in.Cdc, in.AddressCodec) m := NewAppModule(in.Cdc, k, in.Registry) return ModuleOutputs{AuthzKeeper: k, Module: m} } diff --git a/x/authz/testutil/expected_keepers_mocks.go b/x/authz/testutil/expected_keepers_mocks.go index df0bcb0e835f..0a2d645dd6d2 100644 --- a/x/authz/testutil/expected_keepers_mocks.go +++ b/x/authz/testutil/expected_keepers_mocks.go @@ -8,76 +8,10 @@ import ( context "context" reflect "reflect" - address "cosmossdk.io/core/address" types "github.com/cosmos/cosmos-sdk/types" gomock "github.com/golang/mock/gomock" ) -// MockAccountKeeper is a mock of AccountKeeper interface. -type MockAccountKeeper struct { - ctrl *gomock.Controller - recorder *MockAccountKeeperMockRecorder -} - -// MockAccountKeeperMockRecorder is the mock recorder for MockAccountKeeper. -type MockAccountKeeperMockRecorder struct { - mock *MockAccountKeeper -} - -// NewMockAccountKeeper creates a new mock instance. -func NewMockAccountKeeper(ctrl *gomock.Controller) *MockAccountKeeper { - mock := &MockAccountKeeper{ctrl: ctrl} - mock.recorder = &MockAccountKeeperMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockAccountKeeper) EXPECT() *MockAccountKeeperMockRecorder { - return m.recorder -} - -// AddressCodec mocks base method. -func (m *MockAccountKeeper) AddressCodec() address.Codec { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddressCodec") - ret0, _ := ret[0].(address.Codec) - return ret0 -} - -// AddressCodec indicates an expected call of AddressCodec. -func (mr *MockAccountKeeperMockRecorder) AddressCodec() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddressCodec", reflect.TypeOf((*MockAccountKeeper)(nil).AddressCodec)) -} - -// GetAccount mocks base method. -func (m *MockAccountKeeper) GetAccount(ctx context.Context, addr types.AccAddress) types.AccountI { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAccount", ctx, addr) - ret0, _ := ret[0].(types.AccountI) - return ret0 -} - -// GetAccount indicates an expected call of GetAccount. -func (mr *MockAccountKeeperMockRecorder) GetAccount(ctx, addr interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccount", reflect.TypeOf((*MockAccountKeeper)(nil).GetAccount), ctx, addr) -} - -// NewAccountWithAddress mocks base method. -func (m *MockAccountKeeper) NewAccountWithAddress(ctx context.Context, addr types.AccAddress) types.AccountI { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewAccountWithAddress", ctx, addr) - ret0, _ := ret[0].(types.AccountI) - return ret0 -} - -// NewAccountWithAddress indicates an expected call of NewAccountWithAddress. -func (mr *MockAccountKeeperMockRecorder) NewAccountWithAddress(ctx, addr interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAccountWithAddress", reflect.TypeOf((*MockAccountKeeper)(nil).NewAccountWithAddress), ctx, addr) -} - // MockBankKeeper is a mock of BankKeeper interface. type MockBankKeeper struct { ctrl *gomock.Controller diff --git a/x/bank/CHANGELOG.md b/x/bank/CHANGELOG.md index f226eac88503..7cfd8ed0410b 100644 --- a/x/bank/CHANGELOG.md +++ b/x/bank/CHANGELOG.md @@ -35,13 +35,14 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#18636](https://github.com/cosmos/cosmos-sdk/pull/18636) `SendCoinsFromModuleToAccount`, `SendCoinsFromModuleToModule`, `SendCoinsFromAccountToModule`, `DelegateCoinsFromAccountToModule`, `UndelegateCoinsFromModuleToAccount`, `MintCoins` and `BurnCoins` methods now returns an error instead of panicking if any module accounts does not exist or unauthorized. * [#20517](https://github.com/cosmos/cosmos-sdk/pull/20517) `SendCoins` now checks for `SendRestrictions` before instead of after deducting coins using `subUnlockedCoins`. * [#20354](https://github.com/cosmos/cosmos-sdk/pull/20354) Reduce the number of `ValidateDenom` calls in `bank.SendCoins`. +* [#21976](https://github.com/cosmos/cosmos-sdk/pull/21976) Resolve a footgun by swapping send restrictions check in `InputOutputCoins` before coin deduction. ### Bug Fixes * [#21407](https://github.com/cosmos/cosmos-sdk/pull/21407) Fix handling of negative spendable balances. - * The `SpendableBalances` query now correctly reports spendable balances when one or more denoms are negative (used to report all zeros). Also, this query now looks up only the balances for the requested page. - * The `SpendableCoins` keeper method now returns the positive spendable balances even when one or more denoms have more locked than available (used to return an empty `Coins`). - * The `SpendableCoin` keeper method now returns a zero coin if there's more locked than available (used to return a negative coin). + * The `SpendableBalances` query now correctly reports spendable balances when one or more denoms are negative (used to report all zeros). Also, this query now looks up only the balances for the requested page. + * The `SpendableCoins` keeper method now returns the positive spendable balances even when one or more denoms have more locked than available (used to return an empty `Coins`). + * The `SpendableCoin` keeper method now returns a zero coin if there's more locked than available (used to return a negative coin). ### API Breaking Changes diff --git a/x/bank/README.md b/x/bank/README.md index 5ac389feb5a2..f6f77f1f947e 100644 --- a/x/bank/README.md +++ b/x/bank/README.md @@ -10,15 +10,13 @@ This document specifies the bank module of the Cosmos SDK. The bank module is responsible for handling multi-asset coin transfers between accounts and tracking special-case pseudo-transfers which must work differently -with particular kinds of accounts (notably delegating/undelegating for vesting +with particular kinds of accounts (notably delegating/undelegating for legacy vesting accounts). It exposes several interfaces with varying capabilities for secure interaction with other modules which must alter user balances. In addition, the bank module tracks and provides query support for the total supply of all assets used in the application. -This module is used in the Cosmos Hub. - ## Contents * [Supply](#supply) @@ -51,9 +49,9 @@ The `supply` functionality: ### Total Supply -The total `Supply` of the network is equal to the sum of all coins from the -account. The total supply is updated every time a `Coin` is minted (eg: as part -of the inflation mechanism) or burned (eg: due to slashing or if a governance +The total `Supply` of the network is equal to the sum of all coins from all +accounts within a chain. The total supply is updated every time a `Coin` is minted +(eg: as part of the inflation mechanism) or burned (eg: due to slashing or if a governance proposal is vetoed). ## Module Accounts @@ -83,13 +81,12 @@ type ModuleAccount interface { > **WARNING!** > Any module or message handler that allows either direct or indirect sending of funds must explicitly guarantee those funds cannot be sent to module accounts (unless allowed). -The supply `Keeper` also introduces new wrapper functions for the auth `Keeper` -and the bank `Keeper` that are related to `ModuleAccount`s in order to be able -to: +The supply `Keeper` interface also introduces new wrapper functions for the auth `Keeper` +and the bank `SendKeeper` in order to be able to: -* Get and set `ModuleAccount`s by providing the `Name`. -* Send coins from and to other `ModuleAccount`s or standard `Account`s - (`BaseAccount` or `VestingAccount`) by passing only the `Name`. +* Get `ModuleAccount`s by providing its `Name`. +* Send coins from and to other `ModuleAccount`s by passing only the `Name` or standard `Account`s + (`BaseAccount` or legacy `VestingAccount`). * `Mint` or `Burn` coins for a `ModuleAccount` (restricted to its permissions). ### Permissions @@ -122,6 +119,7 @@ aforementioned state: * Denom Metadata Index: `0x1 | byte(denom) -> ProtocolBuffer(Metadata)` * Balances Index: `0x2 | byte(address length) | []byte(address) | []byte(balance.Denom) -> ProtocolBuffer(balance)` * Reverse Denomination to Address Index: `0x03 | byte(denom) | 0x00 | []byte(address) -> 0` +* Send enabled Denoms: `0x4 | string -> bool` ## Params @@ -131,7 +129,7 @@ it can be updated with governance or the address with authority. * Params: `0x05 | ProtocolBuffer(Params)` ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/bank.proto#L12-L23 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/bank/proto/cosmos/bank/v1beta1/bank.proto#L12-L23 ``` ## Keepers @@ -142,11 +140,11 @@ should use the least-permissive interface that provides the functionality they require. Best practices dictate careful review of `bank` module code to ensure that -permissions are limited in the way that you expect. +permissions are limited in the way that you expected. ### Denied Addresses -The `x/bank` module accepts a map of addresses that are considered blocklisted +The `x/bank` module accepts a map of addresses (`blockedAddrs`) that are considered blocklisted from directly and explicitly receiving funds through means such as `MsgSend` and `MsgMultiSend` and direct API calls like `SendCoinsFromModuleToAccount`. @@ -160,7 +158,7 @@ By providing the `x/bank` module with a blocklisted set of addresses, an error o #### Input -An input of a multiparty transfer +An input of a multi-send transaction ```protobuf // Input models transaction input. @@ -172,7 +170,7 @@ message Input { #### Output -An output of a multiparty transfer. +An output of a multi-send transaction. ```protobuf // Output models transaction outputs. @@ -195,8 +193,8 @@ type Keeper interface { SendKeeper WithMintCoinsRestriction(MintingRestrictionFn) BaseKeeper - InitGenesis(context.Context, *types.GenesisState) - ExportGenesis(context.Context) *types.GenesisState + InitGenesis(context.Context, *types.GenesisState) error + ExportGenesis(context.Context) (*types.GenesisState, error) GetSupply(ctx context.Context, denom string) sdk.Coin HasSupply(ctx context.Context, denom string) bool @@ -213,14 +211,11 @@ type Keeper interface { DelegateCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error UndelegateCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error MintCoins(ctx context.Context, moduleName string, amt sdk.Coins) error - BurnCoins(ctx context.Context, moduleName string, amt sdk.Coins) error + BurnCoins(ctx context.Context, address []byte, amt sdk.Coins) error DelegateCoins(ctx context.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error UndelegateCoins(ctx context.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error - // GetAuthority gets the address capable of executing governance proposal messages. Usually the gov module account. - GetAuthority() string - types.QueryServer } ``` @@ -274,17 +269,18 @@ Both functions compose the provided restriction with any previously provided res `AppendSendRestriction` adds the provided restriction to be run after any previously provided send restrictions. `PrependSendRestriction` adds the restriction to be run before any previously provided send restrictions. The composition will short-circuit when an error is encountered. I.e. if the first one returns an error, the second is not run. +Send restrictions can also be cleared by using `ClearSendRestriction`. -During `SendCoins`, the send restriction is applied before coins are removed from the from address and adding them to the to address. -During `InputOutputCoins`, the send restriction is applied after the input coins are removed and once for each output before the funds are added. - -A send restriction function should make use of a custom value in the context to allow bypassing that specific restriction. +During `SendCoins`, the send restriction is applied before coins are removed from the `from_address` and adding them to the `to_address`. +During `InputOutputCoins`, the send restriction is applied before the input coins are removed, once for each output before the funds are added. Send Restrictions are not placed on `ModuleToAccount` or `ModuleToModule` transfers. This is done due to modules needing to move funds to user accounts and other module accounts. This is a design decision to allow for more flexibility in the state machine. The state machine should be able to move funds between module accounts and user accounts without restrictions. Secondly this limitation would limit the usage of the state machine even for itself. users would not be able to receive rewards, not be able to move funds between module accounts. In the case that a user sends funds from a user account to the community pool and then a governance proposal is used to get those tokens into the users account this would fall under the discretion of the app chain developer to what they would like to do here. We can not make strong assumptions here. -Thirdly, this issue could lead into a chain halt if a token is disabled and the token is moved in the begin/endblock. This is the last reason we see the current change and more damaging then beneficial for users. +Thirdly, this issue could lead into a chain halt if a token is disabled and the token is moved in the begin/endblock. This is the last reason we see the current change as they are more damaging then beneficial for users. + +A send restriction function should make use of a custom value in the context to allow bypassing that specific restriction. For example, in your module's keeper package, you'd define the send restriction function: ```golang @@ -337,7 +333,8 @@ func HasBypass(ctx context.Context) bool { } ``` -Now, anywhere where you want to use `SendCoins` or `InputOutputCoins`, but you don't want your send restriction applied: +Now, anywhere where you want to use `SendCoins` or `InputOutputCoins` but you don't want your send restriction applied +you just need to apply custom value in the context: ```golang func (k Keeper) DoThing(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error { @@ -375,35 +372,35 @@ type ViewKeeper interface { Send coins from one address to another. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L38-L53 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/bank/proto/cosmos/bank/v1beta1/tx.proto#L44-L59 ``` The message will fail under the following conditions: * The coins do not have sending enabled -* The `to` address is restricted +* The `to_address` is restricted ### MsgMultiSend -Send coins from one sender and to a series of different address. If any of the receiving addresses do not correspond to an existing account, a new account is created. +Send coins from one sender and to a series of different address. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L58-L69 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/bank/proto/cosmos/bank/v1beta1/tx.proto#L65-L75 ``` The message will fail under the following conditions: * Any of the coins do not have sending enabled -* Any of the `to` addresses are restricted +* Any of the `to_address` are restricted * Any of the coins are locked -* The inputs and outputs do not correctly correspond to one another +* The inputs and outputs do not correctly correspond to one another (eg: total_in not equal to total_out) ### MsgUpdateParams The `bank` module params can be updated through `MsgUpdateParams`, which can be done using governance proposal. The signer will always be the `gov` module account address. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L74-L88 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/bank/proto/cosmos/bank/v1beta1/tx.proto#L81-L93 ``` The message handling can fail if: @@ -412,30 +409,30 @@ The message handling can fail if: ### MsgSetSendEnabled -Used with the x/gov module to set create/edit SendEnabled entries. +Used with the x/gov module to create or edit SendEnabled entries. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L96-L117 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/bank/proto/cosmos/bank/v1beta1/tx.proto#L106-L122 ``` The message will fail under the following conditions: -* The authority is not a decodable address. -* The authority is not x/gov module's address. -* There are multiple SendEnabled entries with the same Denom. -* One or more SendEnabled entries has an invalid Denom. +* The authority is not a decodable address +* The authority is not x/gov module's address +* There are multiple SendEnabled entries with the same Denom +* One or more SendEnabled entries has an invalid Denom ### MsgBurn Used to burn coins from an account. The coins are removed from the account and the total supply is reduced. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/1af000b3ef6296f9928caf494fe5bb812990f22d/proto/cosmos/bank/v1beta1/tx.proto#L131-L148 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/bank/proto/cosmos/bank/v1beta1/tx.proto#L130-L139 ``` This message will fail under the following conditions: -* The signer is not present +* The `from_address` is not a decodable address * The coins are not spendable * The coins are not positive * The coins are not valid @@ -451,20 +448,20 @@ The bank module emits the following events: | Type | Attribute Key | Attribute Value | | -------- | ------------- | ------------------ | | transfer | recipient | {recipientAddress} | +| transfer | sender | {senderAddress} | | transfer | amount | {amount} | | message | module | bank | | message | action | send | -| message | sender | {senderAddress} | #### MsgMultiSend | Type | Attribute Key | Attribute Value | | -------- | ------------- | ------------------ | | transfer | recipient | {recipientAddress} | +| transfer | sender | {senderAddress} | | transfer | amount | {amount} | | message | module | bank | | message | action | multisend | -| message | sender | {senderAddress} | ### Keeper Events @@ -592,9 +589,7 @@ The bank module contains the following parameters ### SendEnabled -The SendEnabled parameter is now deprecated and not to be use. It is replaced -with state store records. - +SendEnabled is depreacted and only kept for backward compatibility. For genesis, use the newly added send_enabled field in the genesis object. Storage, lookup, and manipulation of this information is now in the keeper. ### DefaultSendEnabled @@ -616,6 +611,20 @@ The `query` commands allow users to query `bank` state. simd query bank --help ``` +##### balance + +The `balance` command allows users to query account balance by specific denom. + +```shell +simd query bank balance [address] [denom] [flags] +``` + +Example: + +```shell +simd query bank balance cosmos1.. stake +``` + ##### balances The `balances` command allows users to query account balances by address. @@ -630,49 +639,65 @@ Example: simd query bank balances cosmos1.. ``` -Example Output: +##### spendable balances + +The `spendable-balances` command allows users to query account spendable balances by address. + +```shell +simd query spendable-balances [address] [flags] +``` + +Example: + +```shell +simd query bank spendable-balances cosmos1.. +``` + +##### spendable balance by denom + +The `spendable-balance` command allows users to query account spendable balance by address for a specific denom. + +```shell +simd query spendable-balance [address] [denom] [flags] +``` + +Example: -```yml -balances: -- amount: "1000000000" - denom: stake -pagination: - next_key: null - total: "0" +```shell +simd query bank spendable-balance cosmos1.. stake ``` ##### denom-metadata -The `denom-metadata` command allows users to query metadata for coin denominations. A user can query metadata for a single denomination using the `--denom` flag or all denominations without it. +The `denom-metadata` command allows users to query metadata for coin denominations. ```shell -simd query bank denom-metadata [flags] +simd query bank denom-metadata [denom] ``` Example: ```shell -simd query bank denom-metadata --denom stake +simd query bank denom-metadata stake +``` + +##### denoms-metadata + +The `denoms-metadata` command allows users to query metadata for all coin denominations. + +```shell +simd query bank denoms-metadata [flags] ``` -Example Output: +Example: -```yml -metadata: - base: stake - denom_units: - - aliases: - - STAKE - denom: stake - description: native staking token of simulation app - display: stake - name: SimApp Token - symbol: STK +```shell +simd query bank denoms-metadata ``` -##### total +##### total supply -The `total` command allows users to query the total supply of coins. A user can query the total supply for a single coin using the `--denom` flag or all coins without it. +The `total-supply` (or `total` for short) command allows users to query the total supply of coins. ```shell simd query bank total [flags] @@ -684,11 +709,18 @@ Example: simd query bank total --denom stake ``` -Example Output: +##### total supply of + +The `total-supply-of` command allows users to query the total supply for a specific coin denominations. + +```shell +simd query bank total-supply-of [denom] +``` + +Example: -```yml -amount: "10000000000" -denom: stake +```shell +simd query bank total-supply-of stake ``` ##### send-enabled @@ -705,16 +737,26 @@ Example: simd query bank send-enabled ``` -Example output: +##### params -```yml -send_enabled: -- denom: foocoin - enabled: true -- denom: barcoin -pagination: - next-key: null - total: 2 +The `params` command allows users to query for the current bank parameters. + +```shell +simd query bank params [flags] +``` + +##### denom owners + +The `denom-owners` command allows users to query for all account addresses that own a particular token denomination. + +```shell +simd query bank denom-owners [denom] [flags] +``` + +Example: + +```shell +simd query bank denom-owners stake ``` #### Transactions @@ -760,17 +802,6 @@ grpcurl -plaintext \ cosmos.bank.v1beta1.Query/Balance ``` -Example Output: - -```json -{ - "balance": { - "denom": "stake", - "amount": "1000000000" - } -} -``` - ### AllBalances The `AllBalances` endpoint allows users to query account balance by address for all denominations. @@ -788,22 +819,6 @@ grpcurl -plaintext \ cosmos.bank.v1beta1.Query/AllBalances ``` -Example Output: - -```json -{ - "balances": [ - { - "denom": "stake", - "amount": "1000000000" - } - ], - "pagination": { - "total": "1" - } -} -``` - ### DenomMetadata The `DenomMetadata` endpoint allows users to query metadata for a single coin denomination. @@ -821,28 +836,6 @@ grpcurl -plaintext \ cosmos.bank.v1beta1.Query/DenomMetadata ``` -Example Output: - -```json -{ - "metadata": { - "description": "native staking token of simulation app", - "denomUnits": [ - { - "denom": "stake", - "aliases": [ - "STAKE" - ] - } - ], - "base": "stake", - "display": "stake", - "name": "SimApp Token", - "symbol": "STK" - } -} -``` - ### DenomsMetadata The `DenomsMetadata` endpoint allows users to query metadata for all coin denominations. @@ -859,33 +852,6 @@ grpcurl -plaintext \ cosmos.bank.v1beta1.Query/DenomsMetadata ``` -Example Output: - -```json -{ - "metadatas": [ - { - "description": "native staking token of simulation app", - "denomUnits": [ - { - "denom": "stake", - "aliases": [ - "STAKE" - ] - } - ], - "base": "stake", - "display": "stake", - "name": "SimApp Token", - "symbol": "STK" - } - ], - "pagination": { - "total": "1" - } -} -``` - ### DenomOwners The `DenomOwners` endpoint allows users to query metadata for a single coin denomination. @@ -903,32 +869,6 @@ grpcurl -plaintext \ cosmos.bank.v1beta1.Query/DenomOwners ``` -Example Output: - -```json -{ - "denomOwners": [ - { - "address": "cosmos1..", - "balance": { - "denom": "stake", - "amount": "5000000000" - } - }, - { - "address": "cosmos1..", - "balance": { - "denom": "stake", - "amount": "5000000000" - } - }, - ], - "pagination": { - "total": "2" - } -} -``` - ### TotalSupply The `TotalSupply` endpoint allows users to query the total supply of all coins. @@ -945,22 +885,6 @@ grpcurl -plaintext \ cosmos.bank.v1beta1.Query/TotalSupply ``` -Example Output: - -```json -{ - "supply": [ - { - "denom": "stake", - "amount": "10000000000" - } - ], - "pagination": { - "total": "1" - } -} -``` - ### SupplyOf The `SupplyOf` endpoint allows users to query the total supply of a single coin. @@ -978,17 +902,6 @@ grpcurl -plaintext \ cosmos.bank.v1beta1.Query/SupplyOf ``` -Example Output: - -```json -{ - "amount": { - "denom": "stake", - "amount": "10000000000" - } -} -``` - ### Params The `Params` endpoint allows users to query the parameters of the `bank` module. @@ -1005,16 +918,6 @@ grpcurl -plaintext \ cosmos.bank.v1beta1.Query/Params ``` -Example Output: - -```json -{ - "params": { - "defaultSendEnabled": true - } -} -``` - ### SendEnabled The `SendEnabled` endpoints allows users to query the SendEnabled entries of the `bank` module. @@ -1033,22 +936,3 @@ grpcurl -plaintext \ cosmos.bank.v1beta1.Query/SendEnabled ``` -Example Output: - -```json -{ - "send_enabled": [ - { - "denom": "foocoin", - "enabled": true - }, - { - "denom": "barcoin" - } - ], - "pagination": { - "next-key": null, - "total": 2 - } -} -``` diff --git a/x/bank/go.mod b/x/bank/go.mod index 62c1752a2b96..53fd49dabcd2 100644 --- a/x/bank/go.mod +++ b/x/bank/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.4.1 // indirect @@ -19,17 +19,18 @@ require ( github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/hashicorp/go-metrics v0.5.3 + github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 gotest.tools/v3 v3.5.1 ) require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect + cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -116,7 +117,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -152,7 +153,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -160,10 +161,8 @@ require ( sigs.k8s.io/yaml v1.4.0 // indirect ) -require cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 - require ( - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cosmos/cosmos-db v1.0.3-0.20240911104526-ddc3f09bfc22 // indirect github.com/google/uuid v1.6.0 // indirect diff --git a/x/bank/go.sum b/x/bank/go.sum index 934d22e1cbe7..7588b565a0d7 100644 --- a/x/bank/go.sum +++ b/x/bank/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -412,8 +412,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -638,8 +638,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -650,8 +650,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index e625712f08b8..4fe765039638 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -790,6 +790,7 @@ func (suite *KeeperTestSuite) TestInputOutputCoinsWithRestrictions() { suite.Require().NoError(err) fromAcc := authtypes.NewBaseAccountWithAddress(fromAddr) inputAccs := []sdk.AccountI{fromAcc} + suite.authKeeper.EXPECT().GetAccount(suite.ctx, inputAccs[0].GetAddress()).Return(inputAccs[0]).AnyTimes() toAddr1 := accAddrs[1] toAddr1Str, err := suite.authKeeper.AddressCodec().BytesToString(toAddr1) suite.Require().NoError(err) @@ -878,7 +879,7 @@ func (suite *KeeperTestSuite) TestInputOutputCoinsWithRestrictions() { }, expErr: "restriction test error", expBals: expBals{ - from: sdk.NewCoins(newFooCoin(959), newBarCoin(412)), + from: sdk.NewCoins(newFooCoin(959), newBarCoin(500)), to1: sdk.NewCoins(newFooCoin(15)), to2: sdk.NewCoins(newFooCoin(26)), }, @@ -907,7 +908,7 @@ func (suite *KeeperTestSuite) TestInputOutputCoinsWithRestrictions() { }, }, expBals: expBals{ - from: sdk.NewCoins(newFooCoin(948), newBarCoin(400)), + from: sdk.NewCoins(newFooCoin(948), newBarCoin(488)), to1: sdk.NewCoins(newFooCoin(26)), to2: sdk.NewCoins(newFooCoin(26), newBarCoin(12)), }, @@ -937,8 +938,8 @@ func (suite *KeeperTestSuite) TestInputOutputCoinsWithRestrictions() { }, expErr: "second restriction error", expBals: expBals{ - from: sdk.NewCoins(newFooCoin(904), newBarCoin(400)), - to1: sdk.NewCoins(newFooCoin(38)), + from: sdk.NewCoins(newFooCoin(948), newBarCoin(488)), + to1: sdk.NewCoins(newFooCoin(26)), to2: sdk.NewCoins(newFooCoin(26), newBarCoin(12)), }, }, @@ -966,8 +967,8 @@ func (suite *KeeperTestSuite) TestInputOutputCoinsWithRestrictions() { }, }, expBals: expBals{ - from: sdk.NewCoins(newFooCoin(904), newBarCoin(365)), - to1: sdk.NewCoins(newFooCoin(38), newBarCoin(25)), + from: sdk.NewCoins(newFooCoin(948), newBarCoin(453)), + to1: sdk.NewCoins(newFooCoin(26), newBarCoin(25)), to2: sdk.NewCoins(newFooCoin(26), newBarCoin(22)), }, }, @@ -980,7 +981,6 @@ func (suite *KeeperTestSuite) TestInputOutputCoinsWithRestrictions() { actualRestrictionArgs = nil suite.bankKeeper.SetSendRestriction(tc.fn) ctx := suite.ctx - suite.mockInputOutputCoins(inputAccs, tc.outputAddrs) input := banktypes.Input{ Address: fromStrAddr, Coins: tc.inputCoins, diff --git a/x/bank/keeper/msg_server.go b/x/bank/keeper/msg_server.go index 5e7b94e13c4c..81d4d2321476 100644 --- a/x/bank/keeper/msg_server.go +++ b/x/bank/keeper/msg_server.go @@ -3,12 +3,9 @@ package keeper import ( "context" - "github.com/hashicorp/go-metrics" - errorsmod "cosmossdk.io/errors" "cosmossdk.io/x/bank/types" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -65,18 +62,6 @@ func (k msgServer) Send(ctx context.Context, msg *types.MsgSend) (*types.MsgSend return nil, err } - defer func() { - for _, a := range msg.Amount { - if a.Amount.IsInt64() { - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", "send"}, - float32(a.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, - ) - } - } - }() - return &types.MsgSendResponse{}, nil } diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 063417b6ca03..929ff2e50285 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -148,14 +148,15 @@ func (k BaseSendKeeper) InputOutputCoins(ctx context.Context, input types.Input, return err } - err = k.subUnlockedCoins(ctx, inAddress, input.Coins) - if err != nil { - return err + // ensure all coins can be sent + type toSend struct { + AddressStr string + Address []byte + Coins sdk.Coins } - - var outAddress sdk.AccAddress + sending := make([]toSend, 0) for _, out := range outputs { - outAddress, err = k.ak.AddressCodec().StringToBytes(out.Address) + outAddress, err := k.ak.AddressCodec().StringToBytes(out.Address) if err != nil { return err } @@ -165,13 +166,25 @@ func (k BaseSendKeeper) InputOutputCoins(ctx context.Context, input types.Input, return err } - if err := k.addCoins(ctx, outAddress, out.Coins); err != nil { + sending = append(sending, toSend{ + Address: outAddress, + AddressStr: out.Address, + Coins: out.Coins, + }) + } + + if err := k.subUnlockedCoins(ctx, inAddress, input.Coins); err != nil { + return err + } + + for _, out := range sending { + if err := k.addCoins(ctx, out.Address, out.Coins); err != nil { return err } if err := k.EventService.EventManager(ctx).EmitKV( types.EventTypeTransfer, - event.NewAttribute(types.AttributeKeyRecipient, out.Address), + event.NewAttribute(types.AttributeKeyRecipient, out.AddressStr), event.NewAttribute(types.AttributeKeySender, input.Address), event.NewAttribute(sdk.AttributeKeyAmount, out.Coins.String()), ); err != nil { diff --git a/x/bank/proto/cosmos/bank/module/v2/module.proto b/x/bank/proto/cosmos/bank/module/v2/module.proto index a4c0ed40b52f..4d6db9db5fc6 100644 --- a/x/bank/proto/cosmos/bank/module/v2/module.proto +++ b/x/bank/proto/cosmos/bank/module/v2/module.proto @@ -14,4 +14,10 @@ message Module { // authority defines the custom module authority. If not set, defaults to the governance module. string authority = 1; + + // restrictions_order specifies the order of send restrictions and should be + // a list of module names which provide a send restriction instance. If no + // order is provided, then restrictions will be applied in alphabetical order + // of module names. + repeated string restrictions_order = 2; } diff --git a/x/bank/v2/depinject.go b/x/bank/v2/depinject.go index b5465d7e02df..6bb04908db2a 100644 --- a/x/bank/v2/depinject.go +++ b/x/bank/v2/depinject.go @@ -1,6 +1,11 @@ package bankv2 import ( + "fmt" + "maps" + "slices" + "sort" + "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" @@ -22,6 +27,7 @@ func init() { appconfig.RegisterModule( &moduletypes.Module{}, appconfig.Provide(ProvideModule), + appconfig.Invoke(InvokeSetSendRestrictions), ) } @@ -61,3 +67,39 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { Module: m, } } + +func InvokeSetSendRestrictions( + config *moduletypes.Module, + keeper keeper.Keeper, + restrictions map[string]types.SendRestrictionFn, +) error { + if config == nil { + return nil + } + + modules := slices.Collect(maps.Keys(restrictions)) + order := config.RestrictionsOrder + if len(order) == 0 { + order = modules + sort.Strings(order) + } + + if len(order) != len(modules) { + return fmt.Errorf("len(restrictions order: %v) != len(restriction modules: %v)", order, modules) + } + + if len(modules) == 0 { + return nil + } + + for _, module := range order { + restriction, ok := restrictions[module] + if !ok { + return fmt.Errorf("can't find send restriction for module %s", module) + } + + keeper.AppendGlobalSendRestriction(restriction) + } + + return nil +} diff --git a/x/bank/v2/keeper/handlers.go b/x/bank/v2/keeper/handlers.go index 561b15306ed2..e998aceecb72 100644 --- a/x/bank/v2/keeper/handlers.go +++ b/x/bank/v2/keeper/handlers.go @@ -6,14 +6,12 @@ import ( "errors" "fmt" - "github.com/hashicorp/go-metrics" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" errorsmod "cosmossdk.io/errors" "cosmossdk.io/x/bank/v2/types" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -85,18 +83,6 @@ func (h handlers) MsgSend(ctx context.Context, msg *types.MsgSend) (*types.MsgSe return nil, err } - defer func() { - for _, a := range msg.Amount { - if a.Amount.IsInt64() { - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", "send"}, - float32(a.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, - ) - } - } - }() - return &types.MsgSendResponse{}, nil } diff --git a/x/bank/v2/keeper/keeper.go b/x/bank/v2/keeper/keeper.go index f16982f168c4..833fb298ef6f 100644 --- a/x/bank/v2/keeper/keeper.go +++ b/x/bank/v2/keeper/keeper.go @@ -28,18 +28,21 @@ type Keeper struct { params collections.Item[types.Params] balances *collections.IndexedMap[collections.Pair[[]byte, string], math.Int, BalancesIndexes] supply collections.Map[string, math.Int] + + sendRestriction *sendRestriction } func NewKeeper(authority []byte, addressCodec address.Codec, env appmodulev2.Environment, cdc codec.BinaryCodec) *Keeper { sb := collections.NewSchemaBuilder(env.KVStoreService) k := &Keeper{ - Environment: env, - authority: authority, - addressCodec: addressCodec, // TODO(@julienrbrt): Should we add address codec to the environment? - params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), - balances: collections.NewIndexedMap(sb, types.BalancesPrefix, "balances", collections.PairKeyCodec(collections.BytesKey, collections.StringKey), sdk.IntValue, newBalancesIndexes(sb)), - supply: collections.NewMap(sb, types.SupplyKey, "supply", collections.StringKey, sdk.IntValue), + Environment: env, + authority: authority, + addressCodec: addressCodec, // TODO(@julienrbrt): Should we add address codec to the environment? + params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), + balances: collections.NewIndexedMap(sb, types.BalancesPrefix, "balances", collections.PairKeyCodec(collections.BytesKey, collections.StringKey), sdk.IntValue, newBalancesIndexes(sb)), + supply: collections.NewMap(sb, types.SupplyKey, "supply", collections.StringKey, sdk.IntValue), + sendRestriction: newSendRestriction(), } schema, err := sb.Build() @@ -94,7 +97,10 @@ func (k Keeper) SendCoins(ctx context.Context, from, to []byte, amt sdk.Coins) e } var err error - // TODO: Send restriction + to, err = k.sendRestriction.apply(ctx, from, to, amt) + if err != nil { + return err + } err = k.subUnlockedCoins(ctx, from, amt) if err != nil { diff --git a/x/bank/v2/keeper/keeper_test.go b/x/bank/v2/keeper/keeper_test.go index 32ccbac4d2ef..2920d0aea040 100644 --- a/x/bank/v2/keeper/keeper_test.go +++ b/x/bank/v2/keeper/keeper_test.go @@ -1,7 +1,9 @@ package keeper_test import ( + "bytes" "context" + "fmt" "testing" "time" @@ -184,3 +186,53 @@ func (suite *KeeperTestSuite) TestSendCoins_Module_To_Module() { mintBarBalance := suite.bankKeeper.GetBalance(ctx, mintAcc.GetAddress(), barDenom) require.Equal(mintBarBalance.Amount, math.NewInt(0)) } + +func (suite *KeeperTestSuite) TestSendCoins_WithRestriction() { + ctx := suite.ctx + require := suite.Require() + balances := sdk.NewCoins(newFooCoin(100), newBarCoin(50)) + sendAmt := sdk.NewCoins(newFooCoin(10), newBarCoin(10)) + + require.NoError(banktestutil.FundAccount(ctx, suite.bankKeeper, accAddrs[0], balances)) + + // Add first restriction + addrRestrictFunc := func(ctx context.Context, from, to []byte, amount sdk.Coins) ([]byte, error) { + if bytes.Equal(from, to) { + return nil, fmt.Errorf("Can not send to same address") + } + return to, nil + } + suite.bankKeeper.AppendGlobalSendRestriction(addrRestrictFunc) + + err := suite.bankKeeper.SendCoins(ctx, accAddrs[0], accAddrs[0], sendAmt) + require.Error(err) + require.Contains(err.Error(), "Can not send to same address") + + // Add second restriction + amtRestrictFunc := func(ctx context.Context, from, to []byte, amount sdk.Coins) ([]byte, error) { + if len(amount) > 1 { + return nil, fmt.Errorf("Allow only one denom per one send") + } + return to, nil + } + suite.bankKeeper.AppendGlobalSendRestriction(amtRestrictFunc) + + // Pass the 1st but failt at the 2nd + err = suite.bankKeeper.SendCoins(ctx, accAddrs[0], accAddrs[1], sendAmt) + require.Error(err) + require.Contains(err.Error(), "Allow only one denom per one send") + + // Pass both 2 restrictions + err = suite.bankKeeper.SendCoins(ctx, accAddrs[0], accAddrs[1], sdk.NewCoins(newFooCoin(10))) + require.NoError(err) + + // Check balances + acc0FooBalance := suite.bankKeeper.GetBalance(ctx, accAddrs[0], fooDenom) + require.Equal(acc0FooBalance.Amount, math.NewInt(90)) + acc0BarBalance := suite.bankKeeper.GetBalance(ctx, accAddrs[0], barDenom) + require.Equal(acc0BarBalance.Amount, math.NewInt(50)) + acc1FooBalance := suite.bankKeeper.GetBalance(ctx, accAddrs[1], fooDenom) + require.Equal(acc1FooBalance.Amount, math.NewInt(10)) + acc1BarBalance := suite.bankKeeper.GetBalance(ctx, accAddrs[1], barDenom) + require.Equal(acc1BarBalance.Amount, math.ZeroInt()) +} diff --git a/x/bank/v2/keeper/restriction.go b/x/bank/v2/keeper/restriction.go new file mode 100644 index 000000000000..e8d0245615f8 --- /dev/null +++ b/x/bank/v2/keeper/restriction.go @@ -0,0 +1,62 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/x/bank/v2/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// sendRestriction is a struct that houses a SendRestrictionFn. +// It exists so that the SendRestrictionFn can be updated in the SendKeeper without needing to have a pointer receiver. +type sendRestriction struct { + fn types.SendRestrictionFn +} + +// newSendRestriction creates a new sendRestriction with nil send restriction. +func newSendRestriction() *sendRestriction { + return &sendRestriction{ + fn: nil, + } +} + +// append adds the provided restriction to this, to be run after the existing function. +func (r *sendRestriction) append(restriction types.SendRestrictionFn) { + r.fn = r.fn.Then(restriction) +} + +// prepend adds the provided restriction to this, to be run before the existing function. +func (r *sendRestriction) prepend(restriction types.SendRestrictionFn) { + r.fn = restriction.Then(r.fn) +} + +// clear removes the send restriction (sets it to nil). +func (r *sendRestriction) clear() { + r.fn = nil +} + +var _ types.SendRestrictionFn = (*sendRestriction)(nil).apply + +// apply applies the send restriction if there is one. If not, it's a no-op. +func (r *sendRestriction) apply(ctx context.Context, fromAddr, toAddr []byte, amt sdk.Coins) ([]byte, error) { + if r == nil || r.fn == nil { + return toAddr, nil + } + return r.fn(ctx, fromAddr, toAddr, amt) +} + +// AppendGlobalSendRestriction adds the provided SendRestrictionFn to run after previously provided global restrictions. +func (k Keeper) AppendGlobalSendRestriction(restriction types.SendRestrictionFn) { + k.sendRestriction.append(restriction) +} + +// PrependGlobalSendRestriction adds the provided SendRestrictionFn to run before previously provided global restrictions. +func (k Keeper) PrependGlobalSendRestriction(restriction types.SendRestrictionFn) { + k.sendRestriction.prepend(restriction) +} + +// ClearGlobalSendRestriction removes the global send restriction (if there is one). +func (k Keeper) ClearGlobalSendRestriction() { + k.sendRestriction.clear() +} diff --git a/x/bank/v2/module.go b/x/bank/v2/module.go index aea151535f1d..99d5ab2ab7d4 100644 --- a/x/bank/v2/module.go +++ b/x/bank/v2/module.go @@ -3,11 +3,8 @@ package bankv2 import ( "context" "encoding/json" - "errors" "fmt" - "reflect" - gogoproto "github.com/cosmos/gogoproto/proto" "github.com/spf13/cobra" appmodulev2 "cosmossdk.io/core/appmodule/v2" @@ -98,77 +95,17 @@ func (am AppModule) ExportGenesis(ctx context.Context) (json.RawMessage, error) func (am AppModule) RegisterMsgHandlers(router appmodulev2.MsgRouter) { handlers := keeper.NewHandlers(am.keeper) - var errs error - if err := appmodulev2.RegisterHandler( - router, gogoproto.MessageName(&types.MsgUpdateParams{}), handlers.MsgUpdateParams, - ); err != nil { - errs = errors.Join(errs, err) - } - - if err := appmodulev2.RegisterHandler( - router, gogoproto.MessageName(&types.MsgSend{}), handlers.MsgSend, - ); err != nil { - errs = errors.Join(errs, err) - } - - if err := appmodulev2.RegisterHandler( - router, gogoproto.MessageName(&types.MsgMint{}), handlers.MsgMint, - ); err != nil { - errs = errors.Join(errs, err) - } - - if errs != nil { - panic(errs) - } + appmodulev2.RegisterMsgHandler(router, handlers.MsgUpdateParams) + appmodulev2.RegisterMsgHandler(router, handlers.MsgSend) + appmodulev2.RegisterMsgHandler(router, handlers.MsgMint) } // RegisterQueryHandlers registers the query handlers for the bank module. func (am AppModule) RegisterQueryHandlers(router appmodulev2.QueryRouter) { handlers := keeper.NewHandlers(am.keeper) - var errs error - if err := appmodulev2.RegisterHandler( - router, gogoproto.MessageName(&types.QueryParamsRequest{}), handlers.QueryParams, - ); err != nil { - errs = errors.Join(errs, err) - } - - if err := appmodulev2.RegisterHandler( - router, gogoproto.MessageName(&types.QueryBalanceRequest{}), handlers.QueryBalance, - ); err != nil { - errs = errors.Join(errs, err) - } - - if errs != nil { - panic(errs) - } -} - -// GetQueryDecoders returns grpc request and the corresponding decoder. -func (am AppModule) GetQueryDecoders() map[string]func() gogoproto.Message { - decodeMaps := make(map[string]func() gogoproto.Message) - var errs error - - typ := gogoproto.MessageType(gogoproto.MessageName(&types.QueryParamsRequest{})) - if typ == nil { - errs = errors.Join(errs, fmt.Errorf("unable to find message in gogotype registry")) - } - decodeMaps[gogoproto.MessageName(&types.QueryParamsRequest{})] = func() gogoproto.Message { - return reflect.New(typ.Elem()).Interface().(gogoproto.Message) - } - - typ = gogoproto.MessageType(gogoproto.MessageName(&types.QueryBalanceRequest{})) - if typ == nil { - errs = errors.Join(errs, fmt.Errorf("unable to find message in gogotype registry")) - } - decodeMaps[gogoproto.MessageName(&types.QueryBalanceRequest{})] = func() gogoproto.Message { - return reflect.New(typ.Elem()).Interface().(gogoproto.Message) - } - - if errs != nil { - panic(errs) - } - return decodeMaps + appmodulev2.RegisterMsgHandler(router, handlers.QueryParams) + appmodulev2.RegisterMsgHandler(router, handlers.QueryBalance) } // GetTxCmd returns the root tx command for the bank/v2 module. diff --git a/x/bank/v2/types/module/module.pb.go b/x/bank/v2/types/module/module.pb.go index 247cbd747e3b..d752f9ecf933 100644 --- a/x/bank/v2/types/module/module.pb.go +++ b/x/bank/v2/types/module/module.pb.go @@ -27,6 +27,11 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Module struct { // authority defines the custom module authority. If not set, defaults to the governance module. Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // restrictions_order specifies the order of send restrictions and should be + // a list of module names which provide a send restriction instance. If no + // order is provided, then restrictions will be applied in alphabetical order + // of module names. + RestrictionsOrder []string `protobuf:"bytes,2,rep,name=restrictions_order,json=restrictionsOrder,proto3" json:"restrictions_order,omitempty"` } func (m *Module) Reset() { *m = Module{} } @@ -69,6 +74,13 @@ func (m *Module) GetAuthority() string { return "" } +func (m *Module) GetRestrictionsOrder() []string { + if m != nil { + return m.RestrictionsOrder + } + return nil +} + func init() { proto.RegisterType((*Module)(nil), "cosmos.bank.module.v2.Module") } @@ -78,19 +90,21 @@ func init() { } var fileDescriptor_34a109a905e2a25b = []byte{ - // 184 bytes of a gzipped FileDescriptorProto + // 219 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4a, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0x4f, 0x4a, 0xcc, 0xcb, 0xd6, 0xcf, 0xcd, 0x4f, 0x29, 0xcd, 0x49, 0xd5, 0x2f, 0x33, 0x82, 0xb2, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x44, 0x21, 0x6a, 0xf4, 0x40, 0x6a, 0xf4, 0xa0, 0x32, 0x65, 0x46, 0x52, 0x0a, 0x50, 0xad, 0x89, 0x05, 0x05, 0xfa, 0x65, 0x86, 0x89, - 0x39, 0x05, 0x19, 0x89, 0x86, 0x28, 0x1a, 0x95, 0xdc, 0xb8, 0xd8, 0x7c, 0xc1, 0x7c, 0x21, 0x19, + 0x39, 0x05, 0x19, 0x89, 0x86, 0x28, 0x1a, 0x95, 0x4a, 0xb9, 0xd8, 0x7c, 0xc1, 0x7c, 0x21, 0x19, 0x2e, 0xce, 0xc4, 0xd2, 0x92, 0x8c, 0xfc, 0xa2, 0xcc, 0x92, 0x4a, 0x09, 0x46, 0x05, 0x46, 0x0d, - 0xce, 0x20, 0x84, 0x80, 0x95, 0xdc, 0xae, 0x03, 0xd3, 0x6e, 0x31, 0x4a, 0x70, 0x89, 0x41, 0x4c, - 0x2c, 0x4e, 0xc9, 0xd6, 0xcb, 0xcc, 0xd7, 0xaf, 0x80, 0x38, 0xaa, 0xcc, 0xc8, 0xc9, 0xf6, 0xc4, - 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, - 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x94, 0xb1, 0xeb, 0xd0, 0x2f, 0xa9, 0x2c, - 0x48, 0x2d, 0x86, 0x3a, 0x26, 0x89, 0x0d, 0xec, 0x1a, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x5e, 0xfc, 0x10, 0x2c, 0xec, 0x00, 0x00, 0x00, + 0xce, 0x20, 0x84, 0x80, 0x90, 0x2e, 0x97, 0x50, 0x51, 0x6a, 0x71, 0x49, 0x51, 0x66, 0x72, 0x49, + 0x66, 0x7e, 0x5e, 0x71, 0x7c, 0x7e, 0x51, 0x4a, 0x6a, 0x91, 0x04, 0x93, 0x02, 0xb3, 0x06, 0x67, + 0x90, 0x20, 0xb2, 0x8c, 0x3f, 0x48, 0xc2, 0x4a, 0x6e, 0xd7, 0x81, 0x69, 0xb7, 0x18, 0x25, 0xb8, + 0xc4, 0x20, 0x0e, 0x28, 0x4e, 0xc9, 0xd6, 0xcb, 0xcc, 0xd7, 0xaf, 0x80, 0xf8, 0xa1, 0xcc, 0xc8, + 0xc9, 0xf6, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, + 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x94, 0xb1, 0xeb, 0xd0, + 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0x86, 0xba, 0x3d, 0x89, 0x0d, 0xec, 0x78, 0x63, 0x40, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x69, 0x6d, 0xb0, 0x10, 0x1b, 0x01, 0x00, 0x00, } func (m *Module) Marshal() (dAtA []byte, err error) { @@ -113,6 +127,15 @@ func (m *Module) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.RestrictionsOrder) > 0 { + for iNdEx := len(m.RestrictionsOrder) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.RestrictionsOrder[iNdEx]) + copy(dAtA[i:], m.RestrictionsOrder[iNdEx]) + i = encodeVarintModule(dAtA, i, uint64(len(m.RestrictionsOrder[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } if len(m.Authority) > 0 { i -= len(m.Authority) copy(dAtA[i:], m.Authority) @@ -144,6 +167,12 @@ func (m *Module) Size() (n int) { if l > 0 { n += 1 + l + sovModule(uint64(l)) } + if len(m.RestrictionsOrder) > 0 { + for _, s := range m.RestrictionsOrder { + l = len(s) + n += 1 + l + sovModule(uint64(l)) + } + } return n } @@ -214,6 +243,38 @@ func (m *Module) Unmarshal(dAtA []byte) error { } m.Authority = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RestrictionsOrder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModule + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModule + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RestrictionsOrder = append(m.RestrictionsOrder, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipModule(dAtA[iNdEx:]) diff --git a/x/bank/v2/types/restrictions.go b/x/bank/v2/types/restrictions.go new file mode 100644 index 000000000000..89c1f7e6cfea --- /dev/null +++ b/x/bank/v2/types/restrictions.go @@ -0,0 +1,57 @@ +package types + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// A SendRestrictionFn can restrict sends and/or provide a new receiver address. +type SendRestrictionFn func(ctx context.Context, fromAddr, toAddr []byte, amt sdk.Coins) (newToAddr []byte, err error) + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (SendRestrictionFn) IsOnePerModuleType() {} + +var _ SendRestrictionFn = NoOpSendRestrictionFn + +// NoOpSendRestrictionFn is a no-op SendRestrictionFn. +func NoOpSendRestrictionFn(_ context.Context, _, toAddr []byte, _ sdk.Coins) ([]byte, error) { + return toAddr, nil +} + +// Then creates a composite restriction that runs this one then the provided second one. +func (r SendRestrictionFn) Then(second SendRestrictionFn) SendRestrictionFn { + return ComposeSendRestrictions(r, second) +} + +// ComposeSendRestrictions combines multiple SendRestrictionFn into one. +// nil entries are ignored. +// If all entries are nil, nil is returned. +// If exactly one entry is not nil, it is returned. +// Otherwise, a new SendRestrictionFn is returned that runs the non-nil restrictions in the order they are given. +// The composition runs each send restriction until an error is encountered and returns that error, +// otherwise it returns the toAddr of the last send restriction. +func ComposeSendRestrictions(restrictions ...SendRestrictionFn) SendRestrictionFn { + toRun := make([]SendRestrictionFn, 0, len(restrictions)) + for _, r := range restrictions { + if r != nil { + toRun = append(toRun, r) + } + } + switch len(toRun) { + case 0: + return nil + case 1: + return toRun[0] + } + return func(ctx context.Context, fromAddr, toAddr []byte, amt sdk.Coins) ([]byte, error) { + var err error + for _, r := range toRun { + toAddr, err = r(ctx, fromAddr, toAddr, amt) + if err != nil { + return toAddr, err + } + } + return toAddr, err + } +} diff --git a/x/circuit/autocli.go b/x/circuit/autocli.go index 898028247808..e9cc67701cf7 100644 --- a/x/circuit/autocli.go +++ b/x/circuit/autocli.go @@ -43,7 +43,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { "SOME_MSGS" = 1, "ALL_MSGS" = 2, "SUPER_ADMIN" = 3,`, - Example: fmt.Sprintf(`%s circuit authorize [address] '{"level":1,"limit_type_urls":["/cosmos.bank.v1beta1.MsgSend, /cosmos.bank.v1beta1.MsgMultiSend"]}'"`, version.AppName), + Example: fmt.Sprintf(`%s tx circuit authorize [address] '{"level":1,"limit_type_urls":["/cosmos.bank.v1beta1.MsgSend, /cosmos.bank.v1beta1.MsgMultiSend"]}'"`, version.AppName), PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: "grantee"}, {ProtoField: "permissions"}, // TODO(@julienrbrt) Support flattening msg for setting each field as a positional arg @@ -53,7 +53,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { RpcMethod: "TripCircuitBreaker", Use: "disable ", Short: "Disable a message from being executed", - Example: fmt.Sprintf(`%s circuit disable "/cosmos.bank.v1beta1.MsgSend /cosmos.bank.v1beta1.MsgMultiSend"`, version.AppName), + Example: fmt.Sprintf(`%s tx circuit disable "/cosmos.bank.v1beta1.MsgSend /cosmos.bank.v1beta1.MsgMultiSend"`, version.AppName), PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: "msg_type_urls", Varargs: true}, }, @@ -62,7 +62,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { RpcMethod: "ResetCircuitBreaker", Use: "reset ", Short: "Enable a message to be executed", - Example: fmt.Sprintf(`%s circuit reset "/cosmos.bank.v1beta1.MsgSend /cosmos.bank.v1beta1.MsgMultiSend"`, version.AppName), + Example: fmt.Sprintf(`%s tx circuit reset "/cosmos.bank.v1beta1.MsgSend /cosmos.bank.v1beta1.MsgMultiSend"`, version.AppName), PositionalArgs: []*autocliv1.PositionalArgDescriptor{ {ProtoField: "msg_type_urls", Varargs: true}, }, diff --git a/x/circuit/go.mod b/x/circuit/go.mod index 99934795a92a..57801be443d0 100644 --- a/x/circuit/go.mod +++ b/x/circuit/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -16,7 +16,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 ) require ( @@ -24,7 +24,7 @@ require ( buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/log v1.4.1 // indirect cosmossdk.io/math v1.3.0 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect @@ -121,7 +121,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -158,7 +158,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/x/circuit/go.sum b/x/circuit/go.sum index 747470c22d80..c9df997e10ec 100644 --- a/x/circuit/go.sum +++ b/x/circuit/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -414,8 +414,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -640,8 +640,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -652,8 +652,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/consensus/go.mod b/x/consensus/go.mod index de3ed1071c85..cee2372dc92d 100644 --- a/x/consensus/go.mod +++ b/x/consensus/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/store v1.1.1-0.20240418092142-896cdf1971bc @@ -18,7 +18,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 ) require ( @@ -27,7 +27,7 @@ require ( cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.4.1 // indirect cosmossdk.io/math v1.3.0 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect @@ -120,7 +120,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -157,7 +157,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/x/consensus/go.sum b/x/consensus/go.sum index 9fa6a4ca9fb4..6a6b2df0b205 100644 --- a/x/consensus/go.sum +++ b/x/consensus/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -414,8 +414,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -636,8 +636,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -648,8 +648,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/distribution/go.mod b/x/distribution/go.mod index d8fcd655d5f4..dac4ae3041e6 100644 --- a/x/distribution/go.mod +++ b/x/distribution/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -18,19 +18,18 @@ require ( github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/hashicorp/go-metrics v0.5.3 github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 ) require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/log v1.4.1 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/tx v0.13.3 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -92,6 +91,7 @@ require ( github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/hashicorp/go-plugin v1.6.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect @@ -122,7 +122,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -158,7 +158,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/x/distribution/go.sum b/x/distribution/go.sum index 934d22e1cbe7..7588b565a0d7 100644 --- a/x/distribution/go.sum +++ b/x/distribution/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -412,8 +412,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -638,8 +638,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -650,8 +650,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/distribution/keeper/abci.go b/x/distribution/keeper/abci.go index 5831ee9e1b9d..361a329a6108 100644 --- a/x/distribution/keeper/abci.go +++ b/x/distribution/keeper/abci.go @@ -11,7 +11,8 @@ import ( // BeginBlocker sets the proposer for determining distribution during endblock // and distribute rewards for the previous block. func (k Keeper) BeginBlocker(ctx context.Context) error { - defer telemetry.ModuleMeasureSince(types.ModuleName, telemetry.Now(), telemetry.MetricKeyBeginBlocker) + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyBeginBlocker) // determine the total power signing the block var previousTotalPower int64 diff --git a/x/distribution/keeper/msg_server.go b/x/distribution/keeper/msg_server.go index 0a4b9f32ca49..5d1fbdcba553 100644 --- a/x/distribution/keeper/msg_server.go +++ b/x/distribution/keeper/msg_server.go @@ -4,12 +4,9 @@ import ( "context" "fmt" - "github.com/hashicorp/go-metrics" - "cosmossdk.io/errors" "cosmossdk.io/x/distribution/types" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -61,18 +58,6 @@ func (k msgServer) WithdrawDelegatorReward(ctx context.Context, msg *types.MsgWi return nil, err } - defer func() { - for _, a := range amount { - if a.Amount.IsInt64() { - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", "withdraw_reward"}, - float32(a.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, - ) - } - } - }() - return &types.MsgWithdrawDelegatorRewardResponse{Amount: amount}, nil } @@ -87,18 +72,6 @@ func (k msgServer) WithdrawValidatorCommission(ctx context.Context, msg *types.M return nil, err } - defer func() { - for _, a := range amount { - if a.Amount.IsInt64() { - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", "withdraw_commission"}, - float32(a.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, - ) - } - } - }() - return &types.MsgWithdrawValidatorCommissionResponse{Amount: amount}, nil } diff --git a/x/epochs/go.mod b/x/epochs/go.mod index 05f635296b34..b8262cba4f35 100644 --- a/x/epochs/go.mod +++ b/x/epochs/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -17,10 +17,10 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 ) -require cosmossdk.io/schema v0.3.0 // indirect +require cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect @@ -119,7 +119,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -156,7 +156,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/x/epochs/go.sum b/x/epochs/go.sum index 9fa6a4ca9fb4..6a6b2df0b205 100644 --- a/x/epochs/go.sum +++ b/x/epochs/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -414,8 +414,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -636,8 +636,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -648,8 +648,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/epochs/keeper/abci.go b/x/epochs/keeper/abci.go index 33821e7fd92c..4b8ab757dae9 100644 --- a/x/epochs/keeper/abci.go +++ b/x/epochs/keeper/abci.go @@ -11,7 +11,8 @@ import ( // BeginBlocker of epochs module. func (k Keeper) BeginBlocker(ctx context.Context) error { - defer telemetry.ModuleMeasureSince(types.ModuleName, telemetry.Now(), telemetry.MetricKeyBeginBlocker) + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyBeginBlocker) headerInfo := k.HeaderService.HeaderInfo(ctx) err := k.EpochInfo.Walk( diff --git a/x/evidence/go.mod b/x/evidence/go.mod index e2170919c18e..94af124c0a3d 100644 --- a/x/evidence/go.mod +++ b/x/evidence/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -20,7 +20,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -28,7 +28,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/log v1.4.1 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect @@ -123,7 +123,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -159,7 +159,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/x/evidence/go.sum b/x/evidence/go.sum index 747470c22d80..c9df997e10ec 100644 --- a/x/evidence/go.sum +++ b/x/evidence/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -414,8 +414,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -640,8 +640,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -652,8 +652,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/evidence/keeper/abci.go b/x/evidence/keeper/abci.go index 38a84ba4ce01..a39b4b3e5e91 100644 --- a/x/evidence/keeper/abci.go +++ b/x/evidence/keeper/abci.go @@ -13,7 +13,8 @@ import ( // BeginBlocker iterates through and handles any newly discovered evidence of // misbehavior submitted by CometBFT. Currently, only equivocation is handled. func (k Keeper) BeginBlocker(ctx context.Context, cometService comet.Service) error { - defer telemetry.ModuleMeasureSince(types.ModuleName, telemetry.Now(), telemetry.MetricKeyBeginBlocker) + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyBeginBlocker) bi := cometService.CometInfo(ctx) diff --git a/x/feegrant/go.mod b/x/feegrant/go.mod index cd3f93c41d25..56310d95579a 100644 --- a/x/feegrant/go.mod +++ b/x/feegrant/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -23,7 +23,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 gotest.tools/v3 v3.5.1 ) @@ -37,7 +37,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/log v1.4.1 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect @@ -131,7 +131,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -167,7 +167,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect pgregory.net/rapid v1.1.0 // indirect diff --git a/x/feegrant/go.sum b/x/feegrant/go.sum index ed1e72cb37a6..8e11511b6d57 100644 --- a/x/feegrant/go.sum +++ b/x/feegrant/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o= cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190/go.mod h1:7WUGupOvmlHJoIMBz1JbObQxeo6/TDiuDBxmtod8HRg= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= @@ -422,8 +422,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -650,8 +650,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -662,8 +662,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/genutil/gentx_test.go b/x/genutil/gentx_test.go index 10721c819e12..d93199ce2e6c 100644 --- a/x/genutil/gentx_test.go +++ b/x/genutil/gentx_test.go @@ -36,7 +36,7 @@ var ( pk2 = priv2.PubKey() addr1 = sdk.AccAddress(pk1.Address()) addr2 = sdk.AccAddress(pk2.Address()) - desc = stakingtypes.NewDescription("testname", "", "", "", "") + desc = stakingtypes.NewDescription("testname", "", "", "", "", stakingtypes.Metadata{}) comm = stakingtypes.CommissionRates{} ) diff --git a/x/genutil/types/genesis_state_test.go b/x/genutil/types/genesis_state_test.go index b5741bef7f81..9e04d9a5f571 100644 --- a/x/genutil/types/genesis_state_test.go +++ b/x/genutil/types/genesis_state_test.go @@ -39,7 +39,7 @@ func TestNetGenesisState(t *testing.T) { } func TestValidateGenesisMultipleMessages(t *testing.T) { - desc := stakingtypes.NewDescription("testname", "", "", "", "") + desc := stakingtypes.NewDescription("testname", "", "", "", "", stakingtypes.Metadata{}) comm := stakingtypes.CommissionRates{} valAc := codectestutil.CodecOptions{}.GetValidatorCodec() @@ -66,7 +66,7 @@ func TestValidateGenesisMultipleMessages(t *testing.T) { } func TestValidateGenesisBadMessage(t *testing.T) { - desc := stakingtypes.NewDescription("testname", "", "", "", "") + desc := stakingtypes.NewDescription("testname", "", "", "", "", stakingtypes.Metadata{}) pk1Addr, err := codectestutil.CodecOptions{}.GetValidatorCodec().BytesToString(pk1.Address()) require.NoError(t, err) msg1 := stakingtypes.NewMsgEditValidator(pk1Addr, desc, nil, nil) diff --git a/x/gov/README.md b/x/gov/README.md index 15f86d335b1e..cda1af118b6c 100644 --- a/x/gov/README.md +++ b/x/gov/README.md @@ -18,13 +18,9 @@ currently supports: * **Proposal submission:** Users can submit proposals with a deposit. Once the minimum deposit is reached, the proposal enters voting period. The minimum deposit can be reached by collecting deposits from different users (including proposer) within deposit period. * **Vote:** Participants can vote on proposals that reached MinDeposit and entered voting period. -* **Inheritance and penalties:** Delegators inherit their validator's vote if -they don't vote themselves. +* **Inheritance and penalties:** Delegators, by default, inherit their validator's vote if they don't vote themselves. * **Claiming deposit:** Users that deposited on proposals can recover their -deposits if the proposal was accepted or rejected. If the proposal was vetoed, or never entered voting period (minimum deposit not reached within deposit period), the deposit is burned. - -This module is in use on the Cosmos Hub (a.k.a [gaia](https://github.com/cosmos/gaia)). - +deposits if the proposal was accepted or rejected. If the proposal was vetoed, or never entered voting period (minimum deposit not reached within deposit period), the deposit is burned (or refunded depending on the gov parameters). ## Contents @@ -59,7 +55,6 @@ staking token of the chain. * [Metadata](#metadata) * [Proposal](#proposal-3) * [Vote](#vote-5) -* [Future Improvements](#future-improvements) ## Concepts @@ -87,7 +82,7 @@ proposal passes. The messages are executed by the governance `ModuleAccount` its such as `x/upgrade`, that want to allow certain messages to be executed by governance only should add a whitelist within the respective msg server, granting the governance module the right to execute the message once a quorum has been reached. The governance -module uses the `MsgServiceRouter` to check that these messages are correctly constructed +module uses the core `router.Service` to check that these messages are correctly constructed and have a respective path to execute on but do not perform a full validity check. :::warning @@ -118,16 +113,22 @@ proposal is finalized (passed or rejected). #### Deposit refund and burn When a proposal is finalized, the coins from the deposit are either refunded or burned -according to the final tally of the proposal: +according to the final tally of the proposal and the governance module parameters: +* All refunded or burned deposits are removed from the state. Events are issued when + burning or refunding a deposit. * If the proposal is approved or rejected but *not* vetoed, each deposit will be automatically refunded to its respective depositor (transferred from the governance `ModuleAccount`). -* When the proposal is vetoed with greater than 1/3, deposits will be burned from the - governance `ModuleAccount` and the proposal information along with its deposit - information will be removed from state. -* All refunded or burned deposits are removed from the state. Events are issued when - burning or refunding a deposit. +* If the proposal is marked as Spam, the deposit will be burned. + +For other cases, they are three parameters that define if the deposit of a proposal should be burned or returned to the depositors. + +* `BurnVoteVeto` burns the proposal deposit if the proposal gets vetoed. +* `BurnVoteQuorum` burns the proposal deposit if the vote does not reach quorum. +* `BurnProposalDepositPrevote` burns the proposal deposit if it does not enter the voting phase. + +> Note: These parameters are modifiable via governance. ### Vote @@ -144,7 +145,7 @@ Note that when *participants* have bonded and unbonded Atoms, their voting power Once a proposal reaches `MinDeposit`, it immediately enters `Voting period`. We define `Voting period` as the interval between the moment the vote opens and -the moment the vote closes. The initial value of `Voting period` is 2 weeks. +the moment the vote closes. The default value of `Voting period` is 2 weeks but is modifiable at genesis or governance. #### Option set @@ -163,8 +164,6 @@ The initial option set includes the following options: allows voters to signal that they do not intend to vote in favor or against the proposal but accept the result of the vote. -*Note: from the UI, for urgent proposals we should maybe add a ‘Not Urgent’ option that casts a `NoWithVeto` vote.* - #### Weighted Votes [ADR-037](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-037-gov-split-vote.md) introduces the weighted vote feature which allows a staker to split their votes into several voting options. For example, it could use 70% of its voting power to vote Yes and 30% of its voting power to vote No. @@ -174,11 +173,11 @@ Often times the entity owning that address might not be a single individual. For To represent weighted vote on chain, we use the following Protobuf message. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1beta1/gov.proto#L34-L47 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/proto/cosmos/gov/v1/gov.proto#L56-L63 ``` ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1beta1/gov.proto#L181-L201 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/proto/cosmos/gov/v1/gov.proto#L202-L219 ``` For a weighted vote to be valid, the `options` field must not contain duplicate vote options, and the sum of weights of all options must be equal to 1. @@ -204,7 +203,7 @@ By default, `YesQuorum` is set to 0, which means no minimum. ### Proposal Types -Proposal types have been introduced in ADR-069. +Proposal types have been introduced in [ADR-069](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-069-gov-improvements.md). #### Standard proposal @@ -225,17 +224,16 @@ A chain can optionally set a list of authorized addresses that can submit optimi #### Multiple Choice Proposals A multiple choice proposal is a proposal where the voting options can be defined by the proposer. -The number of voting options is limited to a maximum of 4. +The number of voting options is limited to a maximum of **4**. Multiple choice proposals, contrary to any other proposal type, cannot have messages to execute. They are only text proposals. -#### Threshold +### Threshold -Threshold is defined as the minimum proportion of `Yes` votes (excluding -`Abstain` votes) for the proposal to be accepted. +Threshold is defined as the minimum proportion of `Yes` votes (excluding `Abstain` votes) for the proposal to be accepted. -Initially, the threshold is set at 50% of `Yes` votes, excluding `Abstain` -votes. A possibility to veto exists if more than 1/3rd of all votes are -`NoWithVeto` votes. Note, both of these values are derived from the `TallyParams` +Initially, the threshold is set at 50% of `Yes` votes, excluding `Abstain` votes. +A possibility to veto exists if more than 1/3rd of all votes are `NoWithVeto` votes. +Note, both of these values are derived from the `Params` on-chain parameter, which is modifiable by governance. This means that proposals are accepted iff: @@ -249,43 +247,37 @@ This means that proposals are accepted iff: For expedited proposals, by default, the threshold is higher than with a *normal proposal*, namely, 66.7%. -#### Inheritance +### Inheritance -If a delegator does not vote, it will inherit its validator vote. +If a delegator does not vote, by default, it will inherit its validator vote. -* If the delegator votes before its validator, it will not inherit from the - validator's vote. -* If the delegator votes after its validator, it will override its validator - vote with its own. If the proposal is urgent, it is possible - that the vote will close before delegators have a chance to react and +* If the delegator votes before its validator, it will not inherit from the validator's vote. +* If the delegator votes after its validator, it will override its validator vote with its own. + If the proposal is urgent, it is possible that the vote will close before delegators have a chance to react and override their validator's vote. This is not a problem, as proposals require more than 2/3rd of the total voting power to pass, when tallied at the end of the voting period. Because as little as 1/3 + 1 validation power could collude to censor transactions, non-collusion is already assumed for ranges exceeding this threshold. -#### Validator’s punishment for non-voting - -At present, validators are not punished for failing to vote. - -#### Governance address - -Later, we may add permissioned keys that could only sign txs from certain modules. For the MVP, the `Governance address` will be the main validator address generated at account creation. This address corresponds to a different PrivKey than the CometBFT PrivKey which is responsible for signing consensus messages. Validators thus do not have to sign governance transactions with the sensitive CometBFT PrivKey. - -#### Burnable Params +This behavior can be changed by passing a custom tally calculation function to the governance module. -There are three parameters that define if the deposit of a proposal should be burned or returned to the depositors. +```go reference +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/keeper/config.go#L33-L35 +``` -* `BurnVoteVeto` burns the proposal deposit if the proposal gets vetoed. -* `BurnVoteQuorum` burns the proposal deposit if the vote does not reach quorum. -* `BurnProposalDepositPrevote` burns the proposal deposit if it does not enter the voting phase. +#### Validator’s punishment for non-voting -> Note: These parameters are modifiable via governance. +At present, validators are not punished for failing to vote. #### Execution -Execution is the process of executing the messages contained in a proposal. The execution phase will commence after the proposal has been accepted by the network. The messages contained in the proposal will be executed in the order they were submitted. +Execution is the process of executing the messages contained in a proposal. The execution phase will commence after the proposal has been accepted by the network. The messages contained in the proposal will be executed in the order they were submitted. All messages must be executed successfully for the proposal to be considered successful. I + +If a proposal passes but fails to execute, the proposal will be marked as `StatusFailed`. This status is different from `StatusRejected`, which is used when a proposal fails to pass. Execution has an upper limit on how much gas can be consumed in a single block. This limit is defined by the `ProposalExecutionGas` parameter. ## State +The governance module uses [collections](https://docs.cosmos.network/v0.50/build/packages/collections) for state management. + ### Constitution `Constitution` is found in the genesis state. It is a string field intended to be used to describe the purpose of a particular blockchain, and its expected norms. A few examples of how the constitution field can be used: @@ -328,7 +320,7 @@ unique id and contains a series of timestamps: `submit_time`, `deposit_end_time` `voting_start_time`, `voting_end_time` which track the lifecycle of a proposal ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L51-L99 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/proto/cosmos/gov/v1/gov.proto#L78-L134 ``` A proposal will generally require more than just a set of messages to explain its @@ -354,7 +346,13 @@ the following `JSON` template: This makes it far easier for clients to support multiple networks. Fields metadata, title and summary have a maximum length that is chosen by the app developer, and -passed into the gov keeper as a config. The default maximum length are: for the title 255 characters, for the metadata 255 characters and for summary 10200 characters (40 times the one of the title). +passed into the gov keeper as a config (`x/gov/keeper/config`). + +The default maximum length are: + +```go reference +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/keeper/config.go#L38-L47 +``` #### Writing a module that uses governance @@ -372,37 +370,20 @@ Note, any message can be executed by governance if embedded in `MsgSudoExec`. ### Parameters and base types -`Parameters` define the rules according to which votes are run. There can only -be one active parameter set at any given time. If governance wants to change a -parameter set, either to modify a value or add/remove a parameter field, a new -parameter set has to be created and the previous one rendered inactive. - -#### DepositParams - -```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L152-L162 -``` - -#### VotingParams - -```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L164-L168 -``` - -#### TallyParams +`Params` define the rules according to which votes are run. If governance wants to change a +parameter it can do so by submitting a gov `MsgUpdateParams` governance proposal. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L170-L182 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/proto/cosmos/gov/v1/gov.proto#L259-L348 ``` -Parameters are stored in a global `GlobalParams` KVStore. +Parameters are stored in the `gov` store under the key `ParamsKey`. Additionally, we introduce some basic types: ```go type ProposalStatus byte - const ( StatusNil ProposalStatus = 0x00 StatusDepositPeriod ProposalStatus = 0x01 // Proposal is submitted. Participants can deposit on it but not vote @@ -416,7 +397,7 @@ const ( ### Deposit ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/gov.proto#L38-L49 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/proto/cosmos/gov/v1/gov.proto#L65-L76 ``` ### ValidatorGovInfo @@ -430,50 +411,12 @@ This type is used in a temp map when tallying } ``` -## Stores - -:::note -Stores are KVStores in the multi-store. The key to find the store is the first parameter in the list -::: - -We will use one KVStore `Governance` to store four mappings: - -* A mapping from `proposalID|'proposal'` to `Proposal`. -* A mapping from `proposalID|'addresses'|address` to `Vote`. This mapping allows - us to query all addresses that voted on the proposal along with their vote by - doing a range query on `proposalID:addresses`. -* A mapping from `ParamsKey|'Params'` to `Params`. This map allows to query all - x/gov params. - -For pseudocode purposes, here are the two functions we will use to read or write in stores: - -* `load(StoreKey, Key)`: Retrieve item stored at key `Key` in store found at key `StoreKey` in the multistore -* `store(StoreKey, Key, value)`: Write value `Value` at key `Key` in store found at key `StoreKey` in the multistore - -### Proposal Processing Queue - -**Store:** - -* `ProposalProcessingQueue`: A queue `queue[proposalID]` containing all the - `ProposalIDs` of proposals that reached `MinDeposit`. During each `EndBlock`, - all the proposals that have reached the end of their voting period are processed. - To process a finished proposal, the application tallies the votes, computes the - votes of each validator and checks if every validator in the validator set has - voted. If the proposal is accepted, deposits are refunded. Finally, the proposal - content `Handler` is executed. - ### Legacy Proposal :::warning -Legacy proposals are deprecated. Use the new proposal flow by granting the governance module the right to execute the message. +Legacy proposals (`gov/v1beta1`) are deprecated. Use the new proposal flow by granting the governance module the right to execute the message. ::: -A legacy proposal is the old implementation of governance proposal. -Contrary to proposal that can contain any messages, a legacy proposal allows to submit a set of pre-defined proposals. -These proposals are defined by their types and handled by handlers that are registered in the gov v1beta1 router. - -More information on how to submit proposals is in the [client section](#client). - ## Messages ### Proposal Submission @@ -481,37 +424,28 @@ More information on how to submit proposals is in the [client section](#client). Proposals can be submitted by any account via a `MsgSubmitProposal` or a `MsgSubmitMultipleChoiceProposal` transaction. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L42-L69 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/proto/cosmos/gov/v1/tx.proto#L64-L102 ``` -:::note +```protobuf reference +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/proto/cosmos/gov/v1/tx.proto#L229-L256 +``` + +:::tip A multiple choice proposal is a proposal where the voting options can be defined by the proposer. It cannot have messages to execute. It is only a text proposal. -::: - -:::warning -Submitting a multiple choice proposal using `MsgSubmitProposal` is invalid, as vote options cannot be defined. +This means submitting a multiple choice proposal using `MsgSubmitProposal` is invalid, as vote options cannot be defined. ::: All `sdk.Msgs` passed into the `messages` field of a `MsgSubmitProposal` message -must be registered in the app's `MsgServiceRouter`. Each of these messages must +must be registered in the app's message router. Each of these messages must have one signer, namely the gov module account. And finally, the metadata length must not be larger than the `maxMetadataLen` config passed into the gov keeper. The `initialDeposit` must be strictly positive and conform to the accepted denom of the `MinDeposit` param. -**State modifications:** - -* Generate new `proposalID` -* Create new `Proposal` -* Initialise `Proposal`'s attributes -* Decrease balance of sender by `InitialDeposit` -* If `MinDeposit` is reached: - * Push `proposalID` in `ProposalProcessingQueue` -* Transfer `InitialDeposit` from the `Proposer` to the governance `ModuleAccount` - ### Deposit -Once a proposal is submitted, if `Proposal.TotalDeposit < ActiveParam.MinDeposit`, Atom holders can send +Once a proposal is submitted, if `Proposal.TotalDeposit < GovParams.MinDeposit`, Atom holders can send `MsgDeposit` transactions to increase the proposal's deposit. A deposit is accepted iff: @@ -521,36 +455,19 @@ A deposit is accepted iff: * The deposited coins are conform to the accepted denom from the `MinDeposit` param ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L134-L147 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/proto/cosmos/gov/v1/tx.proto#L167-L180 ``` -**State modifications:** - -* Decrease balance of sender by `deposit` -* Add `deposit` of sender in `proposal.Deposits` -* Increase `proposal.TotalDeposit` by sender's `deposit` -* If `MinDeposit` is reached: - * Push `proposalID` in `ProposalProcessingQueueEnd` -* Transfer `Deposit` from the `proposer` to the governance `ModuleAccount` - ### Vote -Once `ActiveParam.MinDeposit` is reached, voting period starts. From there, +Once `GovParams.MinDeposit` is reached, voting period starts. From there, bonded Atom holders are able to send `MsgVote` transactions to cast their vote on the proposal. ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/gov/v1/tx.proto#L92-L108 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/proto/cosmos/gov/v1/tx.proto#L125-L141 ``` -**State modifications:** - -* Record `Vote` of sender - -:::note -Gas cost for this message has to take into account the future tallying of the vote in EndBlocker. -::: - ## Events The governance module emits the following events: @@ -659,9 +576,44 @@ In addition to the parameters above, the governance module can also be configure If configured, these params will take precedence over the global params for a specific proposal. :::warning -Currently, messaged based parameters limit the number of messages that can be included in a proposal to 1 if a messaged based parameter is configured. +Currently, messaged based parameters limit the number of messages that can be included in a proposal. +Only messages that have the same message parameters can be included in the same proposal. +::: + +## Metadata + +The gov module has two locations for metadata where users can provide further context about the on-chain actions they are taking. By default all metadata fields have a 255 character length field where metadata can be stored in json format, either on-chain or off-chain depending on the amount of data required. Here we provide a recommendation for the json structure and where the data should be stored. There are two important factors in making these recommendations. First, that the gov and group modules are consistent with one another, note the number of proposals made by all groups may be quite large. Second, that client applications such as block explorers and governance interfaces have confidence in the consistency of metadata structure across chains. + +### Proposal + +Location: off-chain as json object stored on IPFS (mirrors [group proposal](../group/README.md#metadata)) + +```json +{ + "title": "", + "authors": [""], + "summary": "", + "details": "", + "proposal_forum_url": "", + "vote_option_context": "", +} +``` + +:::note +The `authors` field is an array of strings, this is to allow for multiple authors to be listed in the metadata. +In v0.46, the `authors` field is a comma-separated string. Frontends are encouraged to support both formats for backwards compatibility. ::: +### Vote + +Location: on-chain as json within 255 character limit (mirrors [group vote](../group/README.md#metadata)) + +```json +{ + "justification": "", +} +``` + ## Client ### CLI @@ -1043,41 +995,6 @@ By default the metadata, summary and title are both limited by 255 characters, t When metadata is not specified, the title is limited to 255 characters and the summary 40x the title length. ::: -##### submit-legacy-proposal - -The `submit-legacy-proposal` command allows users to submit a governance legacy proposal along with an initial deposit. - -```bash -simd tx gov submit-legacy-proposal [command] [flags] -``` - -Example: - -```bash -simd tx gov submit-legacy-proposal --title="Test Proposal" --description="testing" --type="Text" --deposit="100000000stake" --from cosmos1.. -``` - -Example (`param-change`): - -```bash -simd tx gov submit-legacy-proposal param-change proposal.json --from cosmos1.. -``` - -```json -{ - "title": "Test Proposal", - "description": "testing, testing, 1, 2, 3", - "changes": [ - { - "subspace": "staking", - "key": "MaxValidators", - "value": 100 - } - ], - "deposit": "10000000stake" -} -``` - ##### cancel-proposal Once proposal is canceled, from the deposits of proposal `deposits * proposal_cancel_ratio` will be burned or sent to `ProposalCancelDest` address , if `ProposalCancelDest` is empty then deposits will be burned. The `remaining deposits` will be sent to depositors. @@ -1128,10 +1045,8 @@ A user can query the `gov` module using gRPC endpoints. The `Proposal` endpoint allows users to query a given proposal. -Using legacy v1beta1: - ```bash -cosmos.gov.v1beta1.Query/Proposal +cosmos.gov.v1.Query/Proposal ``` Example: @@ -1140,312 +1055,99 @@ Example: grpcurl -plaintext \ -d '{"proposal_id":"1"}' \ localhost:9090 \ - cosmos.gov.v1beta1.Query/Proposal + cosmos.gov.v1.Query/Proposal ``` -Example Output: - -```bash -{ - "proposal": { - "proposalId": "1", - "content": {"@type":"/cosmos.gov.v1beta1.TextProposal","description":"testing, testing, 1, 2, 3","title":"Test Proposal"}, - "status": "PROPOSAL_STATUS_VOTING_PERIOD", - "finalTallyResult": { - "yes": "0", - "abstain": "0", - "no": "0", - "noWithVeto": "0" - }, - "submitTime": "2021-09-16T19:40:08.712440474Z", - "depositEndTime": "2021-09-18T19:40:08.712440474Z", - "totalDeposit": [ - { - "denom": "stake", - "amount": "10000000" - } - ], - "votingStartTime": "2021-09-16T19:40:08.712440474Z", - "votingEndTime": "2021-09-18T19:40:08.712440474Z", - "title": "Test Proposal", - "summary": "testing, testing, 1, 2, 3" - } -} -``` +#### Proposals -Using v1: +The `Proposals` endpoint allows users to query all proposals with optional filters. ```bash -cosmos.gov.v1.Query/Proposal +cosmos.gov.v1.Query/Proposals ``` Example: ```bash grpcurl -plaintext \ - -d '{"proposal_id":"1"}' \ localhost:9090 \ - cosmos.gov.v1.Query/Proposal -``` - -Example Output: - -```bash -{ - "proposal": { - "id": "1", - "messages": [ - {"@type":"/cosmos.bank.v1beta1.MsgSend","amount":[{"denom":"stake","amount":"10"}],"fromAddress":"cosmos1..","toAddress":"cosmos1.."} - ], - "status": "PROPOSAL_STATUS_VOTING_PERIOD", - "finalTallyResult": { - "yesCount": "0", - "abstainCount": "0", - "noCount": "0", - "noWithVetoCount": "0" - }, - "submitTime": "2022-03-28T11:50:20.819676256Z", - "depositEndTime": "2022-03-30T11:50:20.819676256Z", - "totalDeposit": [ - { - "denom": "stake", - "amount": "10000000" - } - ], - "votingStartTime": "2022-03-28T14:25:26.644857113Z", - "votingEndTime": "2022-03-30T14:25:26.644857113Z", - "metadata": "AQ==", - "title": "Test Proposal", - "summary": "testing, testing, 1, 2, 3" - } -} + cosmos.gov.v1.Query/Proposals ``` -#### Proposals - -The `Proposals` endpoint allows users to query all proposals with optional filters. +#### Vote -Using legacy v1beta1: +The `Vote` endpoint allows users to query a vote for a given proposal. ```bash -cosmos.gov.v1beta1.Query/Proposals +cosmos.gov.v1.Query/Vote ``` Example: ```bash grpcurl -plaintext \ + -d '{"proposal_id":"1","voter":"cosmos1.."}' \ localhost:9090 \ - cosmos.gov.v1beta1.Query/Proposals + cosmos.gov.v1.Query/Vote ``` -Example Output: - -```bash -{ - "proposals": [ - { - "proposalId": "1", - "status": "PROPOSAL_STATUS_VOTING_PERIOD", - "finalTallyResult": { - "yes": "0", - "abstain": "0", - "no": "0", - "noWithVeto": "0" - }, - "submitTime": "2022-03-28T11:50:20.819676256Z", - "depositEndTime": "2022-03-30T11:50:20.819676256Z", - "totalDeposit": [ - { - "denom": "stake", - "amount": "10000000010" - } - ], - "votingStartTime": "2022-03-28T14:25:26.644857113Z", - "votingEndTime": "2022-03-30T14:25:26.644857113Z" - }, - { - "proposalId": "2", - "status": "PROPOSAL_STATUS_DEPOSIT_PERIOD", - "finalTallyResult": { - "yes": "0", - "abstain": "0", - "no": "0", - "noWithVeto": "0" - }, - "submitTime": "2022-03-28T14:02:41.165025015Z", - "depositEndTime": "2022-03-30T14:02:41.165025015Z", - "totalDeposit": [ - { - "denom": "stake", - "amount": "10" - } - ], - "votingStartTime": "0001-01-01T00:00:00Z", - "votingEndTime": "0001-01-01T00:00:00Z" - } - ], - "pagination": { - "total": "2" - } -} - -``` +#### Votes -Using v1: +The `Votes` endpoint allows users to query all votes for a given proposal. ```bash -cosmos.gov.v1.Query/Proposals +cosmos.gov.v1.Query/Votes ``` Example: ```bash grpcurl -plaintext \ + -d '{"proposal_id":"1"}' \ localhost:9090 \ - cosmos.gov.v1.Query/Proposals -``` - -Example Output: - -```bash -{ - "proposals": [ - { - "id": "1", - "messages": [ - {"@type":"/cosmos.bank.v1beta1.MsgSend","amount":[{"denom":"stake","amount":"10"}],"fromAddress":"cosmos1..","toAddress":"cosmos1.."} - ], - "status": "PROPOSAL_STATUS_VOTING_PERIOD", - "finalTallyResult": { - "yesCount": "0", - "abstainCount": "0", - "noCount": "0", - "noWithVetoCount": "0" - }, - "submitTime": "2022-03-28T11:50:20.819676256Z", - "depositEndTime": "2022-03-30T11:50:20.819676256Z", - "totalDeposit": [ - { - "denom": "stake", - "amount": "10000000010" - } - ], - "votingStartTime": "2022-03-28T14:25:26.644857113Z", - "votingEndTime": "2022-03-30T14:25:26.644857113Z", - "metadata": "AQ==", - "title": "Proposal Title", - "summary": "Proposal Summary" - }, - { - "id": "2", - "messages": [ - {"@type":"/cosmos.bank.v1beta1.MsgSend","amount":[{"denom":"stake","amount":"10"}],"fromAddress":"cosmos1..","toAddress":"cosmos1.."} - ], - "status": "PROPOSAL_STATUS_DEPOSIT_PERIOD", - "finalTallyResult": { - "yesCount": "0", - "abstainCount": "0", - "noCount": "0", - "noWithVetoCount": "0" - }, - "submitTime": "2022-03-28T14:02:41.165025015Z", - "depositEndTime": "2022-03-30T14:02:41.165025015Z", - "totalDeposit": [ - { - "denom": "stake", - "amount": "10" - } - ], - "metadata": "AQ==", - "title": "Proposal Title", - "summary": "Proposal Summary" - } - ], - "pagination": { - "total": "2" - } -} + cosmos.gov.v1.Query/Votes ``` -#### Vote - -The `Vote` endpoint allows users to query a vote for a given proposal. +#### Params -Using legacy v1beta1: +The `Params` endpoint allows users to query all parameters for the `gov` module. ```bash -cosmos.gov.v1beta1.Query/Vote +cosmos.gov.v1.Query/Params ``` Example: ```bash grpcurl -plaintext \ - -d '{"proposal_id":"1","voter":"cosmos1.."}' \ + -d '{"params_type":"voting"}' \ localhost:9090 \ - cosmos.gov.v1beta1.Query/Vote + cosmos.gov.v1.Query/Params ``` -Example Output: - -```bash -{ - "vote": { - "proposalId": "1", - "voter": "cosmos1..", - "option": "VOTE_OPTION_YES", - "options": [ - { - "option": "VOTE_OPTION_YES", - "weight": "1000000000000000000" - } - ] - } -} -``` +#### Deposit -Using v1: +The `Deposit` endpoint allows users to query a deposit for a given proposal from a given depositor. ```bash -cosmos.gov.v1.Query/Vote +cosmos.gov.v1.Query/Deposit ``` Example: ```bash grpcurl -plaintext \ - -d '{"proposal_id":"1","voter":"cosmos1.."}' \ + '{"proposal_id":"1","depositor":"cosmos1.."}' \ localhost:9090 \ - cosmos.gov.v1.Query/Vote -``` - -Example Output: - -```bash -{ - "vote": { - "proposalId": "1", - "voter": "cosmos1..", - "option": "VOTE_OPTION_YES", - "options": [ - { - "option": "VOTE_OPTION_YES", - "weight": "1.000000000000000000" - } - ] - } -} + cosmos.gov.v1.Query/Deposit ``` -#### Votes - -The `Votes` endpoint allows users to query all votes for a given proposal. +#### deposits -Using legacy v1beta1: +The `Deposits` endpoint allows users to query all deposits for a given proposal. ```bash -cosmos.gov.v1beta1.Query/Votes +cosmos.gov.v1.Query/Deposits ``` Example: @@ -1454,35 +1156,15 @@ Example: grpcurl -plaintext \ -d '{"proposal_id":"1"}' \ localhost:9090 \ - cosmos.gov.v1beta1.Query/Votes + cosmos.gov.v1.Query/Deposits ``` -Example Output: - -```bash -{ - "votes": [ - { - "proposalId": "1", - "voter": "cosmos1..", - "options": [ - { - "option": "VOTE_OPTION_YES", - "weight": "1000000000000000000" - } - ] - } - ], - "pagination": { - "total": "1" - } -} -``` +#### TallyResult -Using v1: +The `TallyResult` endpoint allows users to query the tally of a given proposal. ```bash -cosmos.gov.v1.Query/Votes +cosmos.gov.v1.Query/TallyResult ``` Example: @@ -1491,353 +1173,16 @@ Example: grpcurl -plaintext \ -d '{"proposal_id":"1"}' \ localhost:9090 \ - cosmos.gov.v1.Query/Votes + cosmos.gov.v1.Query/TallyResult ``` -Example Output: - -```bash -{ - "votes": [ - { - "proposalId": "1", - "voter": "cosmos1..", - "options": [ - { - "option": "VOTE_OPTION_YES", - "weight": "1.000000000000000000" - } - ] - } - ], - "pagination": { - "total": "1" - } -} -``` - -#### Params - -The `Params` endpoint allows users to query all parameters for the `gov` module. - -Using legacy v1beta1: - -```bash -cosmos.gov.v1beta1.Query/Params -``` - -Example: - -```bash -grpcurl -plaintext \ - -d '{"params_type":"voting"}' \ - localhost:9090 \ - cosmos.gov.v1beta1.Query/Params -``` - -Example Output: - -```bash -{ - "votingParams": { - "votingPeriod": "172800s" - }, - "depositParams": { - "maxDepositPeriod": "0s" - }, - "tallyParams": { - "quorum": "MA==", - "threshold": "MA==", - "vetoThreshold": "MA==" - } -} -``` - -Using v1: - -```bash -cosmos.gov.v1.Query/Params -``` - -Example: - -```bash -grpcurl -plaintext \ - -d '{"params_type":"voting"}' \ - localhost:9090 \ - cosmos.gov.v1.Query/Params -``` - -Example Output: - -```bash -{ - "votingParams": { - "votingPeriod": "172800s" - } -} -``` - -#### Deposit - -The `Deposit` endpoint allows users to query a deposit for a given proposal from a given depositor. - -Using legacy v1beta1: - -```bash -cosmos.gov.v1beta1.Query/Deposit -``` - -Example: - -```bash -grpcurl -plaintext \ - '{"proposal_id":"1","depositor":"cosmos1.."}' \ - localhost:9090 \ - cosmos.gov.v1beta1.Query/Deposit -``` - -Example Output: - -```bash -{ - "deposit": { - "proposalId": "1", - "depositor": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10000000" - } - ] - } -} -``` - -Using v1: - -```bash -cosmos.gov.v1.Query/Deposit -``` - -Example: - -```bash -grpcurl -plaintext \ - '{"proposal_id":"1","depositor":"cosmos1.."}' \ - localhost:9090 \ - cosmos.gov.v1.Query/Deposit -``` - -Example Output: - -```bash -{ - "deposit": { - "proposalId": "1", - "depositor": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10000000" - } - ] - } -} -``` - -#### deposits - -The `Deposits` endpoint allows users to query all deposits for a given proposal. - -Using legacy v1beta1: - -```bash -cosmos.gov.v1beta1.Query/Deposits -``` - -Example: - -```bash -grpcurl -plaintext \ - -d '{"proposal_id":"1"}' \ - localhost:9090 \ - cosmos.gov.v1beta1.Query/Deposits -``` - -Example Output: - -```bash -{ - "deposits": [ - { - "proposalId": "1", - "depositor": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10000000" - } - ] - } - ], - "pagination": { - "total": "1" - } -} -``` - -Using v1: - -```bash -cosmos.gov.v1.Query/Deposits -``` - -Example: - -```bash -grpcurl -plaintext \ - -d '{"proposal_id":"1"}' \ - localhost:9090 \ - cosmos.gov.v1.Query/Deposits -``` - -Example Output: - -```bash -{ - "deposits": [ - { - "proposalId": "1", - "depositor": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10000000" - } - ] - } - ], - "pagination": { - "total": "1" - } -} -``` - -#### TallyResult - -The `TallyResult` endpoint allows users to query the tally of a given proposal. - -Using legacy v1beta1: - -```bash -cosmos.gov.v1beta1.Query/TallyResult -``` - -Example: - -```bash -grpcurl -plaintext \ - -d '{"proposal_id":"1"}' \ - localhost:9090 \ - cosmos.gov.v1beta1.Query/TallyResult -``` - -Example Output: - -```bash -{ - "tally": { - "yes": "1000000", - "abstain": "0", - "no": "0", - "noWithVeto": "0", - "option_one_count": "1000000", - "option_two_count": "0", - "option_three_count": "0", - "option_four_count": "0", - "spam_count": "0" - } -} -``` - -Using v1: - -```bash -cosmos.gov.v1.Query/TallyResult -``` - -Example: - -```bash -grpcurl -plaintext \ - -d '{"proposal_id":"1"}' \ - localhost:9090 \ - cosmos.gov.v1.Query/TallyResult -``` - -Example Output: - -```bash -{ - "tally": { - "yes": "1000000", - "abstain": "0", - "no": "0", - "noWithVeto": "0" - } -} -``` - -### REST - -A user can query the `gov` module using REST endpoints. - -#### proposal - -The `proposals` endpoint allows users to query a given proposal. - -Using legacy v1beta1: - -```bash -/cosmos/gov/v1beta1/proposals/{proposal_id} -``` - -Example: - -```bash -curl localhost:1317/cosmos/gov/v1beta1/proposals/1 -``` - -Example Output: - -```bash -{ - "proposal": { - "proposal_id": "1", - "content": null, - "status": "PROPOSAL_STATUS_VOTING_PERIOD", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "2022-03-28T11:50:20.819676256Z", - "deposit_end_time": "2022-03-30T11:50:20.819676256Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "10000000010" - } - ], - "voting_start_time": "2022-03-28T14:25:26.644857113Z", - "voting_end_time": "2022-03-30T14:25:26.644857113Z" - } -} -``` - -Using v1: +### REST + +A user can query the `gov` module using REST endpoints. + +#### proposal + +The `proposals` endpoint allows users to query a given proposal. ```bash /cosmos/gov/v1/proposals/{proposal_id} @@ -1849,121 +1194,10 @@ Example: curl localhost:1317/cosmos/gov/v1/proposals/1 ``` -Example Output: - -```bash -{ - "proposal": { - "id": "1", - "messages": [ - { - "@type": "/cosmos.bank.v1beta1.MsgSend", - "from_address": "cosmos1..", - "to_address": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10" - } - ] - } - ], - "status": "PROPOSAL_STATUS_VOTING_PERIOD", - "final_tally_result": { - "yes_count": "0", - "abstain_count": "0", - "no_count": "0", - "no_with_veto_count": "0" - }, - "submit_time": "2022-03-28T11:50:20.819676256Z", - "deposit_end_time": "2022-03-30T11:50:20.819676256Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "10000000" - } - ], - "voting_start_time": "2022-03-28T14:25:26.644857113Z", - "voting_end_time": "2022-03-30T14:25:26.644857113Z", - "metadata": "AQ==", - "title": "Proposal Title", - "summary": "Proposal Summary" - } -} -``` - #### proposals The `proposals` endpoint also allows users to query all proposals with optional filters. -Using legacy v1beta1: - -```bash -/cosmos/gov/v1beta1/proposals -``` - -Example: - -```bash -curl localhost:1317/cosmos/gov/v1beta1/proposals -``` - -Example Output: - -```bash -{ - "proposals": [ - { - "proposal_id": "1", - "content": null, - "status": "PROPOSAL_STATUS_VOTING_PERIOD", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "2022-03-28T11:50:20.819676256Z", - "deposit_end_time": "2022-03-30T11:50:20.819676256Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "10000000" - } - ], - "voting_start_time": "2022-03-28T14:25:26.644857113Z", - "voting_end_time": "2022-03-30T14:25:26.644857113Z" - }, - { - "proposal_id": "2", - "content": null, - "status": "PROPOSAL_STATUS_DEPOSIT_PERIOD", - "final_tally_result": { - "yes": "0", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - }, - "submit_time": "2022-03-28T14:02:41.165025015Z", - "deposit_end_time": "2022-03-30T14:02:41.165025015Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "10" - } - ], - "voting_start_time": "0001-01-01T00:00:00Z", - "voting_end_time": "0001-01-01T00:00:00Z" - } - ], - "pagination": { - "next_key": null, - "total": "2" - } -} -``` - -Using v1: ```bash /cosmos/gov/v1/proposals @@ -1975,126 +1209,10 @@ Example: curl localhost:1317/cosmos/gov/v1/proposals ``` -Example Output: - -```bash -{ - "proposals": [ - { - "id": "1", - "messages": [ - { - "@type": "/cosmos.bank.v1beta1.MsgSend", - "from_address": "cosmos1..", - "to_address": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10" - } - ] - } - ], - "status": "PROPOSAL_STATUS_VOTING_PERIOD", - "final_tally_result": { - "yes_count": "0", - "abstain_count": "0", - "no_count": "0", - "no_with_veto_count": "0" - }, - "submit_time": "2022-03-28T11:50:20.819676256Z", - "deposit_end_time": "2022-03-30T11:50:20.819676256Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "10000000010" - } - ], - "voting_start_time": "2022-03-28T14:25:26.644857113Z", - "voting_end_time": "2022-03-30T14:25:26.644857113Z", - "metadata": "AQ==", - "title": "Proposal Title", - "summary": "Proposal Summary" - }, - { - "id": "2", - "messages": [ - { - "@type": "/cosmos.bank.v1beta1.MsgSend", - "from_address": "cosmos1..", - "to_address": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10" - } - ] - } - ], - "status": "PROPOSAL_STATUS_DEPOSIT_PERIOD", - "final_tally_result": { - "yes_count": "0", - "abstain_count": "0", - "no_count": "0", - "no_with_veto_count": "0" - }, - "submit_time": "2022-03-28T14:02:41.165025015Z", - "deposit_end_time": "2022-03-30T14:02:41.165025015Z", - "total_deposit": [ - { - "denom": "stake", - "amount": "10" - } - ], - "voting_start_time": null, - "voting_end_time": null, - "metadata": "AQ==", - "title": "Proposal Title", - "summary": "Proposal Summary" - } - ], - "pagination": { - "next_key": null, - "total": "2" - } -} -``` - #### voter vote The `votes` endpoint allows users to query a vote for a given proposal. -Using legacy v1beta1: - -```bash -/cosmos/gov/v1beta1/proposals/{proposal_id}/votes/{voter} -``` - -Example: - -```bash -curl localhost:1317/cosmos/gov/v1beta1/proposals/1/votes/cosmos1.. -``` - -Example Output: - -```bash -{ - "vote": { - "proposal_id": "1", - "voter": "cosmos1..", - "option": "VOTE_OPTION_YES", - "options": [ - { - "option": "VOTE_OPTION_YES", - "weight": "1.000000000000000000" - } - ] - } -} -``` - -Using v1: ```bash /cosmos/gov/v1/proposals/{proposal_id}/votes/{voter} @@ -2106,66 +1224,10 @@ Example: curl localhost:1317/cosmos/gov/v1/proposals/1/votes/cosmos1.. ``` -Example Output: - -```bash -{ - "vote": { - "proposal_id": "1", - "voter": "cosmos1..", - "options": [ - { - "option": "VOTE_OPTION_YES", - "weight": "1.000000000000000000" - } - ], - "metadata": "" - } -} -``` - #### votes The `votes` endpoint allows users to query all votes for a given proposal. -Using legacy v1beta1: - -```bash -/cosmos/gov/v1beta1/proposals/{proposal_id}/votes -``` - -Example: - -```bash -curl localhost:1317/cosmos/gov/v1beta1/proposals/1/votes -``` - -Example Output: - -```bash -{ - "votes": [ - { - "proposal_id": "1", - "voter": "cosmos1..", - "option": "VOTE_OPTION_YES", - "options": [ - { - "option": "VOTE_OPTION_YES", - "weight": "1.000000000000000000" - } - ] - } - ], - "pagination": { - "next_key": null, - "total": "1" - } -} -``` - -Using v1: - ```bash /cosmos/gov/v1/proposals/{proposal_id}/votes ``` @@ -2176,58 +1238,10 @@ Example: curl localhost:1317/cosmos/gov/v1/proposals/1/votes ``` -Example Output: - -```bash -{ - "votes": [ - { - "proposal_id": "1", - "voter": "cosmos1..", - "options": [ - { - "option": "VOTE_OPTION_YES", - "weight": "1.000000000000000000" - } - ], - "metadata": "" - } - ], - "pagination": { - "next_key": null, - "total": "1" - } -} -``` - #### params The `params` endpoint allows users to query all parameters for the `gov` module. -Using legacy v1beta1: - -```bash -/cosmos/gov/v1beta1/params/{params_type} -``` - -Example: - -```bash -curl localhost:1317/cosmos/gov/v1beta1/params/voting -``` - -Example Output: - -```bash -{ - "voting_params": { - "voting_period": "172800s" - }, -} -``` - -Using v1: - ```bash /cosmos/gov/v1/params/{params_type} ``` @@ -2238,63 +1252,12 @@ Example: curl localhost:1317/cosmos/gov/v1/params/voting ``` -Example Output: - -```bash -{ - "voting_params": { - "voting_period": "172800s" - }, - "deposit_params": { - "min_deposit": [ - ], - "max_deposit_period": "0s" - }, - "tally_params": { - "quorum": "0.000000000000000000", - "threshold": "0.000000000000000000", - "veto_threshold": "0.000000000000000000" - } -} -``` - Note: `params_type` are deprecated in v1 since all params are stored in Params. #### deposits The `deposits` endpoint allows users to query a deposit for a given proposal from a given depositor. -Using legacy v1beta1: - -```bash -/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits/{depositor} -``` - -Example: - -```bash -curl localhost:1317/cosmos/gov/v1beta1/proposals/1/deposits/cosmos1.. -``` - -Example Output: - -```bash -{ - "deposit": { - "proposal_id": "1", - "depositor": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10000000" - } - ] - } -} -``` - -Using v1: - ```bash /cosmos/gov/v1/proposals/{proposal_id}/deposits/{depositor} ``` @@ -2305,64 +1268,10 @@ Example: curl localhost:1317/cosmos/gov/v1/proposals/1/deposits/cosmos1.. ``` -Example Output: - -```bash -{ - "deposit": { - "proposal_id": "1", - "depositor": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10000000" - } - ] - } -} -``` - #### proposal deposits The `deposits` endpoint allows users to query all deposits for a given proposal. -Using legacy v1beta1: - -```bash -/cosmos/gov/v1beta1/proposals/{proposal_id}/deposits -``` - -Example: - -```bash -curl localhost:1317/cosmos/gov/v1beta1/proposals/1/deposits -``` - -Example Output: - -```bash -{ - "deposits": [ - { - "proposal_id": "1", - "depositor": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10000000" - } - ] - } - ], - "pagination": { - "next_key": null, - "total": "1" - } -} -``` - -Using v1: - ```bash /cosmos/gov/v1/proposals/{proposal_id}/deposits ``` @@ -2373,60 +1282,10 @@ Example: curl localhost:1317/cosmos/gov/v1/proposals/1/deposits ``` -Example Output: - -```bash -{ - "deposits": [ - { - "proposal_id": "1", - "depositor": "cosmos1..", - "amount": [ - { - "denom": "stake", - "amount": "10000000" - } - ] - } - ], - "pagination": { - "next_key": null, - "total": "1" - } -} -``` - #### tally The `tally` endpoint allows users to query the tally of a given proposal. -Using legacy v1beta1: - -```bash -/cosmos/gov/v1beta1/proposals/{proposal_id}/tally -``` - -Example: - -```bash -curl localhost:1317/cosmos/gov/v1beta1/proposals/1/tally -``` - -Example Output: - -```bash -{ - "tally": { - "yes": "1000000", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - } -} -``` - -Using v1: - ```bash /cosmos/gov/v1/proposals/{proposal_id}/tally ``` @@ -2436,50 +1295,3 @@ Example: ```bash curl localhost:1317/cosmos/gov/v1/proposals/1/tally ``` - -Example Output: - -```bash -{ - "tally": { - "yes": "1000000", - "abstain": "0", - "no": "0", - "no_with_veto": "0" - } -} -``` - -## Metadata - -The gov module has two locations for metadata where users can provide further context about the on-chain actions they are taking. By default all metadata fields have a 255 character length field where metadata can be stored in json format, either on-chain or off-chain depending on the amount of data required. Here we provide a recommendation for the json structure and where the data should be stored. There are two important factors in making these recommendations. First, that the gov and group modules are consistent with one another, note the number of proposals made by all groups may be quite large. Second, that client applications such as block explorers and governance interfaces have confidence in the consistency of metadata structure across chains. - -### Proposal - -Location: off-chain as json object stored on IPFS (mirrors [group proposal](../group/README.md#metadata)) - -```json -{ - "title": "", - "authors": [""], - "summary": "", - "details": "", - "proposal_forum_url": "", - "vote_option_context": "", -} -``` - -:::note -The `authors` field is an array of strings, this is to allow for multiple authors to be listed in the metadata. -In v0.46, the `authors` field is a comma-separated string. Frontends are encouraged to support both formats for backwards compatibility. -::: - -### Vote - -Location: on-chain as json within 255 character limit (mirrors [group vote](../group/README.md#metadata)) - -```json -{ - "justification": "", -} -``` diff --git a/x/gov/go.mod b/x/gov/go.mod index 80af69cf1281..f86ae5dcf8c6 100644 --- a/x/gov/go.mod +++ b/x/gov/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -28,14 +28,14 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/tx v0.13.3 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -127,7 +127,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -162,7 +162,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/x/gov/go.sum b/x/gov/go.sum index 25e66089f97e..46e0295dc4b6 100644 --- a/x/gov/go.sum +++ b/x/gov/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -420,8 +420,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -648,8 +648,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -660,8 +660,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/gov/keeper/abci.go b/x/gov/keeper/abci.go index c0e4120528ab..0ea2860b47a7 100644 --- a/x/gov/keeper/abci.go +++ b/x/gov/keeper/abci.go @@ -20,7 +20,8 @@ import ( // EndBlocker is called every block. func (k Keeper) EndBlocker(ctx context.Context) error { - defer telemetry.ModuleMeasureSince(types.ModuleName, telemetry.Now(), telemetry.MetricKeyEndBlocker) + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyEndBlocker) // delete dead proposals from store and returns theirs deposits. // A proposal is dead when it's inactive and didn't get enough deposit on time to get into voting phase. diff --git a/x/group/go.mod b/x/group/go.mod index 2740cb7f9c0b..6f83519f4085 100644 --- a/x/group/go.mod +++ b/x/group/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -29,7 +29,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 pgregory.net/rapid v1.1.0 ) @@ -38,11 +38,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/collections v0.4.0 // indirect - cosmossdk.io/schema v0.3.0 // indirect - cosmossdk.io/x/accounts/defaults/base v0.0.0-00010101000000-000000000000 // indirect - cosmossdk.io/x/accounts/defaults/lockup v0.0.0-20240417181816-5e7aae0db1f5 // indirect - cosmossdk.io/x/accounts/defaults/multisig v0.0.0-00010101000000-000000000000 // indirect - cosmossdk.io/x/distribution v0.0.0-00010101000000-000000000000 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/epochs v0.0.0-20240522060652-a1ae4c3e0337 // indirect cosmossdk.io/x/tx v0.13.3 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -137,7 +133,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -173,7 +169,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/x/group/go.sum b/x/group/go.sum index 12dc9d6cd335..dbc625fc5f52 100644 --- a/x/group/go.sum +++ b/x/group/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -422,8 +422,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -650,8 +650,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -662,8 +662,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/group/keeper/abci.go b/x/group/keeper/abci.go index 563490cbe856..c8d980375496 100644 --- a/x/group/keeper/abci.go +++ b/x/group/keeper/abci.go @@ -2,11 +2,18 @@ package keeper import ( "context" + + "cosmossdk.io/x/group" + + "github.com/cosmos/cosmos-sdk/telemetry" ) // EndBlocker called at every block, updates proposal's `FinalTallyResult` and // prunes expired proposals. func (k Keeper) EndBlocker(ctx context.Context) error { + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(group.ModuleName, start, telemetry.MetricKeyEndBlocker) + if err := k.TallyProposalsAtVPEnd(ctx); err != nil { return err } diff --git a/x/mint/go.mod b/x/mint/go.mod index 444f1ee93640..b0343d16ef05 100644 --- a/x/mint/go.mod +++ b/x/mint/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -22,14 +22,14 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 gotest.tools/v3 v3.5.1 // indirect ) require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect @@ -119,7 +119,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -156,7 +156,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/x/mint/go.sum b/x/mint/go.sum index 747470c22d80..c9df997e10ec 100644 --- a/x/mint/go.sum +++ b/x/mint/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -414,8 +414,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -640,8 +640,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -652,8 +652,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/mint/keeper/abci.go b/x/mint/keeper/abci.go index 85b7d3155978..b828d8b7474f 100644 --- a/x/mint/keeper/abci.go +++ b/x/mint/keeper/abci.go @@ -10,7 +10,8 @@ import ( // BeginBlocker mints new tokens for the previous block. func (k Keeper) BeginBlocker(ctx context.Context) error { - defer telemetry.ModuleMeasureSince(types.ModuleName, telemetry.Now(), telemetry.MetricKeyBeginBlocker) + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyBeginBlocker) // fetch stored minter & params minter, err := k.Minter.Get(ctx) diff --git a/x/nft/README.md b/x/nft/README.md index 34c1d40660b9..3bf1b6b41b44 100644 --- a/x/nft/README.md +++ b/x/nft/README.md @@ -22,6 +22,8 @@ sidebar_position: 1 * [Messages](#messages) * [MsgSend](#msgsend) * [Events](#events) +* [Queries](#queries) +* [Keeper Functions](#keeper-functions) ## Concepts @@ -86,4 +88,30 @@ The message handling should fail if: ## Events -The nft module emits proto events defined in [the Protobuf reference](https://buf.build/cosmos/cosmos-sdk/docs/main:cosmos.nft.v1beta1). +The NFT module emits proto events defined in [the Protobuf reference](https://buf.build/cosmos/cosmos-sdk/docs/main:cosmos.nft.v1beta1). + +## Queries + +The `x/nft` module provides several queries to retrieve information about NFTs and classes: + +* `Balance`: Returns the number of NFTs of a given class owned by the owner. +* `Owner`: Returns the owner of an NFT based on its class and ID. +* `Supply`: Returns the number of NFTs from the given class. +* `NFTs`: Queries all NFTs of a given class or owner. +* `NFT`: Returns an NFT based on its class and ID. +* `Class`: Returns an NFT class based on its ID. +* `Classes`: Returns all NFT classes. + +## Keeper Functions + +The Keeper of the `x/nft` module provides several functions to manage NFTs: + +* `Mint`: Mints a new NFT. +* `Burn`: Burns an existing NFT. +* `Update`: Updates an existing NFT. +* `Transfer`: Transfers an NFT from one owner to another. +* `GetNFT`: Retrieves information about a specific NFT. +* `GetNFTsOfClass`: Retrieves all NFTs of a specific class. +* `GetNFTsOfClassByOwner`: Retrieves all NFTs of a specific class belonging to an owner. +* `GetBalance`: Retrieves the balance of NFTs of a specific class for an owner. +* `GetTotalSupply`: Retrieves the total supply of NFTs of a specific class. diff --git a/x/nft/go.mod b/x/nft/go.mod index 2e1f662b59a3..baca50bed955 100644 --- a/x/nft/go.mod +++ b/x/nft/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.4.1 @@ -18,7 +18,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 ) require ( @@ -26,7 +26,7 @@ require ( buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect @@ -121,7 +121,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -158,7 +158,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/x/nft/go.sum b/x/nft/go.sum index 747470c22d80..c9df997e10ec 100644 --- a/x/nft/go.sum +++ b/x/nft/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -414,8 +414,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -640,8 +640,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -652,8 +652,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/params/go.mod b/x/params/go.mod index 6ceb76cd56ea..f072f3b0256b 100644 --- a/x/params/go.mod +++ b/x/params/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -22,14 +22,14 @@ require ( github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 ) require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/collections v0.4.0 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/tx v0.13.3 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -115,7 +115,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -150,7 +150,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/x/params/go.sum b/x/params/go.sum index 8e04ce6df3e9..048c9a1067ea 100644 --- a/x/params/go.sum +++ b/x/params/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -390,8 +390,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -613,8 +613,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -625,8 +625,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/protocolpool/go.mod b/x/protocolpool/go.mod index 8cb08057781c..5454bc67d0dd 100644 --- a/x/protocolpool/go.mod +++ b/x/protocolpool/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -19,7 +19,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -27,7 +27,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/log v1.4.1 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect @@ -122,7 +122,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -159,7 +159,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/x/protocolpool/go.sum b/x/protocolpool/go.sum index 747470c22d80..c9df997e10ec 100644 --- a/x/protocolpool/go.sum +++ b/x/protocolpool/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -414,8 +414,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -640,8 +640,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -652,8 +652,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/protocolpool/keeper/keeper.go b/x/protocolpool/keeper/keeper.go index f0d6cff755a7..8017714a6a84 100644 --- a/x/protocolpool/keeper/keeper.go +++ b/x/protocolpool/keeper/keeper.go @@ -14,6 +14,7 @@ import ( "cosmossdk.io/x/protocolpool/types" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -507,5 +508,8 @@ func (k Keeper) validateContinuousFund(ctx context.Context, msg types.MsgCreateC } func (k Keeper) BeginBlocker(ctx context.Context) error { + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyBeginBlocker) + return k.SetToDistribute(ctx) } diff --git a/x/simulation/mock_cometbft.go b/x/simulation/mock_cometbft.go index c9572dd46924..691494c64fe7 100644 --- a/x/simulation/mock_cometbft.go +++ b/x/simulation/mock_cometbft.go @@ -151,10 +151,13 @@ func RandomRequestFinalizeBlock( signed = false } + var commitStatus cmtproto.BlockIDFlag if signed { event("begin_block", "signing", "signed") + commitStatus = cmtproto.BlockIDFlagCommit } else { event("begin_block", "signing", "missed") + commitStatus = cmtproto.BlockIDFlagAbsent } voteInfos[i] = abci.VoteInfo{ @@ -162,7 +165,7 @@ func RandomRequestFinalizeBlock( Address: SumTruncated(mVal.val.PubKeyBytes), Power: mVal.val.Power, }, - BlockIdFlag: cmtproto.BlockIDFlagCommit, + BlockIdFlag: commitStatus, } } diff --git a/x/slashing/abci.go b/x/slashing/abci.go index e99b6acea574..00318f1f5637 100644 --- a/x/slashing/abci.go +++ b/x/slashing/abci.go @@ -13,7 +13,8 @@ import ( // BeginBlocker check for infraction evidence or downtime of validators // on every begin block func BeginBlocker(ctx context.Context, k keeper.Keeper, cometService comet.Service) error { - defer telemetry.ModuleMeasureSince(types.ModuleName, telemetry.Now(), telemetry.MetricKeyBeginBlocker) + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyBeginBlocker) // Retrieve CometBFT info, then iterate through all validator votes // from the last commit. For each vote, handle the validator's signature, potentially diff --git a/x/slashing/go.mod b/x/slashing/go.mod index 057192775e17..c207b1c5317b 100644 --- a/x/slashing/go.mod +++ b/x/slashing/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -21,7 +21,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 gotest.tools/v3 v3.5.1 ) @@ -30,7 +30,7 @@ require ( buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.34.2-20240701160653-fedbb9acfd2f.2 // indirect buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2 // indirect cosmossdk.io/log v1.4.1 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/tx v0.13.3 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -124,7 +124,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -161,7 +161,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect pgregory.net/rapid v1.1.0 // indirect diff --git a/x/slashing/go.sum b/x/slashing/go.sum index 9090a0b868ad..9600563cd537 100644 --- a/x/slashing/go.sum +++ b/x/slashing/go.sum @@ -6,8 +6,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -18,8 +18,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -416,8 +416,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -642,8 +642,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -654,8 +654,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/staking/CHANGELOG.md b/x/staking/CHANGELOG.md index b185542abed4..24843a45f121 100644 --- a/x/staking/CHANGELOG.md +++ b/x/staking/CHANGELOG.md @@ -34,6 +34,9 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#19537](https://github.com/cosmos/cosmos-sdk/pull/19537) Changing `MinCommissionRate` in `MsgUpdateParams` now updates the minimum commission rate for all validators. * [#20434](https://github.com/cosmos/cosmos-sdk/pull/20434) Add consensus address to validator query response +* [#21315](https://github.com/cosmos/cosmos-sdk/pull/21315) Create metadata type and add metadata field in validator details proto + * Add parsing of `metadata-profile-pic-uri` in `create-validator` JSON. + * Add cli flag: `metadata-profile-pic-uri` to `edit-validator` cmd. ### Improvements @@ -42,6 +45,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#19277](https://github.com/cosmos/cosmos-sdk/pull/19277) Hooks calls on `SetUnbondingDelegationEntry`, `SetRedelegationEntry`, `Slash` and `RemoveValidator` returns errors instead of logging just like other hooks calls. * [#18636](https://github.com/cosmos/cosmos-sdk/pull/18636) `IterateBondedValidatorsByPower`, `GetDelegatorBonded`, `Delegate`, `Unbond`, `Slash`, `Jail`, `SlashRedelegation`, `ApplyAndReturnValidatorSetUpdates` methods no longer panics on any kind of errors but instead returns appropriate errors. * [#18506](https://github.com/cosmos/cosmos-sdk/pull/18506) Detect the length of the ed25519 pubkey in CreateValidator to prevent panic. +* [#21315](https://github.com/cosmos/cosmos-sdk/pull/21315) Add a `Validate` method to the `Description` type that validates the metadata as well as other description details. ### API Breaking Changes @@ -96,8 +100,11 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#17335](https://github.com/cosmos/cosmos-sdk/pull/17335) Remove usage of `"cosmossdk.io/x/staking/types".Infraction_*` in favour of `"cosmossdk.io/api/cosmos/staking/v1beta1".Infraction_` in order to remove dependency between modules on staking * [#20295](https://github.com/cosmos/cosmos-sdk/pull/20295) `GetValidatorByConsAddr` now returns the Cosmos SDK `cryptotypes.Pubkey` instead of `cometcrypto.Publickey`. The caller is responsible to translate the returned value to the expected type. * Remove `CmtConsPublicKey()` and `TmConsPublicKey()` from `Validator` interface and as methods on the `Validator` struct. -* [#21480](https://github.com/cosmos/cosmos-sdk/pull/21480) ConsensusKeeper is required to be passed to the keeper. - +* [#21480](https://github.com/cosmos/cosmos-sdk/pull/21480) ConsensusKeeper is required to be passed to the keeper. +* [#21315](https://github.com/cosmos/cosmos-sdk/pull/21315) New struct `Metadata` to store extra validator information. + * New field `Metadata` introduced in `types`: `Description`. + * The signature of `NewDescription` has changed to accept an extra argument of type `Metadata`. + ### State Breaking changes * [#18841](https://github.com/cosmos/cosmos-sdk/pull/18841) In a undelegation or redelegation if the shares being left delegated correspond to less than 1 token (in base denom) the entire delegation gets removed. diff --git a/x/staking/client/cli/flags.go b/x/staking/client/cli/flags.go index 61643a04865f..45f3a65e8f38 100644 --- a/x/staking/client/cli/flags.go +++ b/x/staking/client/cli/flags.go @@ -15,12 +15,14 @@ const ( FlagSharesAmount = "shares-amount" FlagSharesFraction = "shares-fraction" - FlagMoniker = "moniker" - FlagEditMoniker = "new-moniker" - FlagIdentity = "identity" - FlagWebsite = "website" - FlagSecurityContact = "security-contact" - FlagDetails = "details" + FlagMoniker = "moniker" + FlagEditMoniker = "new-moniker" + FlagIdentity = "identity" + FlagWebsite = "website" + FlagSecurityContact = "security-contact" + FlagDetails = "details" + FlagMetadataProfilePicUri = "metadata-profile-pic-uri" + FlagMetadataSocialHandleUris = "metadata-social-handle-uris" FlagCommissionRate = "commission-rate" FlagCommissionMaxRate = "commission-max-rate" @@ -89,6 +91,8 @@ func flagSetDescriptionEdit() *flag.FlagSet { fs.String(FlagWebsite, types.DoNotModifyDesc, "The validator's (optional) website") fs.String(FlagSecurityContact, types.DoNotModifyDesc, "The validator's (optional) security contact email") fs.String(FlagDetails, types.DoNotModifyDesc, "The validator's (optional) details") + fs.String(FlagMetadataProfilePicUri, "", "The validator's profile pic uri") + fs.StringArray(FlagMetadataSocialHandleUris, []string{}, "The validator's social handles uris") return fs } diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 3e80b30a047b..0e1ba1c396dd 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -72,6 +72,7 @@ Where validator.json contains: "website": "validator's (optional) website", "security": "validator's (optional) security contact email", "details": "validator's (optional) details", + "metadata-profile-pic-uri": "link to validator's (optional) profile picture", "commission-rate": "0.1", "commission-max-rate": "0.2", "commission-max-change-rate": "0.01", @@ -129,7 +130,15 @@ func NewEditValidatorCmd() *cobra.Command { website, _ := cmd.Flags().GetString(FlagWebsite) security, _ := cmd.Flags().GetString(FlagSecurityContact) details, _ := cmd.Flags().GetString(FlagDetails) - description := types.NewDescription(moniker, identity, website, security, details) + profilePicUri, _ := cmd.Flags().GetString(FlagMetadataProfilePicUri) + socialHandlesUris, _ := cmd.Flags().GetStringArray(FlagMetadataSocialHandleUris) + + metadata := types.Metadata{ + ProfilePicUri: profilePicUri, + SocialHandleUris: socialHandlesUris, + } + + description := types.NewDescription(moniker, identity, website, security, details, metadata) var newRate *math.LegacyDec @@ -183,6 +192,7 @@ func newBuildCreateValidatorMsg(clientCtx client.Context, txf tx.Factory, fs *fl val.Website, val.Security, val.Details, + val.Metadata, ) valStr, err := valAc.BytesToString(sdk.ValAddress(valAddr)) @@ -225,6 +235,8 @@ func CreateValidatorMsgFlagSet(ipDefault string) (fs *flag.FlagSet, defaultsDesc fsCreateValidator.String(FlagSecurityContact, "", "The validator's (optional) security contact email") fsCreateValidator.String(FlagDetails, "", "The validator's (optional) details") fsCreateValidator.String(FlagIdentity, "", "The (optional) identity signature (ex. UPort or Keybase)") + fsCreateValidator.String(FlagMetadataProfilePicUri, "", "The validator's profile pic uri") + fsCreateValidator.StringArray(FlagMetadataSocialHandleUris, []string{}, "The validator's social handles uris") fsCreateValidator.AddFlagSet(FlagSetCommissionCreate()) fsCreateValidator.AddFlagSet(FlagSetMinSelfDelegation()) fsCreateValidator.AddFlagSet(FlagSetAmount()) @@ -263,6 +275,7 @@ type TxCreateValidatorConfig struct { SecurityContact string Details string Identity string + Metadata types.Metadata } func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, chainID string, valPubKey cryptotypes.PubKey) (TxCreateValidatorConfig, error) { @@ -302,6 +315,14 @@ func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, c return c, err } + profilePicUri, err := flagSet.GetString(FlagMetadataProfilePicUri) + if err != nil { + return c, err + } + metadata := types.Metadata{ + ProfilePicUri: profilePicUri, + } + c.Amount, err = flagSet.GetString(FlagAmount) if err != nil { return c, err @@ -338,6 +359,7 @@ func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, c c.SecurityContact = securityContact c.Details = details c.Identity = identity + c.Metadata = metadata c.ChainID = chainID c.Moniker = moniker @@ -379,6 +401,7 @@ func BuildCreateValidatorMsg(clientCtx client.Context, config TxCreateValidatorC config.Website, config.SecurityContact, config.Details, + config.Metadata, ) // get the initial validator commission parameters diff --git a/x/staking/client/cli/utils.go b/x/staking/client/cli/utils.go index ff22b8876fc4..fc4ed032efc4 100644 --- a/x/staking/client/cli/utils.go +++ b/x/staking/client/cli/utils.go @@ -24,23 +24,26 @@ type validator struct { Website string Security string Details string + Metadata types.Metadata CommissionRates types.CommissionRates MinSelfDelegation math.Int } func parseAndValidateValidatorJSON(cdc codec.Codec, path string) (validator, error) { type internalVal struct { - Amount string `json:"amount"` - PubKey json.RawMessage `json:"pubkey"` - Moniker string `json:"moniker"` - Identity string `json:"identity,omitempty"` - Website string `json:"website,omitempty"` - Security string `json:"security,omitempty"` - Details string `json:"details,omitempty"` - CommissionRate string `json:"commission-rate"` - CommissionMaxRate string `json:"commission-max-rate"` - CommissionMaxChange string `json:"commission-max-change-rate"` - MinSelfDelegation string `json:"min-self-delegation"` + Amount string `json:"amount"` + PubKey json.RawMessage `json:"pubkey"` + Moniker string `json:"moniker"` + Identity string `json:"identity,omitempty"` + Website string `json:"website,omitempty"` + Security string `json:"security,omitempty"` + Details string `json:"details,omitempty"` + MetadataProfilePicUri string `json:"metadata-profile-pic-uri,omitempty"` + MetadataSocialHandlesUris []string `json:"metadata-social-handles-uris,omitempty"` + CommissionRate string `json:"commission-rate"` + CommissionMaxRate string `json:"commission-max-rate"` + CommissionMaxChange string `json:"commission-max-change-rate"` + MinSelfDelegation string `json:"min-self-delegation"` } contents, err := os.ReadFile(path) @@ -87,6 +90,11 @@ func parseAndValidateValidatorJSON(cdc codec.Codec, path string) (validator, err return validator{}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "minimum self delegation must be a positive integer") } + metadata, err := buildMetadata(v.MetadataProfilePicUri, v.MetadataSocialHandlesUris) + if err != nil { + return validator{}, err + } + return validator{ Amount: amount, PubKey: pk, @@ -95,6 +103,7 @@ func parseAndValidateValidatorJSON(cdc codec.Codec, path string) (validator, err Website: v.Website, Security: v.Security, Details: v.Details, + Metadata: metadata, CommissionRates: commissionRates, MinSelfDelegation: minSelfDelegation, }, nil @@ -124,3 +133,12 @@ func buildCommissionRates(rateStr, maxRateStr, maxChangeRateStr string) (commiss return commission, nil } + +func buildMetadata(profilePicUri string, socialHandlesUris []string) (metadata types.Metadata, err error) { + metadata.ProfilePicUri = profilePicUri + metadata.SocialHandleUris = socialHandlesUris + if err := metadata.Validate(); err != nil { + return metadata, err + } + return metadata, nil +} diff --git a/x/staking/go.mod b/x/staking/go.mod index ae13425ebaa8..9c4cdacb1257 100644 --- a/x/staking/go.mod +++ b/x/staking/go.mod @@ -5,7 +5,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 cosmossdk.io/collections v0.4.0 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -19,12 +19,12 @@ require ( github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/hashicorp/go-metrics v0.5.3 + github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -111,7 +111,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -143,7 +143,7 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect pgregory.net/rapid v1.1.0 // indirect @@ -163,7 +163,7 @@ require ( ) require ( - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cosmos/cosmos-db v1.0.3-0.20240911104526-ddc3f09bfc22 // indirect github.com/google/uuid v1.6.0 // indirect diff --git a/x/staking/go.sum b/x/staking/go.sum index 934d22e1cbe7..7588b565a0d7 100644 --- a/x/staking/go.sum +++ b/x/staking/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88e buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.34.2-20240130113600-88ef6483f90f.2/go.mod h1:HqcXMSa5qnNuakaMUo+hWhF51mKbcrZxGl9Vp5EeJXc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -16,8 +16,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= @@ -412,8 +412,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -638,8 +638,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -650,8 +650,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x/staking/keeper/abci.go b/x/staking/keeper/abci.go index dc14285ccf68..79bfbf5595f6 100644 --- a/x/staking/keeper/abci.go +++ b/x/staking/keeper/abci.go @@ -13,5 +13,6 @@ import ( func (k *Keeper) EndBlocker(ctx context.Context) ([]appmodule.ValidatorUpdate, error) { start := telemetry.Now() defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyEndBlocker) + return k.BlockValidatorUpdates(ctx) } diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index 92561bc6e7f3..24e0f1bd7437 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -481,7 +481,7 @@ func (s *KeeperTestSuite) TestValidatorsMigrationToColls() { // legacy Set method s.ctx.KVStore(s.key).Set(getValidatorKey(valAddrs[i]), valBz) }, - "d8acdcf8b7c8e17f3e83f0a4c293f89ad619a5dcb14d232911ccc5da15653177", + "55565aebbb67e1de08d0f17634ad168c68eae74f5cc9074e3a1ec4d1fbff16e5", ) s.Require().NoError(err) @@ -507,7 +507,7 @@ func (s *KeeperTestSuite) TestValidatorsMigrationToColls() { err := s.stakingKeeper.SetValidator(s.ctx, val) s.Require().NoError(err) }, - "d8acdcf8b7c8e17f3e83f0a4c293f89ad619a5dcb14d232911ccc5da15653177", + "55565aebbb67e1de08d0f17634ad168c68eae74f5cc9074e3a1ec4d1fbff16e5", ) s.Require().NoError(err) } diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index fa7cd6a6c0bf..272932c494fb 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -9,7 +9,6 @@ import ( "strconv" "time" - "github.com/hashicorp/go-metrics" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -21,7 +20,6 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -111,7 +109,7 @@ func (k msgServer) CreateValidator(ctx context.Context, msg *types.MsgCreateVali ) } - if _, err := msg.Description.EnsureLength(); err != nil { + if _, err := msg.Description.Validate(); err != nil { return nil, err } @@ -178,7 +176,7 @@ func (k msgServer) EditValidator(ctx context.Context, msg *types.MsgEditValidato return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid validator address: %s", err) } - if msg.Description == (types.Description{}) { + if msg.Description.IsEmpty() { return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "empty description") } @@ -301,17 +299,6 @@ func (k msgServer) Delegate(ctx context.Context, msg *types.MsgDelegate) (*types return nil, err } - if msg.Amount.Amount.IsInt64() { - defer func() { - telemetry.IncrCounter(1, types.ModuleName, "delegate") - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", sdk.MsgTypeURL(msg)}, - float32(msg.Amount.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", msg.Amount.Denom)}, - ) - }() - } - if err := k.EventService.EventManager(ctx).EmitKV( types.EventTypeDelegate, event.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress), @@ -374,17 +361,6 @@ func (k msgServer) BeginRedelegate(ctx context.Context, msg *types.MsgBeginRedel return nil, err } - if msg.Amount.Amount.IsInt64() { - defer func() { - telemetry.IncrCounter(1, types.ModuleName, "redelegate") - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", sdk.MsgTypeURL(msg)}, - float32(msg.Amount.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", msg.Amount.Denom)}, - ) - }() - } - if err := k.EventService.EventManager(ctx).EmitKV( types.EventTypeRedelegate, event.NewAttribute(types.AttributeKeySrcValidator, msg.ValidatorSrcAddress), @@ -444,17 +420,6 @@ func (k msgServer) Undelegate(ctx context.Context, msg *types.MsgUndelegate) (*t undelegatedCoin := sdk.NewCoin(msg.Amount.Denom, undelegatedAmt) - if msg.Amount.Amount.IsInt64() { - defer func() { - telemetry.IncrCounter(1, types.ModuleName, "undelegate") - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", sdk.MsgTypeURL(msg)}, - float32(msg.Amount.Amount.Int64()), - []metrics.Label{telemetry.NewLabel("denom", msg.Amount.Denom)}, - ) - }() - } - if err := k.EventService.EventManager(ctx).EmitKV( types.EventTypeUnbond, event.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress), diff --git a/x/staking/proto/buf.lock b/x/staking/proto/buf.lock index 3a2b87c1a666..3ad9de72f05b 100644 --- a/x/staking/proto/buf.lock +++ b/x/staking/proto/buf.lock @@ -11,6 +11,11 @@ deps: repository: cosmos-proto commit: 04467658e59e44bbb22fe568206e1f70 digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466 + - remote: buf.build + owner: cosmos + repository: cosmos-sdk + commit: 05419252bcc241ea8023acf1ed4cadc5 + digest: shake256:1e54a48c19a8b59d35e0a7efa76402939f515f2d8005df099856f24c37c20a52800308f025abb8cffcd014d437b49707388aaca4865d9d063d8f25d5d4eb77d5 - remote: buf.build owner: cosmos repository: gogo-proto @@ -19,5 +24,15 @@ deps: - remote: buf.build owner: googleapis repository: googleapis - commit: 7e6f6e774e29406da95bd61cdcdbc8bc - digest: shake256:fe43dd2265ea0c07d76bd925eeba612667cf4c948d2ce53d6e367e1b4b3cb5fa69a51e6acb1a6a50d32f894f054a35e6c0406f6808a483f2752e10c866ffbf73 + commit: 8bc2c51e08c447cd8886cdea48a73e14 + digest: shake256:a969155953a5cedc5b2df5b42c368f2bc66ff8ce1804bc96e0f14ff2ee8a893687963058909df844d1643cdbc98ff099d2daa6bc9f9f5b8886c49afdc60e19af + - remote: buf.build + owner: protocolbuffers + repository: wellknowntypes + commit: 657250e6a39648cbb169d079a60bd9ba + digest: shake256:00de25001b8dd2e29d85fc4bcc3ede7aed886d76d67f5e0f7a9b320b90f871d3eb73507d50818d823a0512f3f8db77a11c043685528403e31ff3fef18323a9fb + - remote: buf.build + owner: tendermint + repository: tendermint + commit: 33ed361a90514289beabf3189e1d7665 + digest: shake256:038267e06294714fd883610626554b04a127b576b4e253befb4206cb72d5d3c1eeccacd4b9ec8e3fb891f7c14e1cb0f770c077d2989638995b0a61c85afedb1d diff --git a/x/staking/proto/cosmos/staking/v1beta1/staking.proto b/x/staking/proto/cosmos/staking/v1beta1/staking.proto index 8b8709322305..b6dd5fcbff78 100644 --- a/x/staking/proto/cosmos/staking/v1beta1/staking.proto +++ b/x/staking/proto/cosmos/staking/v1beta1/staking.proto @@ -1,17 +1,16 @@ syntax = "proto3"; package cosmos.staking.v1beta1; +import "amino/amino.proto"; +import "cometbft/abci/v1/types.proto"; +import "cometbft/types/v1/types.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "amino/amino.proto"; -import "cometbft/types/v1/types.proto"; -import "cometbft/abci/v1/types.proto"; - option go_package = "cosmossdk.io/x/staking/types"; // HistoricalInfo contains header and validator information for a given block. @@ -79,6 +78,19 @@ message Description { string security_contact = 4; // details define other optional details. string details = 5; + // metadata defines extra information about the validator. + Metadata metadata = 6 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; +} + +// Metadata defines extra information about the validator. +message Metadata { + option (gogoproto.equal) = true; + + // profile_pic_uri defines a link to the validator profile picture. + string profile_pic_uri = 1; + + // social_handle_uris defines a string array of uris to the validator's social handles. + repeated string social_handle_uris = 2; } // Validator defines a validator, together with the total amount of the @@ -221,7 +233,8 @@ message UnbondingDelegation { string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.ValidatorAddressString"]; // entries are the unbonding delegation entries. repeated UnbondingDelegationEntry entries = 3 - [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // unbonding delegation entries + [(gogoproto.nullable) = false, + (amino.dont_omitempty) = true]; // unbonding delegation entries } // UnbondingDelegationEntry defines an unbonding object with relevant metadata. @@ -294,7 +307,8 @@ message Redelegation { string validator_dst_address = 3 [(cosmos_proto.scalar) = "cosmos.ValidatorAddressString"]; // entries are the redelegation entries. repeated RedelegationEntry entries = 4 - [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // redelegation entries + [(gogoproto.nullable) = false, + (amino.dont_omitempty) = true]; // redelegation entries } // Params defines the parameters for the x/staking module. diff --git a/x/staking/simulation/msg_factory.go b/x/staking/simulation/msg_factory.go index 31c35cddd507..49aff2505298 100644 --- a/x/staking/simulation/msg_factory.go +++ b/x/staking/simulation/msg_factory.go @@ -39,12 +39,17 @@ func MsgCreateValidatorFactory(k *keeper.Keeper) simsx.SimMsgFactoryFn[*types.Ms } selfDelegation := valOper.LiquidBalance().RandSubsetCoin(reporter, bondDenom) + description := types.NewDescription( r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), + types.Metadata{ + ProfilePicUri: RandURIOfHostLength(r.Rand, 10), + SocialHandleUris: RandSocialHandleURIs(r.Rand, 2, 10), + }, ) maxCommission := math.LegacyNewDecWithPrec(int64(r.IntInRange(0, 100)), 2) @@ -138,7 +143,10 @@ func MsgEditValidatorFactory(k *keeper.Keeper) simsx.SimMsgFactoryFn[*types.MsgE } valOpAddrBz := must(k.ValidatorAddressCodec().StringToBytes(val.GetOperator())) valOper := testData.GetAccountbyAccAddr(reporter, valOpAddrBz) - d := types.NewDescription(r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10)) + d := types.NewDescription(r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), types.Metadata{ + ProfilePicUri: RandURIOfHostLength(r.Rand, 10), + SocialHandleUris: RandSocialHandleURIs(r.Rand, 2, 10), + }) msg := types.NewMsgEditValidator(val.GetOperator(), d, &newCommissionRate, nil) return []simsx.SimAccount{valOper}, msg diff --git a/x/staking/simulation/rand_util.go b/x/staking/simulation/rand_util.go new file mode 100644 index 000000000000..c847a66f788f --- /dev/null +++ b/x/staking/simulation/rand_util.go @@ -0,0 +1,36 @@ +package simulation + +import ( + "fmt" + "math/rand" + "net/url" + + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" +) + +// RandURIOfHostLength returns a random valid uri with hostname length n. If n = 0, returns an empty string. +func RandURIOfHostLength(r *rand.Rand, n int) string { + if n == 0 { + return "" + } + tld := ".com" + hostLength := n - len(tld) + uri := &url.URL{ + Scheme: "https", + Host: fmt.Sprintf("%s%s", simtypes.RandStringOfLength(r, hostLength), tld), + } + + return uri.String() +} + +// RandSocialHandleURIs returns a string array of length num with uris. +func RandSocialHandleURIs(r *rand.Rand, num, uriHostLength int) []string { + if num == 0 { + return []string{} + } + var socialHandles []string + for i := 0; i < num; i++ { + socialHandles = append(socialHandles, RandURIOfHostLength(r, uriHostLength)) + } + return socialHandles +} diff --git a/x/staking/simulation/rand_util_test.go b/x/staking/simulation/rand_util_test.go new file mode 100644 index 000000000000..fb619e784eee --- /dev/null +++ b/x/staking/simulation/rand_util_test.go @@ -0,0 +1,60 @@ +package simulation_test + +import ( + "math/rand" + "net/url" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "cosmossdk.io/x/staking/simulation" +) + +func TestRandURIOfHostLength(t *testing.T) { + t.Parallel() + r := rand.New(rand.NewSource(time.Now().Unix())) + tests := []struct { + name string + n int + want int + }{ + {"0-size", 0, 0}, + {"10-size", 10, 10}, + {"1_000_000-size", 1_000_000, 1_000_000}, + } + for _, tt := range tests { + tc := tt + t.Run(tc.name, func(t *testing.T) { + got := 0 + uri := simulation.RandURIOfHostLength(r, tc.n) + if uri != "" { + parsedUri, err := url.Parse(uri) + require.NoError(t, err) + got = len(parsedUri.Host) + } + require.Equal(t, tc.want, got) + }) + } +} + +func TestRandSocialHandleURIs(t *testing.T) { + t.Parallel() + r := rand.New(rand.NewSource(time.Now().Unix())) + tests := []struct { + name string + n int + want int + }{ + {"0-handles", 0, 0}, + {"10-handles", 10, 10}, + {"100-handles", 100, 100}, + } + for _, tt := range tests { + tc := tt + t.Run(tc.name, func(t *testing.T) { + uris := simulation.RandSocialHandleURIs(r, tc.n, 10) + require.Equal(t, tc.want, len(uris)) + }) + } +} diff --git a/x/staking/types/msg.go b/x/staking/types/msg.go index b68818275ddf..879d3c821540 100644 --- a/x/staking/types/msg.go +++ b/x/staking/types/msg.go @@ -64,7 +64,7 @@ func (msg MsgCreateValidator) Validate(ac address.Codec) error { return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "invalid delegation amount") } - if msg.Description == (Description{}) { + if msg.Description.IsEmpty() { return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "empty description") } diff --git a/x/staking/types/staking.pb.go b/x/staking/types/staking.pb.go index d6511264f7c3..197e937a35d4 100644 --- a/x/staking/types/staking.pb.go +++ b/x/staking/types/staking.pb.go @@ -270,6 +270,8 @@ type Description struct { SecurityContact string `protobuf:"bytes,4,opt,name=security_contact,json=securityContact,proto3" json:"security_contact,omitempty"` // details define other optional details. Details string `protobuf:"bytes,5,opt,name=details,proto3" json:"details,omitempty"` + // metadata defines extra information about the validator. + Metadata Metadata `protobuf:"bytes,6,opt,name=metadata,proto3" json:"metadata"` } func (m *Description) Reset() { *m = Description{} } @@ -340,6 +342,68 @@ func (m *Description) GetDetails() string { return "" } +func (m *Description) GetMetadata() Metadata { + if m != nil { + return m.Metadata + } + return Metadata{} +} + +// Metadata defines extra information about the validator. +type Metadata struct { + // profile_pic_uri defines a link to the validator profile picture. + ProfilePicUri string `protobuf:"bytes,1,opt,name=profile_pic_uri,json=profilePicUri,proto3" json:"profile_pic_uri,omitempty"` + // social_handle_uris defines a string array of uris to the validator's social handles. + SocialHandleUris []string `protobuf:"bytes,2,rep,name=social_handle_uris,json=socialHandleUris,proto3" json:"social_handle_uris,omitempty"` +} + +func (m *Metadata) Reset() { *m = Metadata{} } +func (m *Metadata) String() string { return proto.CompactTextString(m) } +func (*Metadata) ProtoMessage() {} +func (*Metadata) Descriptor() ([]byte, []int) { + return fileDescriptor_64c30c6cf92913c9, []int{4} +} +func (m *Metadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Metadata.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Metadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metadata.Merge(m, src) +} +func (m *Metadata) XXX_Size() int { + return m.Size() +} +func (m *Metadata) XXX_DiscardUnknown() { + xxx_messageInfo_Metadata.DiscardUnknown(m) +} + +var xxx_messageInfo_Metadata proto.InternalMessageInfo + +func (m *Metadata) GetProfilePicUri() string { + if m != nil { + return m.ProfilePicUri + } + return "" +} + +func (m *Metadata) GetSocialHandleUris() []string { + if m != nil { + return m.SocialHandleUris + } + return nil +} + // Validator defines a validator, together with the total amount of the // Validator's bond shares and their exchange rate to coins. Slashing results in // a decrease in the exchange rate, allowing correct calculation of future @@ -381,7 +445,7 @@ func (m *Validator) Reset() { *m = Validator{} } func (m *Validator) String() string { return proto.CompactTextString(m) } func (*Validator) ProtoMessage() {} func (*Validator) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{4} + return fileDescriptor_64c30c6cf92913c9, []int{5} } func (m *Validator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -419,7 +483,7 @@ func (m *ValAddresses) Reset() { *m = ValAddresses{} } func (m *ValAddresses) String() string { return proto.CompactTextString(m) } func (*ValAddresses) ProtoMessage() {} func (*ValAddresses) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{5} + return fileDescriptor_64c30c6cf92913c9, []int{6} } func (m *ValAddresses) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -467,7 +531,7 @@ func (m *DVPair) Reset() { *m = DVPair{} } func (m *DVPair) String() string { return proto.CompactTextString(m) } func (*DVPair) ProtoMessage() {} func (*DVPair) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{6} + return fileDescriptor_64c30c6cf92913c9, []int{7} } func (m *DVPair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -505,7 +569,7 @@ func (m *DVPairs) Reset() { *m = DVPairs{} } func (m *DVPairs) String() string { return proto.CompactTextString(m) } func (*DVPairs) ProtoMessage() {} func (*DVPairs) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{7} + return fileDescriptor_64c30c6cf92913c9, []int{8} } func (m *DVPairs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -555,7 +619,7 @@ func (m *DVVTriplet) Reset() { *m = DVVTriplet{} } func (m *DVVTriplet) String() string { return proto.CompactTextString(m) } func (*DVVTriplet) ProtoMessage() {} func (*DVVTriplet) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{8} + return fileDescriptor_64c30c6cf92913c9, []int{9} } func (m *DVVTriplet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -593,7 +657,7 @@ func (m *DVVTriplets) Reset() { *m = DVVTriplets{} } func (m *DVVTriplets) String() string { return proto.CompactTextString(m) } func (*DVVTriplets) ProtoMessage() {} func (*DVVTriplets) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{9} + return fileDescriptor_64c30c6cf92913c9, []int{10} } func (m *DVVTriplets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -645,7 +709,7 @@ func (m *Delegation) Reset() { *m = Delegation{} } func (m *Delegation) String() string { return proto.CompactTextString(m) } func (*Delegation) ProtoMessage() {} func (*Delegation) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{10} + return fileDescriptor_64c30c6cf92913c9, []int{11} } func (m *Delegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -689,7 +753,7 @@ func (m *UnbondingDelegation) Reset() { *m = UnbondingDelegation{} } func (m *UnbondingDelegation) String() string { return proto.CompactTextString(m) } func (*UnbondingDelegation) ProtoMessage() {} func (*UnbondingDelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{11} + return fileDescriptor_64c30c6cf92913c9, []int{12} } func (m *UnbondingDelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -738,7 +802,7 @@ func (m *UnbondingDelegationEntry) Reset() { *m = UnbondingDelegationEnt func (m *UnbondingDelegationEntry) String() string { return proto.CompactTextString(m) } func (*UnbondingDelegationEntry) ProtoMessage() {} func (*UnbondingDelegationEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{12} + return fileDescriptor_64c30c6cf92913c9, []int{13} } func (m *UnbondingDelegationEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -815,7 +879,7 @@ func (m *RedelegationEntry) Reset() { *m = RedelegationEntry{} } func (m *RedelegationEntry) String() string { return proto.CompactTextString(m) } func (*RedelegationEntry) ProtoMessage() {} func (*RedelegationEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{13} + return fileDescriptor_64c30c6cf92913c9, []int{14} } func (m *RedelegationEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -889,7 +953,7 @@ func (m *Redelegation) Reset() { *m = Redelegation{} } func (m *Redelegation) String() string { return proto.CompactTextString(m) } func (*Redelegation) ProtoMessage() {} func (*Redelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{14} + return fileDescriptor_64c30c6cf92913c9, []int{15} } func (m *Redelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -941,7 +1005,7 @@ func (m *Params) Reset() { *m = Params{} } func (m *Params) String() string { return proto.CompactTextString(m) } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{15} + return fileDescriptor_64c30c6cf92913c9, []int{16} } func (m *Params) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1024,7 +1088,7 @@ func (m *DelegationResponse) Reset() { *m = DelegationResponse{} } func (m *DelegationResponse) String() string { return proto.CompactTextString(m) } func (*DelegationResponse) ProtoMessage() {} func (*DelegationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{16} + return fileDescriptor_64c30c6cf92913c9, []int{17} } func (m *DelegationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1079,7 +1143,7 @@ func (m *RedelegationEntryResponse) Reset() { *m = RedelegationEntryResp func (m *RedelegationEntryResponse) String() string { return proto.CompactTextString(m) } func (*RedelegationEntryResponse) ProtoMessage() {} func (*RedelegationEntryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{17} + return fileDescriptor_64c30c6cf92913c9, []int{18} } func (m *RedelegationEntryResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1127,7 +1191,7 @@ func (m *RedelegationResponse) Reset() { *m = RedelegationResponse{} } func (m *RedelegationResponse) String() string { return proto.CompactTextString(m) } func (*RedelegationResponse) ProtoMessage() {} func (*RedelegationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{18} + return fileDescriptor_64c30c6cf92913c9, []int{19} } func (m *RedelegationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1181,7 +1245,7 @@ func (m *Pool) Reset() { *m = Pool{} } func (m *Pool) String() string { return proto.CompactTextString(m) } func (*Pool) ProtoMessage() {} func (*Pool) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{19} + return fileDescriptor_64c30c6cf92913c9, []int{20} } func (m *Pool) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1222,7 +1286,7 @@ func (m *ValidatorUpdates) Reset() { *m = ValidatorUpdates{} } func (m *ValidatorUpdates) String() string { return proto.CompactTextString(m) } func (*ValidatorUpdates) ProtoMessage() {} func (*ValidatorUpdates) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{20} + return fileDescriptor_64c30c6cf92913c9, []int{21} } func (m *ValidatorUpdates) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1276,7 +1340,7 @@ func (m *ConsPubKeyRotationHistory) Reset() { *m = ConsPubKeyRotationHis func (m *ConsPubKeyRotationHistory) String() string { return proto.CompactTextString(m) } func (*ConsPubKeyRotationHistory) ProtoMessage() {} func (*ConsPubKeyRotationHistory) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{21} + return fileDescriptor_64c30c6cf92913c9, []int{22} } func (m *ConsPubKeyRotationHistory) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1315,7 +1379,7 @@ func (m *ValAddrsOfRotatedConsKeys) Reset() { *m = ValAddrsOfRotatedCons func (m *ValAddrsOfRotatedConsKeys) String() string { return proto.CompactTextString(m) } func (*ValAddrsOfRotatedConsKeys) ProtoMessage() {} func (*ValAddrsOfRotatedConsKeys) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{22} + return fileDescriptor_64c30c6cf92913c9, []int{23} } func (m *ValAddrsOfRotatedConsKeys) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1358,6 +1422,7 @@ func init() { proto.RegisterType((*CommissionRates)(nil), "cosmos.staking.v1beta1.CommissionRates") proto.RegisterType((*Commission)(nil), "cosmos.staking.v1beta1.Commission") proto.RegisterType((*Description)(nil), "cosmos.staking.v1beta1.Description") + proto.RegisterType((*Metadata)(nil), "cosmos.staking.v1beta1.Metadata") proto.RegisterType((*Validator)(nil), "cosmos.staking.v1beta1.Validator") proto.RegisterType((*ValAddresses)(nil), "cosmos.staking.v1beta1.ValAddresses") proto.RegisterType((*DVPair)(nil), "cosmos.staking.v1beta1.DVPair") @@ -1384,137 +1449,142 @@ func init() { } var fileDescriptor_64c30c6cf92913c9 = []byte{ - // 2065 bytes of a gzipped FileDescriptorProto + // 2146 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x59, 0x4b, 0x6c, 0x1b, 0xc7, - 0x19, 0xd6, 0x92, 0x0c, 0x25, 0xfd, 0x94, 0x44, 0x6a, 0xfc, 0xa2, 0xe8, 0x58, 0x92, 0x19, 0xb7, - 0x91, 0xdd, 0x9a, 0x8a, 0xdc, 0xc2, 0x05, 0x84, 0x20, 0x85, 0x29, 0xd2, 0x31, 0xf3, 0x90, 0xd4, - 0xa5, 0xa4, 0x3e, 0xd0, 0x66, 0x31, 0xdc, 0x1d, 0x52, 0x5b, 0x91, 0xb3, 0xec, 0xce, 0x50, 0x36, - 0xef, 0x3d, 0x04, 0x2e, 0x0a, 0xe4, 0x54, 0x04, 0x28, 0x8c, 0x1a, 0xe8, 0x25, 0xbd, 0xe5, 0x60, - 0xf4, 0xde, 0x5b, 0x5a, 0xa0, 0x80, 0xe1, 0x53, 0x11, 0xa0, 0x6e, 0x61, 0x1f, 0x12, 0x34, 0x97, - 0xa2, 0xa7, 0x1e, 0x8b, 0x79, 0xec, 0x83, 0xa2, 0x68, 0x59, 0x72, 0x50, 0x04, 0xed, 0x45, 0xe0, - 0xcc, 0xfc, 0xff, 0xb7, 0xf3, 0x7f, 0xf3, 0x3f, 0x66, 0x7e, 0xc1, 0x25, 0xdb, 0x63, 0x1d, 0x8f, - 0x2d, 0x33, 0x8e, 0xf7, 0x5c, 0xda, 0x5a, 0xde, 0x5f, 0x69, 0x10, 0x8e, 0x57, 0x82, 0x71, 0xa9, - 0xeb, 0x7b, 0xdc, 0x43, 0x67, 0x95, 0x54, 0x29, 0x98, 0xd5, 0x52, 0x85, 0xd3, 0x2d, 0xaf, 0xe5, - 0x49, 0x91, 0x65, 0xf1, 0x4b, 0x49, 0x17, 0xe6, 0x5a, 0x9e, 0xd7, 0x6a, 0x93, 0x65, 0x39, 0x6a, - 0xf4, 0x9a, 0xcb, 0x98, 0xf6, 0xf5, 0xd2, 0xfc, 0xc1, 0x25, 0xa7, 0xe7, 0x63, 0xee, 0x7a, 0x54, - 0xaf, 0x2f, 0x1c, 0x5c, 0xe7, 0x6e, 0x87, 0x30, 0x8e, 0x3b, 0xdd, 0x00, 0x5b, 0xed, 0xc4, 0x52, - 0x1f, 0xd5, 0xdb, 0xd2, 0xd8, 0xda, 0x94, 0x06, 0x66, 0x24, 0xb4, 0xc3, 0xf6, 0xdc, 0x00, 0x7b, - 0x16, 0x77, 0x5c, 0xea, 0x2d, 0xcb, 0xbf, 0x7a, 0xea, 0x82, 0xed, 0x75, 0x08, 0x6f, 0x34, 0xf9, - 0x32, 0xef, 0x77, 0x09, 0x5b, 0xde, 0x5f, 0x51, 0x3f, 0xf4, 0xf2, 0xcb, 0xe1, 0x32, 0x6e, 0xd8, - 0xee, 0x81, 0xd5, 0xe2, 0x87, 0x06, 0xcc, 0xdc, 0x72, 0x19, 0xf7, 0x7c, 0xd7, 0xc6, 0xed, 0x1a, - 0x6d, 0x7a, 0xe8, 0x75, 0x48, 0xef, 0x12, 0xec, 0x10, 0x3f, 0x6f, 0x2c, 0x1a, 0x4b, 0x99, 0x6b, - 0x73, 0xa5, 0x00, 0xa1, 0xa4, 0x34, 0xf7, 0x57, 0x4a, 0xb7, 0xa4, 0x40, 0x79, 0xf2, 0x93, 0xc7, - 0x0b, 0x63, 0x1f, 0x7d, 0xf6, 0xf1, 0x15, 0xc3, 0xd4, 0x3a, 0xa8, 0x02, 0xe9, 0x7d, 0xdc, 0x66, - 0x84, 0xe7, 0x13, 0x8b, 0xc9, 0xa5, 0xcc, 0xb5, 0x8b, 0xa5, 0xc3, 0x69, 0x2f, 0xed, 0xe0, 0xb6, - 0xeb, 0x60, 0xee, 0x0d, 0xa2, 0x28, 0xdd, 0xd5, 0x44, 0xde, 0x28, 0xfe, 0x2a, 0x01, 0xd9, 0x35, - 0xaf, 0xd3, 0x71, 0x19, 0x73, 0x3d, 0x6a, 0x62, 0x4e, 0x18, 0x7a, 0x0b, 0x52, 0x3e, 0xe6, 0x44, - 0xee, 0x6c, 0xb2, 0x7c, 0x5d, 0x28, 0x7e, 0xfa, 0x78, 0xe1, 0xbc, 0xfa, 0x04, 0x73, 0xf6, 0x4a, - 0xae, 0xb7, 0xdc, 0xc1, 0x7c, 0xb7, 0xf4, 0x0e, 0x69, 0x61, 0xbb, 0x5f, 0x21, 0xf6, 0xa3, 0x07, - 0x57, 0x41, 0xef, 0xa0, 0x42, 0x6c, 0xf5, 0x15, 0x89, 0x81, 0xbe, 0x07, 0x13, 0x1d, 0x7c, 0xc7, - 0x92, 0x78, 0x89, 0x17, 0xc2, 0x1b, 0xef, 0xe0, 0x3b, 0x62, 0x7f, 0xe8, 0x3d, 0xc8, 0x0a, 0x48, - 0x7b, 0x17, 0xd3, 0x16, 0x51, 0xc8, 0xc9, 0x17, 0x42, 0x9e, 0xee, 0xe0, 0x3b, 0x6b, 0x12, 0x4d, - 0xe0, 0xaf, 0xa6, 0x3e, 0xbf, 0xbf, 0x60, 0x14, 0xff, 0x60, 0x00, 0x44, 0xc4, 0x20, 0x0c, 0x39, - 0x3b, 0x1c, 0xc9, 0x8f, 0x32, 0x7d, 0x72, 0xaf, 0x8e, 0xe2, 0xfe, 0x00, 0xad, 0xe5, 0x69, 0xb1, - 0xbd, 0x87, 0x8f, 0x17, 0x0c, 0xf5, 0xd5, 0xac, 0x3d, 0x44, 0x7b, 0xa6, 0xd7, 0x75, 0x30, 0x27, - 0x96, 0x70, 0x65, 0xc9, 0x56, 0xe6, 0x5a, 0xa1, 0xa4, 0xfc, 0xbc, 0x14, 0xf8, 0x79, 0x69, 0x2b, - 0xf0, 0x73, 0x05, 0xf8, 0xc1, 0xdf, 0x02, 0x40, 0x50, 0xda, 0x62, 0x5d, 0xdb, 0xf0, 0x91, 0x01, - 0x99, 0x0a, 0x61, 0xb6, 0xef, 0x76, 0x45, 0xe4, 0xa0, 0x3c, 0x8c, 0x77, 0x3c, 0xea, 0xee, 0x69, - 0xaf, 0x9b, 0x34, 0x83, 0x21, 0x2a, 0xc0, 0x84, 0xeb, 0x10, 0xca, 0x5d, 0xde, 0x57, 0xc7, 0x64, - 0x86, 0x63, 0xa1, 0x75, 0x9b, 0x34, 0x98, 0x1b, 0xf0, 0x6c, 0x06, 0x43, 0x74, 0x19, 0x72, 0x8c, - 0xd8, 0x3d, 0xdf, 0xe5, 0x7d, 0xcb, 0xf6, 0x28, 0xc7, 0x36, 0xcf, 0xa7, 0xa4, 0x48, 0x36, 0x98, - 0x5f, 0x53, 0xd3, 0x02, 0xc4, 0x21, 0x1c, 0xbb, 0x6d, 0x96, 0x7f, 0x49, 0x81, 0xe8, 0xa1, 0xde, - 0xea, 0xbd, 0x71, 0x98, 0x0c, 0x9d, 0x15, 0xad, 0x41, 0xce, 0xeb, 0x12, 0x5f, 0xfc, 0xb6, 0xb0, - 0xe3, 0xf8, 0x84, 0x31, 0xed, 0x8d, 0xf9, 0x47, 0x0f, 0xae, 0x9e, 0xd6, 0x84, 0xdf, 0x50, 0x2b, - 0x75, 0xee, 0xbb, 0xb4, 0x65, 0x66, 0x03, 0x0d, 0x3d, 0x8d, 0x7e, 0x28, 0x8e, 0x8c, 0x32, 0x42, - 0x59, 0x8f, 0x59, 0xdd, 0x5e, 0x63, 0x8f, 0xf4, 0x35, 0xa9, 0xa7, 0x87, 0x48, 0xbd, 0x41, 0xfb, - 0xe5, 0xfc, 0x9f, 0x22, 0x68, 0xdb, 0xef, 0x77, 0xb9, 0x57, 0xda, 0xec, 0x35, 0xde, 0x26, 0x7d, - 0x71, 0x54, 0x1a, 0x67, 0x53, 0xc2, 0xa0, 0xb3, 0x90, 0xfe, 0x29, 0x76, 0xdb, 0xc4, 0x91, 0x8c, - 0x4c, 0x98, 0x7a, 0x84, 0x56, 0x21, 0xcd, 0x38, 0xe6, 0x3d, 0x26, 0x69, 0x98, 0xb9, 0x56, 0x1c, - 0xe5, 0x1b, 0x65, 0x8f, 0x3a, 0x75, 0x29, 0x69, 0x6a, 0x0d, 0xb4, 0x06, 0x69, 0xee, 0xed, 0x11, - 0xaa, 0x09, 0x2a, 0x7f, 0x43, 0x7b, 0xf3, 0x99, 0x61, 0x6f, 0xae, 0x51, 0x1e, 0xf3, 0xe3, 0x1a, - 0xe5, 0xa6, 0x56, 0x45, 0x3f, 0x86, 0x9c, 0x43, 0xda, 0xa4, 0x25, 0x99, 0x63, 0xbb, 0xd8, 0x27, - 0x2c, 0x9f, 0x96, 0x70, 0x2b, 0xc7, 0x0e, 0x0e, 0x33, 0x1b, 0x42, 0xd5, 0x25, 0x12, 0xda, 0x84, - 0x8c, 0x13, 0xb9, 0x53, 0x7e, 0x5c, 0x92, 0xf9, 0xca, 0x28, 0x1b, 0x63, 0x9e, 0x17, 0xcf, 0x3e, - 0x71, 0x08, 0xe1, 0x41, 0x3d, 0xda, 0xf0, 0xa8, 0xe3, 0xd2, 0x96, 0xb5, 0x4b, 0xdc, 0xd6, 0x2e, - 0xcf, 0x4f, 0x2c, 0x1a, 0x4b, 0x49, 0x33, 0x1b, 0xce, 0xdf, 0x92, 0xd3, 0x68, 0x13, 0x66, 0x22, - 0x51, 0x19, 0x21, 0x93, 0xc7, 0x8d, 0x90, 0xe9, 0x10, 0x40, 0x88, 0xa0, 0x77, 0x01, 0xa2, 0x18, - 0xcc, 0x83, 0x44, 0x2b, 0x1e, 0x1d, 0xcd, 0x71, 0x63, 0x62, 0x00, 0x88, 0xc2, 0xa9, 0x8e, 0x4b, - 0x2d, 0x46, 0xda, 0x4d, 0x4b, 0x33, 0x27, 0x70, 0x33, 0x92, 0xfe, 0x37, 0x8e, 0x71, 0x9a, 0x9f, - 0x3e, 0xb8, 0x9a, 0x55, 0xa3, 0xab, 0xcc, 0xd9, 0x5b, 0x7c, 0xad, 0xf4, 0xed, 0xef, 0x98, 0xb3, - 0x1d, 0x97, 0xd6, 0x49, 0xbb, 0x59, 0x09, 0x81, 0xd1, 0xeb, 0x70, 0x3e, 0x22, 0xc4, 0xa3, 0xd6, - 0xae, 0xd7, 0x76, 0x2c, 0x9f, 0x34, 0x2d, 0xdb, 0xeb, 0x51, 0x9e, 0x9f, 0x92, 0x34, 0x9e, 0x0b, - 0x45, 0x36, 0xe8, 0x2d, 0xaf, 0xed, 0x98, 0xa4, 0xb9, 0x26, 0x96, 0xd1, 0x2b, 0x10, 0xb1, 0x61, - 0xb9, 0x0e, 0xcb, 0x4f, 0x2f, 0x26, 0x97, 0x52, 0xe6, 0x54, 0x38, 0x59, 0x73, 0xd8, 0xea, 0xc4, - 0xfb, 0xf7, 0x17, 0xc6, 0x3e, 0xbf, 0xbf, 0x30, 0x56, 0xbc, 0x09, 0x53, 0x3b, 0xb8, 0xad, 0x43, - 0x8b, 0x30, 0x74, 0x1d, 0x26, 0x71, 0x30, 0xc8, 0x1b, 0x8b, 0xc9, 0x67, 0x86, 0x66, 0x24, 0x5a, - 0xfc, 0x9d, 0x01, 0xe9, 0xca, 0xce, 0x26, 0x76, 0x7d, 0x54, 0x85, 0xd9, 0xc8, 0x57, 0x9f, 0x37, - 0xca, 0x23, 0xf7, 0x0e, 0xc2, 0x7c, 0x1d, 0x66, 0xf7, 0x83, 0xc4, 0x11, 0xc2, 0xa8, 0x52, 0x73, - 0xf1, 0xd1, 0x83, 0xab, 0x17, 0x34, 0x4c, 0x98, 0x5c, 0x0e, 0xe0, 0xed, 0x1f, 0x98, 0x8f, 0xd9, - 0xfc, 0x16, 0x8c, 0xab, 0xad, 0x32, 0xf4, 0x5d, 0x78, 0xa9, 0x2b, 0x7e, 0x48, 0x53, 0x33, 0xd7, - 0xe6, 0x47, 0xfa, 0xbc, 0x94, 0x8f, 0x7b, 0x88, 0xd2, 0x2b, 0xfe, 0x22, 0x01, 0x50, 0xd9, 0xd9, - 0xd9, 0xf2, 0xdd, 0x6e, 0x9b, 0xf0, 0x2f, 0xcb, 0xf6, 0x6d, 0x38, 0x13, 0xd9, 0xce, 0x7c, 0xfb, - 0xf8, 0xf6, 0x9f, 0x0a, 0xf5, 0xeb, 0xbe, 0x7d, 0x28, 0xac, 0xc3, 0x78, 0x08, 0x9b, 0x3c, 0x3e, - 0x6c, 0x85, 0xf1, 0x61, 0x66, 0x7f, 0x00, 0x99, 0x88, 0x0c, 0x86, 0x6a, 0x30, 0xc1, 0xf5, 0x6f, - 0x4d, 0x70, 0x71, 0x34, 0xc1, 0x81, 0x5a, 0x9c, 0xe4, 0x50, 0xbd, 0xf8, 0x6f, 0x03, 0x20, 0x16, - 0x23, 0x5f, 0x4d, 0x1f, 0x43, 0x35, 0x48, 0xeb, 0xe4, 0x9c, 0x3c, 0x69, 0x72, 0xd6, 0x00, 0x31, - 0x52, 0x7f, 0x99, 0x80, 0x53, 0xdb, 0x41, 0xf4, 0x7e, 0xf5, 0x39, 0xd8, 0x86, 0x71, 0x42, 0xb9, - 0xef, 0x4a, 0x12, 0xc4, 0x99, 0xbf, 0x36, 0xea, 0xcc, 0x0f, 0x31, 0xaa, 0x4a, 0xb9, 0xdf, 0x8f, - 0x7b, 0x40, 0x80, 0x15, 0xe3, 0xe3, 0xd7, 0x49, 0xc8, 0x8f, 0x52, 0x45, 0xaf, 0x42, 0xd6, 0xf6, - 0x89, 0x9c, 0x08, 0xea, 0x8e, 0x21, 0x13, 0xe6, 0x4c, 0x30, 0xad, 0xcb, 0x8e, 0x09, 0xe2, 0xa2, - 0x26, 0x9c, 0x4b, 0x88, 0x9e, 0xec, 0x66, 0x36, 0x13, 0x21, 0xc8, 0xc2, 0xb3, 0x05, 0x59, 0x97, - 0xba, 0xdc, 0xc5, 0x6d, 0xab, 0x81, 0xdb, 0x98, 0xda, 0xc1, 0x0d, 0xf6, 0x58, 0x35, 0x7f, 0x46, - 0x63, 0x94, 0x15, 0x04, 0xaa, 0xc2, 0x78, 0x80, 0x96, 0x3a, 0x3e, 0x5a, 0xa0, 0x8b, 0x2e, 0xc2, - 0x54, 0xbc, 0x30, 0xc8, 0xdb, 0x48, 0xca, 0xcc, 0xc4, 0xea, 0xc2, 0x51, 0x95, 0x27, 0xfd, 0xcc, - 0xca, 0xa3, 0x2f, 0x7c, 0xbf, 0x49, 0xc2, 0xac, 0x49, 0x9c, 0xff, 0xfd, 0x63, 0xd9, 0x04, 0x50, - 0xa1, 0x2a, 0x32, 0xa9, 0x3e, 0x99, 0x13, 0xc4, 0xfb, 0xa4, 0x02, 0xa9, 0x30, 0xfe, 0xdf, 0x3a, - 0xa1, 0xbf, 0x26, 0x60, 0x2a, 0x7e, 0x42, 0xff, 0x97, 0x45, 0x0b, 0xad, 0x47, 0x69, 0x2a, 0x25, - 0xd3, 0xd4, 0xe5, 0x51, 0x69, 0x6a, 0xc8, 0x9b, 0x8f, 0xc8, 0x4f, 0x5f, 0x24, 0x21, 0xbd, 0x89, - 0x7d, 0xdc, 0x61, 0x68, 0x63, 0xe8, 0x6e, 0x1b, 0x74, 0x05, 0x0e, 0x3a, 0x73, 0x45, 0x77, 0x41, - 0x94, 0x2f, 0x7f, 0x38, 0xea, 0x6a, 0xfb, 0x35, 0x98, 0x11, 0x6f, 0xe4, 0xd0, 0x20, 0x45, 0xee, - 0xb4, 0x7c, 0xea, 0x86, 0xd6, 0x33, 0xb4, 0x00, 0x19, 0x21, 0x16, 0xe5, 0x61, 0x21, 0x03, 0x1d, - 0x7c, 0xa7, 0xaa, 0x66, 0xd0, 0x0a, 0xa0, 0xdd, 0xb0, 0x71, 0x61, 0x45, 0x44, 0x18, 0x4b, 0xd3, - 0xe5, 0x44, 0xde, 0x30, 0x67, 0xa3, 0xd5, 0x40, 0xe5, 0x02, 0x80, 0xd8, 0x89, 0xe5, 0x10, 0xea, - 0x75, 0xf4, 0x63, 0x6f, 0x52, 0xcc, 0x54, 0xc4, 0x04, 0xfa, 0xb9, 0xa1, 0xae, 0xc9, 0x07, 0x5e, - 0xd3, 0xfa, 0x95, 0xb2, 0xf5, 0x1c, 0x81, 0xf1, 0xaf, 0xc7, 0x0b, 0x85, 0x3e, 0xee, 0xb4, 0x57, - 0x8b, 0x87, 0xe0, 0x14, 0x0f, 0x7b, 0xe0, 0x8b, 0xcb, 0xf3, 0xe0, 0x6b, 0x1c, 0xd5, 0x20, 0xb7, - 0x47, 0xfa, 0x96, 0xef, 0x71, 0x95, 0x6c, 0x9a, 0x84, 0xe8, 0xf7, 0xcc, 0x5c, 0x70, 0xbe, 0x0d, - 0xcc, 0x48, 0xec, 0xfa, 0xef, 0xd2, 0x72, 0x4a, 0xec, 0xce, 0x9c, 0xd9, 0x23, 0x7d, 0x53, 0xeb, - 0xdd, 0x24, 0x64, 0xf5, 0x92, 0x88, 0x96, 0xbb, 0x9f, 0x7d, 0x7c, 0xe5, 0x7c, 0x74, 0x69, 0x5f, - 0xbe, 0x13, 0xf6, 0xc9, 0xd4, 0x11, 0x8b, 0x8b, 0x2f, 0x8a, 0x8a, 0x90, 0x49, 0x58, 0x57, 0xbc, - 0x29, 0xc5, 0x1b, 0x24, 0xf6, 0x56, 0x30, 0x9e, 0xfd, 0x06, 0x89, 0xf4, 0x07, 0xde, 0x20, 0xb1, - 0x10, 0x7d, 0x23, 0xaa, 0x01, 0x89, 0xa3, 0xac, 0x89, 0x7b, 0xa7, 0x56, 0x92, 0x91, 0x3f, 0x56, - 0xfc, 0xb3, 0x01, 0x73, 0x43, 0xde, 0x1c, 0x6e, 0xd9, 0x06, 0xe4, 0xc7, 0x16, 0xa5, 0x57, 0xf4, - 0xf5, 0xd6, 0x4f, 0x16, 0x1c, 0xb3, 0xfe, 0x50, 0x21, 0xf8, 0x72, 0x8a, 0x99, 0xce, 0x64, 0x7f, - 0x34, 0xe0, 0x74, 0x7c, 0x03, 0xa1, 0x29, 0x75, 0x98, 0x8a, 0x7f, 0x5a, 0x1b, 0x71, 0xe9, 0x79, - 0x8c, 0x88, 0xef, 0x7f, 0x00, 0x04, 0xed, 0x44, 0x19, 0x43, 0x75, 0xe7, 0x56, 0x9e, 0x9b, 0x94, - 0x60, 0x63, 0x87, 0x66, 0x0e, 0x75, 0x36, 0x5f, 0x18, 0x90, 0xda, 0xf4, 0xbc, 0x36, 0xfa, 0x19, - 0xcc, 0x52, 0x8f, 0x5b, 0x22, 0xb2, 0x88, 0x63, 0xe9, 0xd6, 0x81, 0xca, 0xc6, 0xd5, 0x67, 0x72, - 0xf5, 0x8f, 0xc7, 0x0b, 0xc3, 0x9a, 0x83, 0x04, 0xea, 0x0e, 0x15, 0xf5, 0x78, 0x59, 0x0a, 0x6d, - 0xa9, 0xee, 0x42, 0x13, 0xa6, 0x07, 0x3f, 0xa7, 0x32, 0xf6, 0x8d, 0xa3, 0x3e, 0x37, 0x7d, 0xe4, - 0xa7, 0xa6, 0x1a, 0xb1, 0xef, 0xac, 0x4e, 0x88, 0x53, 0xfb, 0xa7, 0x38, 0xb9, 0xf7, 0x20, 0x17, - 0xa6, 0xab, 0x6d, 0xd9, 0xde, 0x62, 0xe8, 0x26, 0x8c, 0xab, 0x4e, 0x57, 0xf0, 0x58, 0xb8, 0x18, - 0xf5, 0x4e, 0x71, 0xc3, 0x76, 0x4b, 0xfb, 0xb1, 0xbe, 0xa7, 0x52, 0x1a, 0xe0, 0x53, 0x2b, 0xcb, - 0xf6, 0xe7, 0xc3, 0x04, 0xcc, 0xad, 0x79, 0x94, 0xe9, 0x46, 0x8f, 0x8e, 0x6a, 0xd5, 0xab, 0xed, - 0xa3, 0xcb, 0x23, 0xda, 0x50, 0x53, 0xc3, 0xcd, 0xa6, 0x1d, 0xc8, 0x8a, 0x12, 0x6b, 0x7b, 0xf4, - 0x05, 0x7b, 0x4d, 0xd3, 0x5e, 0xdb, 0xd1, 0x3b, 0xda, 0x23, 0x7d, 0x81, 0x4b, 0xc9, 0xed, 0x01, - 0xdc, 0xe4, 0xc9, 0x70, 0x29, 0xb9, 0x1d, 0xc3, 0x3d, 0x0b, 0x69, 0x7d, 0xbf, 0x4a, 0xc9, 0xdb, - 0x83, 0x1e, 0xa1, 0xeb, 0x90, 0x14, 0xa9, 0xf0, 0xa5, 0x63, 0x24, 0x0f, 0xa1, 0x10, 0x2b, 0x6b, - 0x75, 0x98, 0xd3, 0x9d, 0x02, 0xb6, 0xd1, 0x94, 0x8c, 0x12, 0x69, 0xd0, 0xdb, 0xa4, 0x7f, 0x48, - 0xdb, 0x60, 0xea, 0xb9, 0xda, 0x06, 0x57, 0x7e, 0x6f, 0x00, 0x44, 0x3d, 0x33, 0xf4, 0x4d, 0x38, - 0x57, 0xde, 0x58, 0xaf, 0x58, 0xf5, 0xad, 0x1b, 0x5b, 0xdb, 0x75, 0x6b, 0x7b, 0xbd, 0xbe, 0x59, - 0x5d, 0xab, 0xdd, 0xac, 0x55, 0x2b, 0xb9, 0xb1, 0x42, 0xf6, 0xee, 0xbd, 0xc5, 0xcc, 0x36, 0x65, - 0x5d, 0x62, 0xbb, 0x4d, 0x97, 0x38, 0xe8, 0xeb, 0x70, 0x7a, 0x50, 0x5a, 0x8c, 0xaa, 0x95, 0x9c, - 0x51, 0x98, 0xba, 0x7b, 0x6f, 0x71, 0x42, 0xbd, 0x11, 0x88, 0x83, 0x96, 0xe0, 0xcc, 0xb0, 0x5c, - 0x6d, 0xfd, 0xcd, 0x5c, 0xa2, 0x30, 0x7d, 0xf7, 0xde, 0xe2, 0x64, 0xf8, 0x98, 0x40, 0x45, 0x40, - 0x71, 0x49, 0x8d, 0x97, 0x2c, 0xc0, 0xdd, 0x7b, 0x8b, 0x69, 0x15, 0x32, 0x85, 0xd4, 0xfb, 0xbf, - 0x9d, 0x1f, 0xbb, 0xf2, 0x13, 0x80, 0x1a, 0x6d, 0xfa, 0xd8, 0x96, 0xa9, 0xa1, 0x00, 0x67, 0x6b, - 0xeb, 0x37, 0xcd, 0x1b, 0x6b, 0x5b, 0xb5, 0x8d, 0xf5, 0xc1, 0x6d, 0x1f, 0x58, 0xab, 0x6c, 0x6c, - 0x97, 0xdf, 0xa9, 0x5a, 0xf5, 0xda, 0x9b, 0xeb, 0x39, 0x03, 0x9d, 0x83, 0x53, 0x03, 0x6b, 0xdf, - 0x5f, 0xdf, 0xaa, 0xbd, 0x5b, 0xcd, 0x25, 0xca, 0xd7, 0x3f, 0x79, 0x32, 0x6f, 0x3c, 0x7c, 0x32, - 0x6f, 0xfc, 0xfd, 0xc9, 0xbc, 0xf1, 0xc1, 0xd3, 0xf9, 0xb1, 0x87, 0x4f, 0xe7, 0xc7, 0xfe, 0xf2, - 0x74, 0x7e, 0xec, 0x47, 0x2f, 0x0f, 0x04, 0x63, 0x54, 0x8e, 0xe4, 0x7f, 0x17, 0x1a, 0x69, 0xe9, - 0x35, 0xdf, 0xfa, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf4, 0xd1, 0x83, 0x1f, 0xd5, 0x19, 0x00, - 0x00, + 0x19, 0xd6, 0x92, 0x34, 0x25, 0xfe, 0x14, 0x45, 0x6a, 0xfc, 0xa2, 0xe8, 0x58, 0x92, 0x19, 0x37, + 0x91, 0xdd, 0x98, 0x8c, 0xdc, 0xc2, 0x05, 0x84, 0x20, 0x85, 0x29, 0xca, 0x36, 0x93, 0x58, 0x52, + 0x97, 0xa2, 0xfa, 0x40, 0x9b, 0xc5, 0x70, 0x77, 0x48, 0x6d, 0x45, 0xee, 0xb2, 0x3b, 0x43, 0xd9, + 0xbc, 0xf7, 0x10, 0xb8, 0x28, 0x90, 0x53, 0x11, 0xa0, 0x30, 0x6a, 0xa0, 0x97, 0xf6, 0x96, 0x83, + 0xd1, 0x7b, 0x6f, 0x69, 0x81, 0x02, 0x86, 0x4f, 0x45, 0x80, 0xba, 0x85, 0x7d, 0x48, 0xd0, 0x5c, + 0xda, 0x9e, 0x7a, 0x2c, 0xe6, 0xb1, 0x0f, 0x8a, 0xa2, 0x65, 0xc9, 0x41, 0x11, 0xb4, 0x17, 0x62, + 0x67, 0xe6, 0xff, 0xbf, 0x99, 0xff, 0x3d, 0xf3, 0x13, 0x2e, 0x9a, 0x2e, 0xed, 0xba, 0xb4, 0x4c, + 0x19, 0xde, 0xb5, 0x9d, 0x76, 0x79, 0x6f, 0xb9, 0x49, 0x18, 0x5e, 0xf6, 0xc7, 0xa5, 0x9e, 0xe7, + 0x32, 0x17, 0x9d, 0x91, 0x54, 0x25, 0x7f, 0x56, 0x51, 0x15, 0x66, 0x71, 0xd7, 0x76, 0xdc, 0xb2, + 0xf8, 0x95, 0xa4, 0x85, 0x57, 0x4c, 0xb7, 0x4b, 0x58, 0xb3, 0xc5, 0xca, 0xb8, 0x69, 0xda, 0xe5, + 0xbd, 0xe5, 0x32, 0x1b, 0xf4, 0x08, 0x55, 0xab, 0xe7, 0x83, 0x55, 0x31, 0xbb, 0x7f, 0x79, 0x5e, + 0x9d, 0xa6, 0x89, 0x29, 0x09, 0x8e, 0x62, 0xba, 0xb6, 0xa3, 0xd6, 0xe7, 0xe4, 0xba, 0x21, 0x46, + 0x65, 0x75, 0x28, 0xb9, 0x74, 0xaa, 0xed, 0xb6, 0x5d, 0x39, 0xcf, 0xbf, 0x7c, 0x86, 0xb6, 0xeb, + 0xb6, 0x3b, 0xa4, 0x2c, 0x46, 0xcd, 0x7e, 0xab, 0x8c, 0x9d, 0x81, 0xbf, 0xd7, 0xfe, 0x25, 0xab, + 0xef, 0x61, 0x66, 0xbb, 0xfe, 0x5e, 0x0b, 0xfb, 0xd7, 0x99, 0xdd, 0x25, 0x94, 0xe1, 0x6e, 0x4f, + 0x12, 0x14, 0x3f, 0xd2, 0x60, 0xe6, 0x96, 0x4d, 0x99, 0xeb, 0xd9, 0x26, 0xee, 0xd4, 0x9c, 0x96, + 0x8b, 0xde, 0x82, 0xe4, 0x0e, 0xc1, 0x16, 0xf1, 0xf2, 0xda, 0xa2, 0xb6, 0x94, 0xbe, 0x3a, 0x57, + 0xf2, 0xe5, 0x2d, 0x49, 0x31, 0xf7, 0x96, 0x4b, 0xb7, 0x04, 0x41, 0x25, 0xf5, 0xc9, 0x93, 0x85, + 0x89, 0xdf, 0x7c, 0xf6, 0xf1, 0x65, 0x4d, 0x57, 0x3c, 0xa8, 0x0a, 0xc9, 0x3d, 0xdc, 0xa1, 0x84, + 0xe5, 0x63, 0x8b, 0xf1, 0xa5, 0xf4, 0xd5, 0x0b, 0xa5, 0x83, 0xd5, 0x5e, 0xda, 0xc6, 0x1d, 0xdb, + 0xc2, 0xcc, 0x1d, 0x46, 0x91, 0xbc, 0x2b, 0xb1, 0xbc, 0x56, 0xfc, 0x45, 0x0c, 0xb2, 0xab, 0x6e, + 0xb7, 0x6b, 0x53, 0x6a, 0xbb, 0x8e, 0x8e, 0x19, 0xa1, 0xe8, 0x1d, 0x48, 0x78, 0x98, 0x11, 0x71, + 0xb2, 0x54, 0xe5, 0x1a, 0x67, 0xfc, 0xf4, 0xc9, 0xc2, 0x39, 0xb9, 0x05, 0xb5, 0x76, 0x4b, 0xb6, + 0x5b, 0xee, 0x62, 0xb6, 0x53, 0x7a, 0x8f, 0xb4, 0xb1, 0x39, 0xa8, 0x12, 0xf3, 0xf1, 0xc3, 0x2b, + 0xa0, 0x4e, 0x50, 0x25, 0xa6, 0xdc, 0x45, 0x60, 0xa0, 0xef, 0xc0, 0x54, 0x17, 0xdf, 0x35, 0x04, + 0x5e, 0xec, 0xa5, 0xf0, 0x26, 0xbb, 0xf8, 0x2e, 0x3f, 0x1f, 0x7a, 0x1f, 0xb2, 0x1c, 0xd2, 0xdc, + 0xc1, 0x4e, 0x9b, 0x48, 0xe4, 0xf8, 0x4b, 0x21, 0x67, 0xba, 0xf8, 0xee, 0xaa, 0x40, 0xe3, 0xf8, + 0x2b, 0x89, 0xcf, 0x1f, 0x2c, 0x68, 0xc5, 0xdf, 0x6b, 0x00, 0xa1, 0x62, 0x10, 0x86, 0x9c, 0x19, + 0x8c, 0xc4, 0xa6, 0x54, 0x59, 0xee, 0xf5, 0x71, 0xba, 0xdf, 0xa7, 0xd6, 0x4a, 0x86, 0x1f, 0xef, + 0xd1, 0x93, 0x05, 0x4d, 0xee, 0x9a, 0x35, 0x47, 0xd4, 0x9e, 0xee, 0xf7, 0x2c, 0xcc, 0x88, 0xc1, + 0xfd, 0x47, 0x68, 0x2b, 0x7d, 0xb5, 0x50, 0x92, 0xce, 0x55, 0xf2, 0x9d, 0xab, 0xb4, 0xe5, 0x3b, + 0x97, 0x04, 0xfc, 0xf0, 0xaf, 0x3e, 0x20, 0x48, 0x6e, 0xbe, 0xae, 0x64, 0xf8, 0xa7, 0x06, 0xe9, + 0x2a, 0xa1, 0xa6, 0x67, 0xf7, 0xb8, 0xbb, 0xa2, 0x3c, 0x4c, 0x76, 0x5d, 0xc7, 0xde, 0x55, 0x5e, + 0x97, 0xd2, 0xfd, 0x21, 0x2a, 0xc0, 0x94, 0x6d, 0x11, 0x87, 0xd9, 0x6c, 0x20, 0xcd, 0xa4, 0x07, + 0x63, 0xce, 0x75, 0x87, 0x34, 0xa9, 0xed, 0xeb, 0x59, 0xf7, 0x87, 0xe8, 0x12, 0xe4, 0x28, 0x31, + 0xfb, 0x9e, 0xcd, 0x06, 0x86, 0xe9, 0x3a, 0x0c, 0x9b, 0x2c, 0x9f, 0x10, 0x24, 0x59, 0x7f, 0x7e, + 0x55, 0x4e, 0x73, 0x10, 0x8b, 0x30, 0x6c, 0x77, 0x68, 0xfe, 0x84, 0x04, 0x51, 0x43, 0x74, 0x13, + 0xa6, 0xba, 0x84, 0x61, 0x0b, 0x33, 0x9c, 0x4f, 0x0a, 0x99, 0x17, 0xc7, 0x69, 0xf4, 0xb6, 0xa2, + 0x8b, 0x3a, 0x73, 0xc0, 0xac, 0x64, 0x6e, 0xc1, 0x94, 0x4f, 0x86, 0x5e, 0x83, 0x6c, 0xcf, 0x73, + 0x5b, 0x76, 0x87, 0x18, 0x3d, 0xdb, 0x34, 0xfa, 0x9e, 0xad, 0xe4, 0xce, 0xa8, 0xe9, 0x4d, 0xdb, + 0x6c, 0x78, 0x36, 0x7a, 0x03, 0x10, 0x75, 0x4d, 0x1b, 0x77, 0x8c, 0x1d, 0xec, 0x58, 0x1d, 0xc2, + 0x29, 0xa9, 0x08, 0xad, 0x94, 0x9e, 0x93, 0x2b, 0xb7, 0xc4, 0x42, 0xc3, 0xb3, 0xa9, 0xda, 0xe7, + 0xfe, 0x24, 0xa4, 0x82, 0xe8, 0x42, 0xab, 0x90, 0x73, 0x7b, 0xc4, 0xe3, 0xdf, 0x06, 0xb6, 0x2c, + 0x8f, 0x50, 0xaa, 0xc2, 0x27, 0xff, 0xf8, 0xe1, 0x95, 0x53, 0x4a, 0x9e, 0xeb, 0x72, 0xa5, 0xce, + 0x3c, 0xdb, 0x69, 0xeb, 0x59, 0x9f, 0x43, 0x4d, 0xa3, 0xef, 0x73, 0x1f, 0x73, 0x28, 0x71, 0x68, + 0x9f, 0x1a, 0xbd, 0x7e, 0x73, 0x97, 0x0c, 0x94, 0x17, 0x9c, 0x1a, 0xf1, 0x82, 0xeb, 0xce, 0xa0, + 0x92, 0xff, 0x63, 0x08, 0x6d, 0x7a, 0x83, 0x1e, 0x73, 0x4b, 0x9b, 0xfd, 0xe6, 0xbb, 0x64, 0xc0, + 0x7d, 0x4b, 0xe1, 0x6c, 0x0a, 0x18, 0x74, 0x06, 0x92, 0x3f, 0xc6, 0x76, 0x87, 0x58, 0xc2, 0x84, + 0x53, 0xba, 0x1a, 0xa1, 0x15, 0x48, 0x52, 0x86, 0x59, 0x9f, 0x0a, 0xbb, 0xcd, 0x5c, 0x2d, 0x8e, + 0x53, 0x7d, 0xc5, 0x75, 0xac, 0xba, 0xa0, 0xd4, 0x15, 0x07, 0x5a, 0x85, 0x24, 0x73, 0x77, 0x89, + 0xa3, 0x2c, 0x5a, 0xf9, 0xba, 0x0a, 0xbf, 0xd3, 0xa3, 0xe1, 0x57, 0x73, 0x58, 0x24, 0xf0, 0x6a, + 0x0e, 0xd3, 0x15, 0x2b, 0xfa, 0x21, 0xe4, 0x2c, 0xd2, 0x21, 0x6d, 0xa1, 0x39, 0xba, 0x83, 0x3d, + 0x42, 0x85, 0x17, 0xa4, 0x2a, 0xcb, 0x47, 0x8e, 0x66, 0x3d, 0x1b, 0x40, 0xd5, 0x05, 0x12, 0xda, + 0x84, 0xb4, 0x15, 0xfa, 0x7f, 0x7e, 0x52, 0x28, 0xf3, 0xd5, 0x71, 0x32, 0x46, 0x42, 0x25, 0xea, + 0x61, 0x51, 0x08, 0xee, 0xf2, 0x7d, 0xa7, 0xe9, 0x3a, 0x96, 0xed, 0xb4, 0x8d, 0x1d, 0x62, 0xb7, + 0x77, 0x58, 0x7e, 0x6a, 0x51, 0x5b, 0x8a, 0xeb, 0xd9, 0x60, 0xfe, 0x96, 0x98, 0x46, 0x9b, 0x30, + 0x13, 0x92, 0x8a, 0x90, 0x4e, 0x1d, 0x35, 0xa4, 0x33, 0x01, 0x00, 0x27, 0x41, 0xb7, 0x01, 0xc2, + 0xa4, 0x91, 0x07, 0x81, 0x56, 0x3c, 0x3c, 0xfd, 0x44, 0x85, 0x89, 0x00, 0x20, 0x07, 0x4e, 0x76, + 0x6d, 0xc7, 0xa0, 0xa4, 0xd3, 0x32, 0x94, 0xe6, 0x38, 0x6e, 0x5a, 0xa8, 0xff, 0xed, 0x23, 0x58, + 0xf3, 0xd3, 0x87, 0x57, 0xb2, 0x72, 0x74, 0x85, 0x5a, 0xbb, 0x8b, 0x6f, 0x96, 0xbe, 0xf9, 0x2d, + 0x7d, 0xb6, 0x6b, 0x3b, 0x75, 0xd2, 0x69, 0x55, 0x03, 0x60, 0xf4, 0x16, 0x9c, 0x0b, 0x15, 0xe2, + 0x3a, 0xc6, 0x8e, 0xdb, 0xb1, 0x0c, 0x8f, 0xb4, 0x0c, 0xd3, 0xed, 0x3b, 0x2c, 0x3f, 0x2d, 0xd4, + 0x78, 0x36, 0x20, 0xd9, 0x70, 0x6e, 0xb9, 0x1d, 0x4b, 0x27, 0xad, 0x55, 0xbe, 0x8c, 0x5e, 0x85, + 0x50, 0x1b, 0x86, 0x6d, 0xd1, 0x7c, 0x66, 0x31, 0xbe, 0x94, 0xd0, 0xa7, 0x83, 0xc9, 0x9a, 0x45, + 0x57, 0xa6, 0x3e, 0x78, 0xb0, 0x30, 0xf1, 0xf9, 0x83, 0x85, 0x89, 0xe2, 0x0d, 0x98, 0xde, 0xc6, + 0x1d, 0x15, 0x5a, 0x84, 0xa2, 0x6b, 0x90, 0xc2, 0xfe, 0x20, 0xaf, 0xf1, 0xd0, 0x7e, 0x4e, 0x68, + 0x86, 0xa4, 0xc5, 0xdf, 0x6a, 0x90, 0xac, 0x6e, 0x6f, 0x62, 0xdb, 0x43, 0x6b, 0x30, 0x1b, 0xfa, + 0xea, 0x8b, 0x46, 0x79, 0xe8, 0xde, 0x7e, 0x98, 0xaf, 0xc3, 0xec, 0x9e, 0x9f, 0x38, 0x02, 0x18, + 0x59, 0x1b, 0x2f, 0x3c, 0x7e, 0x78, 0xe5, 0xbc, 0x82, 0x09, 0x92, 0xcb, 0x3e, 0xbc, 0xbd, 0x7d, + 0xf3, 0x11, 0x99, 0xdf, 0x81, 0x49, 0x79, 0x54, 0x8a, 0xbe, 0x0d, 0x27, 0x7a, 0xfc, 0x43, 0x88, + 0x9a, 0xbe, 0x3a, 0x3f, 0xd6, 0xe7, 0x05, 0x7d, 0xd4, 0x43, 0x24, 0x5f, 0xf1, 0x67, 0x31, 0x80, + 0xea, 0xf6, 0xf6, 0x96, 0x67, 0xf7, 0x3a, 0x84, 0x7d, 0x59, 0xb2, 0x37, 0xe0, 0x74, 0x28, 0x3b, + 0xf5, 0xcc, 0xa3, 0xcb, 0x7f, 0x32, 0xe0, 0xaf, 0x7b, 0xe6, 0x81, 0xb0, 0x16, 0x65, 0x01, 0x6c, + 0xfc, 0xe8, 0xb0, 0x55, 0xca, 0x46, 0x35, 0xfb, 0x3d, 0x48, 0x87, 0xca, 0xa0, 0xa8, 0x06, 0x53, + 0x4c, 0x7d, 0x2b, 0x05, 0x17, 0xc7, 0x2b, 0xd8, 0x67, 0x1b, 0xaa, 0x5a, 0x3e, 0x7b, 0xf1, 0xdf, + 0x1a, 0x40, 0x24, 0x46, 0xbe, 0x9a, 0x3e, 0x86, 0x6a, 0x90, 0x54, 0xc9, 0x39, 0x7e, 0xdc, 0xe4, + 0xac, 0x00, 0x22, 0x4a, 0xfd, 0x79, 0x0c, 0x4e, 0x36, 0xfc, 0xe8, 0xfd, 0xea, 0xeb, 0xa0, 0x01, + 0x93, 0xc4, 0x61, 0x9e, 0x2d, 0x94, 0xc0, 0x6d, 0xfe, 0xe6, 0x38, 0x9b, 0x1f, 0x20, 0xd4, 0x9a, + 0xc3, 0xbc, 0x41, 0xd4, 0x03, 0x7c, 0xac, 0x88, 0x3e, 0x7e, 0x19, 0x87, 0xfc, 0x38, 0x56, 0xf4, + 0x3a, 0x64, 0x4d, 0x8f, 0x88, 0x09, 0xbf, 0xee, 0x68, 0x22, 0x61, 0xce, 0xf8, 0xd3, 0xaa, 0xec, + 0xe8, 0xc0, 0x6f, 0x96, 0xdc, 0xb9, 0x38, 0xe9, 0xf1, 0xae, 0x92, 0x33, 0x21, 0x82, 0x28, 0x3c, + 0x5b, 0x90, 0xb5, 0x1d, 0x9b, 0xf1, 0x1b, 0x52, 0x13, 0x77, 0xb0, 0x63, 0xfa, 0x57, 0xee, 0x23, + 0xd5, 0xfc, 0x19, 0x85, 0x51, 0x91, 0x10, 0x68, 0x0d, 0x26, 0x7d, 0xb4, 0xc4, 0xd1, 0xd1, 0x7c, + 0x5e, 0x74, 0x01, 0xa6, 0xa3, 0x85, 0x41, 0xdc, 0x46, 0x12, 0x7a, 0x3a, 0x52, 0x17, 0x0e, 0xab, + 0x3c, 0xc9, 0xe7, 0x56, 0x1e, 0x75, 0xe1, 0xfb, 0x55, 0x1c, 0x66, 0x75, 0x62, 0xfd, 0xef, 0x9b, + 0x65, 0x13, 0x40, 0x86, 0x2a, 0xcf, 0xa4, 0xca, 0x32, 0xc7, 0x88, 0xf7, 0x94, 0x04, 0xa9, 0x52, + 0xf6, 0xdf, 0xb2, 0xd0, 0x5f, 0x62, 0x30, 0x1d, 0xb5, 0xd0, 0xff, 0x65, 0xd1, 0x42, 0xeb, 0x61, + 0x9a, 0x4a, 0x88, 0x34, 0x75, 0x69, 0x5c, 0x9a, 0x1a, 0xf1, 0xe6, 0x43, 0xf2, 0xd3, 0x17, 0x71, + 0x48, 0x6e, 0x62, 0x0f, 0x77, 0x29, 0xda, 0x18, 0xb9, 0xdb, 0xfa, 0x6d, 0x8c, 0xfd, 0xce, 0x5c, + 0x55, 0xbd, 0x12, 0xe9, 0xcb, 0x1f, 0x8d, 0xbb, 0xda, 0x7e, 0x0d, 0x66, 0xf8, 0xa3, 0x3e, 0x10, + 0x48, 0x2a, 0x37, 0x23, 0xde, 0xe6, 0x81, 0xf4, 0x14, 0x2d, 0x40, 0x9a, 0x93, 0x85, 0x79, 0x98, + 0xd3, 0x40, 0x17, 0xdf, 0x5d, 0x93, 0x33, 0x68, 0x19, 0xd0, 0x4e, 0xd0, 0x69, 0x31, 0x42, 0x45, + 0x68, 0x4b, 0x99, 0x4a, 0x2c, 0xaf, 0xe9, 0xb3, 0xe1, 0xaa, 0xcf, 0x72, 0x1e, 0x80, 0x9f, 0xc4, + 0xb0, 0x88, 0xe3, 0x76, 0xd5, 0xeb, 0x34, 0xc5, 0x67, 0xaa, 0x7c, 0x02, 0xfd, 0x54, 0x93, 0xd7, + 0xe4, 0x7d, 0xcf, 0x7f, 0xf5, 0x4a, 0xd9, 0x7a, 0x81, 0xc0, 0xf8, 0xd7, 0x93, 0x85, 0xc2, 0x00, + 0x77, 0x3b, 0x2b, 0xc5, 0x03, 0x70, 0x8a, 0x07, 0x75, 0x24, 0xf8, 0xe5, 0x79, 0xb8, 0x7d, 0x80, + 0x6a, 0x90, 0xdb, 0x25, 0x03, 0xc3, 0x73, 0x99, 0x4c, 0x36, 0x2d, 0x42, 0xd4, 0x7b, 0x66, 0xce, + 0xb7, 0x6f, 0x13, 0x53, 0x12, 0xb9, 0xfe, 0xdb, 0x4e, 0x25, 0xc1, 0x4f, 0xa7, 0xcf, 0xec, 0x92, + 0x81, 0xae, 0xf8, 0x6e, 0x10, 0xb2, 0x72, 0x91, 0x47, 0xcb, 0xbd, 0xcf, 0x3e, 0xbe, 0x7c, 0x2e, + 0xbc, 0xb4, 0x97, 0xef, 0x06, 0x8d, 0x3d, 0x69, 0x62, 0x7e, 0xf1, 0x45, 0x61, 0x11, 0xd2, 0x09, + 0xed, 0xf1, 0x37, 0x25, 0x7f, 0x83, 0x44, 0xde, 0x0a, 0xda, 0xf3, 0xdf, 0x20, 0x21, 0xff, 0xd0, + 0x1b, 0x24, 0x12, 0xa2, 0x6f, 0x87, 0x35, 0x20, 0x76, 0x98, 0x34, 0x51, 0xef, 0x54, 0x4c, 0x22, + 0xf2, 0x27, 0x8a, 0x7f, 0xd2, 0x60, 0x6e, 0xc4, 0x9b, 0x83, 0x23, 0x9b, 0x80, 0xbc, 0xc8, 0xa2, + 0xf0, 0x8a, 0x81, 0x3a, 0xfa, 0xf1, 0x82, 0x63, 0xd6, 0x1b, 0x29, 0x04, 0x5f, 0x4e, 0x31, 0x53, + 0x99, 0xec, 0x0f, 0x1a, 0x9c, 0x8a, 0x1e, 0x20, 0x10, 0xa5, 0x0e, 0xd3, 0xd1, 0xad, 0x95, 0x10, + 0x17, 0x5f, 0x44, 0x88, 0xe8, 0xf9, 0x87, 0x40, 0xd0, 0x76, 0x98, 0x31, 0x64, 0x3b, 0x71, 0xf9, + 0x85, 0x95, 0xe2, 0x1f, 0xec, 0xc0, 0xcc, 0x21, 0x6d, 0xf3, 0x85, 0x06, 0x89, 0x4d, 0xd7, 0xed, + 0xa0, 0x9f, 0xc0, 0xac, 0xe3, 0x32, 0x83, 0x47, 0x16, 0xb1, 0x0c, 0xd5, 0x3a, 0x90, 0xd9, 0x78, + 0xed, 0xb9, 0xba, 0xfa, 0xfb, 0x93, 0x85, 0x51, 0xce, 0x61, 0x05, 0xaa, 0x96, 0x9a, 0xe3, 0xb2, + 0x8a, 0x20, 0xda, 0x92, 0xdd, 0x85, 0x16, 0x64, 0x86, 0xb7, 0x93, 0x19, 0xfb, 0xfa, 0x61, 0xdb, + 0x65, 0x0e, 0xdd, 0x6a, 0xba, 0x19, 0xd9, 0x67, 0x65, 0x8a, 0x5b, 0xed, 0x1f, 0xdc, 0x72, 0xef, + 0x43, 0x2e, 0x48, 0x57, 0x0d, 0xd1, 0x8f, 0xa3, 0xe8, 0x06, 0x4c, 0xca, 0xd6, 0x9c, 0xff, 0x58, + 0xb8, 0x10, 0x36, 0x7b, 0x71, 0xd3, 0xb4, 0x4b, 0x7b, 0x91, 0x46, 0xad, 0x64, 0x1a, 0xd2, 0xa7, + 0x62, 0x16, 0xfd, 0xda, 0x47, 0x31, 0x98, 0x5b, 0x75, 0x1d, 0xaa, 0x1a, 0x3d, 0x2a, 0xaa, 0x65, + 0x73, 0x79, 0x80, 0x2e, 0x8d, 0x69, 0x43, 0x4d, 0x8f, 0x36, 0x9b, 0xb6, 0x21, 0xcb, 0x4b, 0xac, + 0xe9, 0x3a, 0x2f, 0xd9, 0x6b, 0xca, 0xb8, 0x1d, 0x4b, 0x9d, 0x68, 0x97, 0x0c, 0x38, 0xae, 0x43, + 0xee, 0x0c, 0xe1, 0xc6, 0x8f, 0x87, 0xeb, 0x90, 0x3b, 0x11, 0xdc, 0x33, 0x90, 0x54, 0xf7, 0xab, + 0x84, 0xb8, 0x3d, 0xa8, 0x11, 0xba, 0x06, 0x71, 0x9e, 0x0a, 0x4f, 0x1c, 0x21, 0x79, 0x70, 0x86, + 0x48, 0x59, 0xab, 0xc3, 0x9c, 0xea, 0x14, 0xd0, 0x8d, 0x96, 0xd0, 0x28, 0x11, 0x02, 0xbd, 0x4b, + 0x06, 0x07, 0xb4, 0x0d, 0xa6, 0x5f, 0xa8, 0x6d, 0x70, 0xf9, 0x77, 0x1a, 0x40, 0xd8, 0x33, 0x43, + 0x6f, 0xc0, 0xd9, 0xca, 0xc6, 0x7a, 0xd5, 0xa8, 0x6f, 0x5d, 0xdf, 0x6a, 0xd4, 0x8d, 0xc6, 0x7a, + 0x7d, 0x73, 0x6d, 0xb5, 0x76, 0xa3, 0xb6, 0x56, 0xcd, 0x4d, 0x14, 0xb2, 0xf7, 0xee, 0x2f, 0xa6, + 0x1b, 0x0e, 0xed, 0x11, 0xd3, 0x6e, 0xd9, 0xc4, 0x42, 0xaf, 0xc1, 0xa9, 0x61, 0x6a, 0x3e, 0x5a, + 0xab, 0xe6, 0xb4, 0xc2, 0xf4, 0xbd, 0xfb, 0x8b, 0x53, 0xf2, 0x8d, 0x40, 0x2c, 0xb4, 0x04, 0xa7, + 0x47, 0xe9, 0x6a, 0xeb, 0x37, 0x73, 0xb1, 0x42, 0xe6, 0xde, 0xfd, 0xc5, 0x54, 0xf0, 0x98, 0x40, + 0x45, 0x40, 0x51, 0x4a, 0x85, 0x17, 0x2f, 0xc0, 0xbd, 0xfb, 0x8b, 0x49, 0x19, 0x32, 0x85, 0xc4, + 0x07, 0xbf, 0x9e, 0x9f, 0xb8, 0xfc, 0x23, 0x80, 0x9a, 0xd3, 0xf2, 0xb0, 0x29, 0x52, 0x43, 0x01, + 0xce, 0xd4, 0xd6, 0x6f, 0xe8, 0xd7, 0x57, 0xb7, 0x6a, 0x1b, 0xeb, 0xc3, 0xc7, 0xde, 0xb7, 0x56, + 0xdd, 0x68, 0x54, 0xde, 0x5b, 0x33, 0xea, 0xb5, 0x9b, 0xeb, 0x39, 0x0d, 0x9d, 0x85, 0x93, 0x43, + 0x6b, 0xdf, 0x5d, 0xdf, 0xaa, 0xdd, 0x5e, 0xcb, 0xc5, 0x2a, 0xd7, 0x3e, 0x79, 0x3a, 0xaf, 0x3d, + 0x7a, 0x3a, 0xaf, 0xfd, 0xed, 0xe9, 0xbc, 0xf6, 0xe1, 0xb3, 0xf9, 0x89, 0x47, 0xcf, 0xe6, 0x27, + 0xfe, 0xfc, 0x6c, 0x7e, 0xe2, 0x07, 0xaf, 0x0c, 0x05, 0x63, 0x58, 0x8e, 0xc4, 0xdf, 0x21, 0xcd, + 0xa4, 0xf0, 0x9a, 0x6f, 0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0x85, 0x67, 0xcc, 0xc5, 0x86, 0x1a, + 0x00, 0x00, } func (this *Pool) Description() (desc *github_com_cosmos_gogoproto_protoc_gen_gogo_descriptor.FileDescriptorSet) { @@ -1523,743 +1593,750 @@ func (this *Pool) Description() (desc *github_com_cosmos_gogoproto_protoc_gen_go func StakingDescription() (desc *github_com_cosmos_gogoproto_protoc_gen_gogo_descriptor.FileDescriptorSet) { d := &github_com_cosmos_gogoproto_protoc_gen_gogo_descriptor.FileDescriptorSet{} var gzipped = []byte{ - // 11763 bytes of a gzipped FileDescriptorSet - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x7b, 0x90, 0x63, 0xd9, - 0x59, 0xdf, 0x5c, 0x49, 0xad, 0x96, 0x3e, 0x49, 0xad, 0xdb, 0xa7, 0x7b, 0x66, 0x34, 0x3d, 0xbb, - 0xd3, 0x3d, 0x77, 0x76, 0x77, 0x66, 0x67, 0x77, 0x7b, 0x76, 0x66, 0x67, 0x67, 0x77, 0xb5, 0x2f, - 0x24, 0xb5, 0x7a, 0x46, 0xb3, 0xfd, 0xf2, 0x95, 0xba, 0xbd, 0xbb, 0x3c, 0x2e, 0xb7, 0xaf, 0x4e, - 0x77, 0xdf, 0x1d, 0xe9, 0x5e, 0x59, 0xf7, 0x6a, 0xa6, 0x7b, 0x53, 0x95, 0x32, 0x01, 0x13, 0xb3, - 0x3c, 0x62, 0x02, 0x01, 0x63, 0x7b, 0x8c, 0x81, 0x80, 0x6d, 0x08, 0x04, 0x62, 0x43, 0x20, 0x54, - 0x1e, 0xa4, 0x12, 0x02, 0xa4, 0x42, 0x1c, 0xaa, 0x92, 0x50, 0x54, 0xb1, 0x01, 0x9b, 0x2a, 0x1c, - 0x6c, 0x08, 0x10, 0x9b, 0xa2, 0xe2, 0x4a, 0x2a, 0x75, 0x5e, 0xf7, 0x21, 0x5d, 0xb5, 0xd4, 0xb3, - 0xbb, 0xc6, 0x81, 0xfc, 0x33, 0xd3, 0xf7, 0x9c, 0xef, 0xfb, 0x9d, 0x73, 0xbe, 0xf3, 0x9d, 0xef, - 0x7c, 0xe7, 0x3b, 0x0f, 0xc1, 0xef, 0x2f, 0xc3, 0xc2, 0xae, 0x6d, 0xef, 0xb6, 0xf0, 0xa5, 0x4e, - 0xd7, 0x76, 0xed, 0xed, 0xde, 0xce, 0xa5, 0x26, 0x76, 0x8c, 0xae, 0xd9, 0x71, 0xed, 0xee, 0x22, - 0x4d, 0x43, 0x79, 0x46, 0xb1, 0x28, 0x28, 0x94, 0x55, 0x98, 0x5e, 0x36, 0x5b, 0x78, 0xc9, 0x23, - 0xac, 0x63, 0x17, 0x3d, 0x0d, 0x89, 0x1d, 0xb3, 0x85, 0x0b, 0xd2, 0x42, 0xfc, 0x42, 0xe6, 0xca, - 0x03, 0x8b, 0x7d, 0x4c, 0x8b, 0x61, 0x8e, 0x0d, 0x92, 0xac, 0x52, 0x0e, 0xe5, 0xff, 0x24, 0x60, - 0x26, 0x22, 0x17, 0x21, 0x48, 0x58, 0x7a, 0x9b, 0x20, 0x4a, 0x17, 0xd2, 0x2a, 0xfd, 0x1b, 0x15, - 0x60, 0xb2, 0xa3, 0x1b, 0xb7, 0xf4, 0x5d, 0x5c, 0x88, 0xd1, 0x64, 0xf1, 0x89, 0xce, 0x00, 0x34, - 0x71, 0x07, 0x5b, 0x4d, 0x6c, 0x19, 0x07, 0x85, 0xf8, 0x42, 0xfc, 0x42, 0x5a, 0x0d, 0xa4, 0xa0, - 0x47, 0x60, 0xba, 0xd3, 0xdb, 0x6e, 0x99, 0x86, 0x16, 0x20, 0x83, 0x85, 0xf8, 0x85, 0x09, 0x55, - 0x66, 0x19, 0x4b, 0x3e, 0xf1, 0x79, 0xc8, 0xdf, 0xc1, 0xfa, 0xad, 0x20, 0x69, 0x86, 0x92, 0x4e, - 0x91, 0xe4, 0x00, 0x61, 0x05, 0xb2, 0x6d, 0xec, 0x38, 0xfa, 0x2e, 0xd6, 0xdc, 0x83, 0x0e, 0x2e, - 0x24, 0x68, 0xeb, 0x17, 0x06, 0x5a, 0xdf, 0xdf, 0xf2, 0x0c, 0xe7, 0x6a, 0x1c, 0x74, 0x30, 0x2a, - 0x41, 0x1a, 0x5b, 0xbd, 0x36, 0x43, 0x98, 0x18, 0x22, 0xbf, 0xaa, 0xd5, 0x6b, 0xf7, 0xa3, 0xa4, - 0x08, 0x1b, 0x87, 0x98, 0x74, 0x70, 0xf7, 0xb6, 0x69, 0xe0, 0x42, 0x92, 0x02, 0x9c, 0x1f, 0x00, - 0xa8, 0xb3, 0xfc, 0x7e, 0x0c, 0xc1, 0x87, 0x2a, 0x90, 0xc6, 0xfb, 0x2e, 0xb6, 0x1c, 0xd3, 0xb6, - 0x0a, 0x93, 0x14, 0xe4, 0xc1, 0x88, 0x5e, 0xc4, 0xad, 0x66, 0x3f, 0x84, 0xcf, 0x87, 0xae, 0xc1, - 0xa4, 0xdd, 0x71, 0x4d, 0xdb, 0x72, 0x0a, 0xa9, 0x05, 0xe9, 0x42, 0xe6, 0xca, 0x7d, 0x91, 0x8a, - 0xb0, 0xce, 0x68, 0x54, 0x41, 0x8c, 0x6a, 0x20, 0x3b, 0x76, 0xaf, 0x6b, 0x60, 0xcd, 0xb0, 0x9b, - 0x58, 0x33, 0xad, 0x1d, 0xbb, 0x90, 0xa6, 0x00, 0xf3, 0x83, 0x0d, 0xa1, 0x84, 0x15, 0xbb, 0x89, - 0x6b, 0xd6, 0x8e, 0xad, 0x4e, 0x39, 0xa1, 0x6f, 0x74, 0x02, 0x92, 0xce, 0x81, 0xe5, 0xea, 0xfb, - 0x85, 0x2c, 0xd5, 0x10, 0xfe, 0x45, 0x54, 0x07, 0x37, 0x4d, 0x52, 0x5c, 0x21, 0xc7, 0x54, 0x87, - 0x7f, 0x2a, 0xbf, 0x94, 0x84, 0xfc, 0x38, 0xca, 0xf7, 0x2c, 0x4c, 0xec, 0x90, 0xf6, 0x17, 0x62, - 0x47, 0x91, 0x0e, 0xe3, 0x09, 0x8b, 0x37, 0x79, 0x8f, 0xe2, 0x2d, 0x41, 0xc6, 0xc2, 0x8e, 0x8b, - 0x9b, 0x4c, 0x57, 0xe2, 0x63, 0x6a, 0x1b, 0x30, 0xa6, 0x41, 0x65, 0x4b, 0xdc, 0x93, 0xb2, 0xbd, - 0x0c, 0x79, 0xaf, 0x4a, 0x5a, 0x57, 0xb7, 0x76, 0x85, 0xd6, 0x5e, 0x1a, 0x55, 0x93, 0xc5, 0xaa, - 0xe0, 0x53, 0x09, 0x9b, 0x3a, 0x85, 0x43, 0xdf, 0x68, 0x09, 0xc0, 0xb6, 0xb0, 0xbd, 0xa3, 0x35, - 0xb1, 0xd1, 0x2a, 0xa4, 0x86, 0x48, 0x69, 0x9d, 0x90, 0x0c, 0x48, 0xc9, 0x66, 0xa9, 0x46, 0x0b, - 0x3d, 0xe3, 0x2b, 0xe1, 0xe4, 0x10, 0x1d, 0x5a, 0x65, 0xc3, 0x6f, 0x40, 0x0f, 0x37, 0x61, 0xaa, - 0x8b, 0xc9, 0x88, 0xc0, 0x4d, 0xde, 0xb2, 0x34, 0xad, 0xc4, 0xe2, 0xc8, 0x96, 0xa9, 0x9c, 0x8d, - 0x35, 0x2c, 0xd7, 0x0d, 0x7e, 0xa2, 0x73, 0xe0, 0x25, 0x68, 0x54, 0xad, 0x80, 0xda, 0xa7, 0xac, - 0x48, 0x5c, 0xd3, 0xdb, 0x78, 0xee, 0x75, 0x98, 0x0a, 0x8b, 0x07, 0xcd, 0xc2, 0x84, 0xe3, 0xea, - 0x5d, 0x97, 0x6a, 0xe1, 0x84, 0xca, 0x3e, 0x90, 0x0c, 0x71, 0x6c, 0x35, 0xa9, 0xfd, 0x9b, 0x50, - 0xc9, 0x9f, 0xe8, 0xeb, 0xfc, 0x06, 0xc7, 0x69, 0x83, 0x1f, 0x1a, 0xec, 0xd1, 0x10, 0x72, 0x7f, - 0xbb, 0xe7, 0x9e, 0x82, 0x5c, 0xa8, 0x01, 0xe3, 0x16, 0xad, 0xfc, 0x74, 0x02, 0x8e, 0x47, 0x62, - 0xa3, 0x97, 0x61, 0xb6, 0x67, 0x99, 0x96, 0x8b, 0xbb, 0x9d, 0x2e, 0x26, 0x2a, 0xcb, 0xca, 0x2a, - 0xfc, 0xe1, 0xe4, 0x10, 0xa5, 0xdb, 0x0c, 0x52, 0x33, 0x14, 0x75, 0xa6, 0x37, 0x98, 0x88, 0x5e, - 0x81, 0x0c, 0xd1, 0x0f, 0xbd, 0xab, 0x53, 0x40, 0x36, 0x1a, 0xaf, 0x8c, 0xd7, 0xe4, 0xc5, 0x25, - 0x9f, 0xb3, 0x1c, 0x7f, 0xbf, 0x14, 0x53, 0x83, 0x58, 0x68, 0x0f, 0xb2, 0xb7, 0x71, 0xd7, 0xdc, - 0x31, 0x0d, 0x86, 0x4d, 0xc4, 0x39, 0x75, 0xe5, 0xe9, 0x31, 0xb1, 0xb7, 0x02, 0xac, 0x75, 0x57, - 0x77, 0x71, 0x11, 0x36, 0xd7, 0xb6, 0xaa, 0x6a, 0x6d, 0xb9, 0x56, 0x5d, 0x52, 0x43, 0xc8, 0x73, - 0x9f, 0x92, 0x20, 0x13, 0xa8, 0x0b, 0x31, 0x5b, 0x56, 0xaf, 0xbd, 0x8d, 0xbb, 0x5c, 0xe2, 0xfc, - 0x0b, 0x9d, 0x86, 0xf4, 0x4e, 0xaf, 0xd5, 0x62, 0x6a, 0xc3, 0xe6, 0xbc, 0x14, 0x49, 0x20, 0x2a, - 0x43, 0xac, 0x14, 0x37, 0x04, 0xd4, 0x4a, 0x91, 0xbf, 0xd1, 0x39, 0xc8, 0x98, 0x8e, 0xd6, 0xc5, - 0x1d, 0xac, 0xbb, 0xb8, 0x59, 0x48, 0x2c, 0x48, 0x17, 0x52, 0xe5, 0x58, 0x41, 0x52, 0xc1, 0x74, - 0x54, 0x9e, 0x8a, 0xe6, 0x20, 0x25, 0x74, 0xaf, 0x30, 0x41, 0x28, 0x54, 0xef, 0x9b, 0xe5, 0x71, - 0xee, 0xa4, 0xc8, 0x63, 0xdf, 0xca, 0x55, 0x98, 0x1e, 0x68, 0x24, 0xca, 0x43, 0x66, 0xa9, 0x5a, - 0x59, 0x29, 0xa9, 0xa5, 0x46, 0x6d, 0x7d, 0x4d, 0x3e, 0x86, 0xa6, 0x20, 0xd0, 0x6e, 0x59, 0xba, - 0x98, 0x4e, 0x7d, 0x7e, 0x52, 0x7e, 0xef, 0x7b, 0xdf, 0xfb, 0xde, 0x98, 0xf2, 0x2b, 0x49, 0x98, - 0x8d, 0xb2, 0x72, 0x91, 0x06, 0xd7, 0x97, 0x49, 0x3c, 0x24, 0x93, 0x12, 0x4c, 0xb4, 0xf4, 0x6d, - 0xdc, 0xa2, 0x8d, 0x9b, 0xba, 0xf2, 0xc8, 0x58, 0x76, 0x74, 0x71, 0x85, 0xb0, 0xa8, 0x8c, 0x13, - 0xbd, 0xc0, 0x25, 0x37, 0x41, 0x11, 0x2e, 0x8e, 0x87, 0x40, 0xac, 0x1f, 0x97, 0xf2, 0x69, 0x48, - 0x93, 0xff, 0x59, 0xb7, 0x24, 0x59, 0xb7, 0x90, 0x04, 0xda, 0x2d, 0x73, 0x90, 0xa2, 0x86, 0xad, - 0x89, 0xbd, 0x2e, 0x13, 0xdf, 0xc4, 0x14, 0x34, 0xf1, 0x8e, 0xde, 0x6b, 0xb9, 0xda, 0x6d, 0xbd, - 0xd5, 0xc3, 0xd4, 0x44, 0xa5, 0xd5, 0x2c, 0x4f, 0xdc, 0x22, 0x69, 0x68, 0x1e, 0x32, 0xcc, 0x0e, - 0x9a, 0x56, 0x13, 0xef, 0xd3, 0x99, 0x70, 0x42, 0x65, 0xa6, 0xb1, 0x46, 0x52, 0x48, 0xf1, 0xaf, - 0x39, 0xb6, 0x25, 0x8c, 0x09, 0x2d, 0x82, 0x24, 0xd0, 0xe2, 0x9f, 0xea, 0x9f, 0x84, 0xef, 0x8f, - 0x6e, 0xde, 0x80, 0xf5, 0x3b, 0x0f, 0x79, 0x4a, 0xf1, 0x04, 0x1f, 0xab, 0x7a, 0xab, 0x30, 0x4d, - 0x15, 0x60, 0x8a, 0x25, 0xaf, 0xf3, 0x54, 0xe5, 0x17, 0x62, 0x90, 0xa0, 0x53, 0x41, 0x1e, 0x32, - 0x8d, 0x57, 0x36, 0xaa, 0xda, 0xd2, 0xfa, 0x66, 0x79, 0xa5, 0x2a, 0x4b, 0xa4, 0xeb, 0x69, 0xc2, - 0xf2, 0xca, 0x7a, 0xa9, 0x21, 0xc7, 0xbc, 0xef, 0xda, 0x5a, 0xe3, 0xda, 0x55, 0x39, 0xee, 0x31, - 0x6c, 0xb2, 0x84, 0x44, 0x90, 0xe0, 0x89, 0x2b, 0xf2, 0x04, 0x92, 0x21, 0xcb, 0x00, 0x6a, 0x2f, - 0x57, 0x97, 0xae, 0x5d, 0x95, 0x93, 0xe1, 0x94, 0x27, 0xae, 0xc8, 0x93, 0x28, 0x07, 0x69, 0x9a, - 0x52, 0x5e, 0x5f, 0x5f, 0x91, 0x53, 0x1e, 0x66, 0xbd, 0xa1, 0xd6, 0xd6, 0xae, 0xcb, 0x69, 0x0f, - 0xf3, 0xba, 0xba, 0xbe, 0xb9, 0x21, 0x83, 0x87, 0xb0, 0x5a, 0xad, 0xd7, 0x4b, 0xd7, 0xab, 0x72, - 0xc6, 0xa3, 0x28, 0xbf, 0xd2, 0xa8, 0xd6, 0xe5, 0x6c, 0xa8, 0x5a, 0x4f, 0x5c, 0x91, 0x73, 0x5e, - 0x11, 0xd5, 0xb5, 0xcd, 0x55, 0x79, 0x0a, 0x4d, 0x43, 0x8e, 0x15, 0x21, 0x2a, 0x91, 0xef, 0x4b, - 0xba, 0x76, 0x55, 0x96, 0xfd, 0x8a, 0x30, 0x94, 0xe9, 0x50, 0xc2, 0xb5, 0xab, 0x32, 0x52, 0x2a, - 0x30, 0x41, 0xd5, 0x10, 0x21, 0x98, 0x5a, 0x29, 0x95, 0xab, 0x2b, 0xda, 0xfa, 0x06, 0x19, 0x34, - 0xa5, 0x15, 0x59, 0xf2, 0xd3, 0xd4, 0xea, 0xbb, 0x36, 0x6b, 0x6a, 0x75, 0x49, 0x8e, 0x05, 0xd3, - 0x36, 0xaa, 0xa5, 0x46, 0x75, 0x49, 0x8e, 0x2b, 0x06, 0xcc, 0x46, 0x4d, 0x81, 0x91, 0x43, 0x28, - 0xa0, 0x0b, 0xb1, 0x21, 0xba, 0x40, 0xb1, 0xfa, 0x75, 0x41, 0xf9, 0x5c, 0x0c, 0x66, 0x22, 0xdc, - 0x80, 0xc8, 0x42, 0x5e, 0x84, 0x09, 0xa6, 0xcb, 0xcc, 0x14, 0x3f, 0x1c, 0xe9, 0x4f, 0x50, 0xcd, - 0x1e, 0x70, 0x8e, 0x28, 0x5f, 0xd0, 0x6d, 0x8c, 0x0f, 0x71, 0x1b, 0x09, 0xc4, 0x80, 0xc2, 0x7e, - 0xe3, 0xc0, 0x74, 0xcd, 0x3c, 0x9a, 0x6b, 0xe3, 0x78, 0x34, 0x34, 0xed, 0x68, 0xd3, 0xf6, 0x44, - 0xc4, 0xb4, 0xfd, 0x2c, 0x4c, 0x0f, 0x00, 0x8d, 0x3d, 0x7d, 0x7e, 0xab, 0x04, 0x85, 0x61, 0xc2, - 0x19, 0x61, 0x12, 0x63, 0x21, 0x93, 0xf8, 0x6c, 0xbf, 0x04, 0xcf, 0x0e, 0xef, 0x84, 0x81, 0xbe, - 0xfe, 0xb8, 0x04, 0x27, 0xa2, 0x97, 0x07, 0x91, 0x75, 0x78, 0x01, 0x92, 0x6d, 0xec, 0xee, 0xd9, - 0xc2, 0x11, 0x7e, 0x28, 0xc2, 0xbd, 0x22, 0xd9, 0xfd, 0x9d, 0xcd, 0xb9, 0x82, 0xfe, 0x59, 0x7c, - 0x98, 0x8f, 0xcf, 0x6a, 0x33, 0x50, 0xd3, 0xef, 0x88, 0xc1, 0xf1, 0x48, 0xf0, 0xc8, 0x8a, 0xde, - 0x0f, 0x60, 0x5a, 0x9d, 0x9e, 0xcb, 0x9c, 0x5d, 0x66, 0x89, 0xd3, 0x34, 0x85, 0x1a, 0x2f, 0x62, - 0x65, 0x7b, 0xae, 0x97, 0xcf, 0x26, 0x51, 0x60, 0x49, 0x94, 0xe0, 0x69, 0xbf, 0xa2, 0x09, 0x5a, - 0xd1, 0x33, 0x43, 0x5a, 0x3a, 0xa0, 0x98, 0x8f, 0x83, 0x6c, 0xb4, 0x4c, 0x6c, 0xb9, 0x9a, 0xe3, - 0x76, 0xb1, 0xde, 0x36, 0xad, 0x5d, 0x36, 0xcf, 0x16, 0x27, 0x76, 0xf4, 0x96, 0x83, 0xd5, 0x3c, - 0xcb, 0xae, 0x8b, 0x5c, 0xc2, 0x41, 0x15, 0xa8, 0x1b, 0xe0, 0x48, 0x86, 0x38, 0x58, 0xb6, 0xc7, - 0xa1, 0x7c, 0x6f, 0x1a, 0x32, 0x81, 0xc5, 0x14, 0x3a, 0x0b, 0xd9, 0xd7, 0xf4, 0xdb, 0xba, 0x26, - 0x16, 0xc8, 0x4c, 0x12, 0x19, 0x92, 0xb6, 0xc1, 0x17, 0xc9, 0x8f, 0xc3, 0x2c, 0x25, 0xb1, 0x7b, - 0x2e, 0xee, 0x6a, 0x46, 0x4b, 0x77, 0x1c, 0x2a, 0xb4, 0x14, 0x25, 0x45, 0x24, 0x6f, 0x9d, 0x64, - 0x55, 0x44, 0x0e, 0x7a, 0x12, 0x66, 0x28, 0x47, 0xbb, 0xd7, 0x72, 0xcd, 0x4e, 0x0b, 0x6b, 0x64, - 0xc9, 0xee, 0xd0, 0x29, 0xc7, 0xab, 0xd9, 0x34, 0xa1, 0x58, 0xe5, 0x04, 0xa4, 0x46, 0x0e, 0x5a, - 0x82, 0xfb, 0x29, 0xdb, 0x2e, 0xb6, 0x70, 0x57, 0x77, 0xb1, 0x86, 0xdf, 0xd3, 0xd3, 0x5b, 0x8e, - 0xa6, 0x5b, 0x4d, 0x6d, 0x4f, 0x77, 0xf6, 0x0a, 0xb3, 0x9e, 0x5b, 0x72, 0x8a, 0x10, 0x5e, 0xe7, - 0x74, 0x55, 0x4a, 0x56, 0xb2, 0x9a, 0x37, 0x74, 0x67, 0x0f, 0x15, 0xe1, 0x04, 0x45, 0x71, 0xdc, - 0xae, 0x69, 0xed, 0x6a, 0xc6, 0x1e, 0x36, 0x6e, 0x69, 0x3d, 0x77, 0xe7, 0xe9, 0xc2, 0xe9, 0x60, - 0xf9, 0xb4, 0x86, 0x75, 0x4a, 0x53, 0x21, 0x24, 0x9b, 0xee, 0xce, 0xd3, 0xa8, 0x0e, 0x59, 0xd2, - 0x19, 0x6d, 0xf3, 0x75, 0xac, 0xed, 0xd8, 0x5d, 0x3a, 0x87, 0x4e, 0x45, 0x98, 0xa6, 0x80, 0x04, - 0x17, 0xd7, 0x39, 0xc3, 0xaa, 0xdd, 0xc4, 0xc5, 0x89, 0xfa, 0x46, 0xb5, 0xba, 0xa4, 0x66, 0x04, - 0xca, 0xb2, 0xdd, 0x25, 0x0a, 0xb5, 0x6b, 0x7b, 0x02, 0xce, 0x30, 0x85, 0xda, 0xb5, 0x85, 0x78, - 0x9f, 0x84, 0x19, 0xc3, 0x60, 0x6d, 0x36, 0x0d, 0x8d, 0x2f, 0xac, 0x9d, 0x82, 0x1c, 0x12, 0x96, - 0x61, 0x5c, 0x67, 0x04, 0x5c, 0xc7, 0x1d, 0xf4, 0x0c, 0x1c, 0xf7, 0x85, 0x15, 0x64, 0x9c, 0x1e, - 0x68, 0x65, 0x3f, 0xeb, 0x93, 0x30, 0xd3, 0x39, 0x18, 0x64, 0x44, 0xa1, 0x12, 0x3b, 0x07, 0xfd, - 0x6c, 0x4f, 0xc1, 0x6c, 0x67, 0xaf, 0x33, 0xc8, 0x77, 0x31, 0xc8, 0x87, 0x3a, 0x7b, 0x9d, 0x7e, - 0xc6, 0x07, 0x69, 0x94, 0xa5, 0x8b, 0x0d, 0xea, 0x1d, 0x9e, 0x0c, 0x92, 0x07, 0x32, 0xd0, 0x22, - 0xc8, 0x86, 0xa1, 0x61, 0x4b, 0xdf, 0x6e, 0x61, 0x4d, 0xef, 0x62, 0x4b, 0x77, 0x0a, 0xf3, 0x94, - 0x38, 0xe1, 0x76, 0x7b, 0x58, 0x9d, 0x32, 0x8c, 0x2a, 0xcd, 0x2c, 0xd1, 0x3c, 0x74, 0x11, 0xa6, - 0xed, 0xed, 0xd7, 0x0c, 0xa6, 0x91, 0x5a, 0xa7, 0x8b, 0x77, 0xcc, 0xfd, 0xc2, 0x03, 0x54, 0xbc, - 0x79, 0x92, 0x41, 0xf5, 0x71, 0x83, 0x26, 0xa3, 0x87, 0x41, 0x36, 0x9c, 0x3d, 0xbd, 0xdb, 0xa1, - 0x26, 0xd9, 0xe9, 0xe8, 0x06, 0x2e, 0x3c, 0xc8, 0x48, 0x59, 0xfa, 0x9a, 0x48, 0x26, 0x23, 0xc2, - 0xb9, 0x63, 0xee, 0xb8, 0x02, 0xf1, 0x3c, 0x1b, 0x11, 0x34, 0x8d, 0xa3, 0x5d, 0x00, 0x99, 0x48, - 0x22, 0x54, 0xf0, 0x05, 0x4a, 0x36, 0xd5, 0xd9, 0xeb, 0x04, 0xcb, 0x3d, 0x07, 0x39, 0x42, 0xe9, - 0x17, 0xfa, 0x30, 0x73, 0xdc, 0x3a, 0x7b, 0x81, 0x12, 0xaf, 0xc2, 0x09, 0x42, 0xd4, 0xc6, 0xae, - 0xde, 0xd4, 0x5d, 0x3d, 0x40, 0xfd, 0x28, 0xa5, 0x26, 0x62, 0x5f, 0xe5, 0x99, 0xa1, 0x7a, 0x76, - 0x7b, 0xdb, 0x07, 0x9e, 0x62, 0x3d, 0xc6, 0xea, 0x49, 0xd2, 0x84, 0x6a, 0xbd, 0x63, 0xab, 0x29, - 0xa5, 0x08, 0xd9, 0xa0, 0xde, 0xa3, 0x34, 0x30, 0xcd, 0x97, 0x25, 0xe2, 0x04, 0x55, 0xd6, 0x97, - 0x88, 0xfb, 0xf2, 0x6a, 0x55, 0x8e, 0x11, 0x37, 0x6a, 0xa5, 0xd6, 0xa8, 0x6a, 0xea, 0xe6, 0x5a, - 0xa3, 0xb6, 0x5a, 0x95, 0xe3, 0x01, 0xc7, 0xfe, 0x66, 0x22, 0xf5, 0x90, 0x7c, 0x5e, 0xf9, 0xe5, - 0x38, 0x4c, 0x85, 0xd7, 0xd6, 0xe8, 0x39, 0x38, 0x29, 0x42, 0x64, 0x0e, 0x76, 0xb5, 0x3b, 0x66, - 0x97, 0x0e, 0xc8, 0xb6, 0xce, 0x26, 0x47, 0x4f, 0x7f, 0x66, 0x39, 0x55, 0x1d, 0xbb, 0xef, 0x36, - 0xbb, 0x64, 0xb8, 0xb5, 0x75, 0x17, 0xad, 0xc0, 0xbc, 0x65, 0x6b, 0x8e, 0xab, 0x5b, 0x4d, 0xbd, - 0xdb, 0xd4, 0xfc, 0xe0, 0xa4, 0xa6, 0x1b, 0x06, 0x76, 0x1c, 0x9b, 0x4d, 0x84, 0x1e, 0xca, 0x7d, - 0x96, 0x5d, 0xe7, 0xc4, 0xfe, 0x0c, 0x51, 0xe2, 0xa4, 0x7d, 0xea, 0x1b, 0x1f, 0xa6, 0xbe, 0xa7, - 0x21, 0xdd, 0xd6, 0x3b, 0x1a, 0xb6, 0xdc, 0xee, 0x01, 0xf5, 0xcf, 0x53, 0x6a, 0xaa, 0xad, 0x77, - 0xaa, 0xe4, 0x1b, 0x6d, 0xc1, 0x43, 0x3e, 0xa9, 0xd6, 0xc2, 0xbb, 0xba, 0x71, 0xa0, 0x51, 0x67, - 0x9c, 0x06, 0x7a, 0x34, 0xc3, 0xb6, 0x76, 0x5a, 0xa6, 0xe1, 0x3a, 0xd4, 0x3e, 0x30, 0x1b, 0xa7, - 0xf8, 0x1c, 0x2b, 0x94, 0xe1, 0xa6, 0x63, 0x5b, 0xd4, 0x07, 0xaf, 0x08, 0xea, 0x77, 0xae, 0x87, - 0xc3, 0xbd, 0x94, 0x90, 0x27, 0x6e, 0x26, 0x52, 0x13, 0x72, 0xf2, 0x66, 0x22, 0x95, 0x94, 0x27, - 0x6f, 0x26, 0x52, 0x29, 0x39, 0x7d, 0x33, 0x91, 0x4a, 0xcb, 0xa0, 0xbc, 0x2f, 0x0d, 0xd9, 0xe0, - 0xca, 0x80, 0x2c, 0xb4, 0x0c, 0x3a, 0x37, 0x4a, 0xd4, 0x7a, 0x9e, 0x3b, 0x74, 0x1d, 0xb1, 0x58, - 0x21, 0x93, 0x66, 0x31, 0xc9, 0xdc, 0x70, 0x95, 0x71, 0x12, 0x87, 0x85, 0xa8, 0x35, 0x66, 0x6e, - 0x4f, 0x4a, 0xe5, 0x5f, 0xe8, 0x3a, 0x24, 0x5f, 0x73, 0x28, 0x76, 0x92, 0x62, 0x3f, 0x70, 0x38, - 0xf6, 0xcd, 0x3a, 0x05, 0x4f, 0xdf, 0xac, 0x6b, 0x6b, 0xeb, 0xea, 0x6a, 0x69, 0x45, 0xe5, 0xec, - 0xe8, 0x14, 0x24, 0x5a, 0xfa, 0xeb, 0x07, 0xe1, 0xe9, 0x95, 0x26, 0xa1, 0x45, 0xc8, 0xf7, 0x2c, - 0xb6, 0xea, 0x26, 0x5d, 0x45, 0xa8, 0xf2, 0x41, 0xaa, 0x29, 0x3f, 0x77, 0x85, 0xd0, 0x8f, 0xa9, - 0x1e, 0xa7, 0x20, 0x71, 0x07, 0xeb, 0xb7, 0xc2, 0x93, 0x20, 0x4d, 0x42, 0x17, 0x20, 0xdb, 0xc4, - 0xdb, 0xbd, 0x5d, 0xad, 0x8b, 0x9b, 0xba, 0xe1, 0x86, 0x4d, 0x7f, 0x86, 0x66, 0xa9, 0x34, 0x07, - 0xbd, 0x04, 0x69, 0xd2, 0x47, 0x16, 0xed, 0xe3, 0x69, 0x2a, 0x82, 0xc7, 0x0e, 0x17, 0x01, 0xef, - 0x62, 0xc1, 0xa4, 0xfa, 0xfc, 0xe8, 0x26, 0x24, 0x5d, 0xbd, 0xbb, 0x8b, 0x5d, 0x6a, 0xf9, 0xa7, - 0x22, 0xc2, 0x55, 0x11, 0x48, 0x0d, 0xca, 0x41, 0xc4, 0x4a, 0x75, 0x94, 0x23, 0xa0, 0x1b, 0x30, - 0xc9, 0xfe, 0x72, 0x0a, 0x33, 0x0b, 0xf1, 0xa3, 0x83, 0xa9, 0x82, 0xfd, 0x1d, 0xb4, 0x59, 0x97, - 0x60, 0x82, 0x2a, 0x1b, 0x02, 0xe0, 0xea, 0x26, 0x1f, 0x43, 0x29, 0x48, 0x54, 0xd6, 0x55, 0x62, - 0xb7, 0x64, 0xc8, 0xb2, 0x54, 0x6d, 0xa3, 0x56, 0xad, 0x54, 0xe5, 0x98, 0xf2, 0x24, 0x24, 0x99, - 0x06, 0x11, 0x9b, 0xe6, 0xe9, 0x90, 0x7c, 0x8c, 0x7f, 0x72, 0x0c, 0x49, 0xe4, 0x6e, 0xae, 0x96, - 0xab, 0xaa, 0x1c, 0x53, 0x36, 0x21, 0xdf, 0x27, 0x75, 0x74, 0x1c, 0xa6, 0xd5, 0x6a, 0xa3, 0xba, - 0x46, 0x56, 0x6d, 0xda, 0xe6, 0xda, 0x4b, 0x6b, 0xeb, 0xef, 0x5e, 0x93, 0x8f, 0x85, 0x93, 0x85, - 0x81, 0x94, 0xd0, 0x2c, 0xc8, 0x7e, 0x72, 0x7d, 0x7d, 0x53, 0xa5, 0xb5, 0xf9, 0xae, 0x18, 0xc8, - 0xfd, 0x62, 0x43, 0x27, 0x61, 0xa6, 0x51, 0x52, 0xaf, 0x57, 0x1b, 0x1a, 0x5b, 0x89, 0x7a, 0xd0, - 0xb3, 0x20, 0x07, 0x33, 0x96, 0x6b, 0x74, 0xa1, 0x3d, 0x0f, 0xa7, 0x83, 0xa9, 0xd5, 0x97, 0x1b, - 0xd5, 0xb5, 0x3a, 0x2d, 0xbc, 0xb4, 0x76, 0x9d, 0x58, 0xeb, 0x3e, 0x3c, 0xb1, 0xf6, 0x8d, 0x93, - 0xaa, 0x86, 0xf1, 0xaa, 0x2b, 0x4b, 0x72, 0xa2, 0x3f, 0x79, 0x7d, 0xad, 0xba, 0xbe, 0x2c, 0x4f, - 0xf4, 0x97, 0x4e, 0xd7, 0xc3, 0x49, 0x34, 0x07, 0x27, 0xfa, 0x53, 0xb5, 0xea, 0x5a, 0x43, 0x7d, - 0x45, 0x9e, 0xec, 0x2f, 0xb8, 0x5e, 0x55, 0xb7, 0x6a, 0x95, 0xaa, 0x9c, 0x42, 0x27, 0x00, 0x85, - 0x6b, 0xd4, 0xb8, 0xb1, 0xbe, 0x24, 0xa7, 0x07, 0xec, 0x93, 0xe2, 0x40, 0x36, 0xb8, 0x28, 0xfd, - 0xaa, 0x98, 0x46, 0xe5, 0x83, 0x31, 0xc8, 0x04, 0x16, 0x99, 0x64, 0x75, 0xa0, 0xb7, 0x5a, 0xf6, - 0x1d, 0x4d, 0x6f, 0x99, 0xba, 0xc3, 0xad, 0x17, 0xd0, 0xa4, 0x12, 0x49, 0x19, 0xd7, 0x5a, 0x8c, - 0x3f, 0x5f, 0x24, 0xbf, 0x16, 0xe7, 0x8b, 0x09, 0x39, 0xa9, 0x7c, 0x54, 0x02, 0xb9, 0x7f, 0xf5, - 0xd8, 0xd7, 0x7c, 0x69, 0x58, 0xf3, 0xbf, 0x2a, 0x7d, 0xf7, 0x11, 0x09, 0xa6, 0xc2, 0x4b, 0xc6, - 0xbe, 0xea, 0x9d, 0xfd, 0x2b, 0xad, 0xde, 0xef, 0xc5, 0x20, 0x17, 0x5a, 0x28, 0x8e, 0x5b, 0xbb, - 0xf7, 0xc0, 0xb4, 0xd9, 0xc4, 0xed, 0x8e, 0xed, 0x62, 0xcb, 0x38, 0xd0, 0x5a, 0xf8, 0x36, 0x6e, - 0x15, 0x14, 0x6a, 0xe2, 0x2f, 0x1d, 0xbe, 0x14, 0x5d, 0xac, 0xf9, 0x7c, 0x2b, 0x84, 0xad, 0x38, - 0x53, 0x5b, 0xaa, 0xae, 0x6e, 0xac, 0x37, 0xaa, 0x6b, 0x95, 0x57, 0x84, 0x75, 0x51, 0x65, 0xb3, - 0x8f, 0xec, 0x1d, 0x34, 0xda, 0x1b, 0x20, 0xf7, 0x57, 0x8a, 0xd8, 0x8a, 0x88, 0x6a, 0xc9, 0xc7, - 0xd0, 0x0c, 0xe4, 0xd7, 0xd6, 0xb5, 0x7a, 0x6d, 0xa9, 0xaa, 0x55, 0x97, 0x97, 0xab, 0x95, 0x46, - 0x9d, 0x05, 0x17, 0x3d, 0xea, 0x86, 0x1c, 0x0b, 0x8a, 0xf8, 0x43, 0x71, 0x98, 0x89, 0xa8, 0x09, - 0x2a, 0xf1, 0xb0, 0x00, 0x8b, 0x54, 0x3c, 0x36, 0x4e, 0xed, 0x17, 0x89, 0x63, 0xbe, 0xa1, 0x77, - 0x5d, 0x1e, 0x45, 0x78, 0x18, 0x88, 0x94, 0x2c, 0x97, 0xf8, 0x09, 0x5d, 0x1e, 0xb4, 0x65, 0xb1, - 0x82, 0xbc, 0x9f, 0xce, 0xe2, 0xb6, 0x8f, 0x02, 0xea, 0xd8, 0x8e, 0xe9, 0x9a, 0xb7, 0xb1, 0x66, - 0x5a, 0x22, 0xc2, 0x9b, 0x58, 0x90, 0x2e, 0x24, 0x54, 0x59, 0xe4, 0xd4, 0x2c, 0xd7, 0xa3, 0xb6, - 0xf0, 0xae, 0xde, 0x47, 0x4d, 0xfc, 0x98, 0xb8, 0x2a, 0x8b, 0x1c, 0x8f, 0xfa, 0x2c, 0x64, 0x9b, - 0x76, 0x8f, 0x2c, 0xa8, 0x18, 0x1d, 0xb1, 0x16, 0x92, 0x9a, 0x61, 0x69, 0x1e, 0x09, 0x5f, 0x2a, - 0xfb, 0xa1, 0xe5, 0xac, 0x9a, 0x61, 0x69, 0x8c, 0xe4, 0x3c, 0xe4, 0xf5, 0xdd, 0xdd, 0x2e, 0x01, - 0x17, 0x40, 0x6c, 0xf1, 0x3f, 0xe5, 0x25, 0x53, 0xc2, 0xb9, 0x9b, 0x90, 0x12, 0x72, 0x20, 0xfe, - 0x30, 0x91, 0x84, 0xd6, 0x61, 0x11, 0xad, 0xd8, 0x85, 0xb4, 0x9a, 0xb2, 0x44, 0xe6, 0x59, 0xc8, - 0x9a, 0x8e, 0xe6, 0xef, 0x6d, 0xc6, 0x16, 0x62, 0x17, 0x52, 0x6a, 0xc6, 0x74, 0xbc, 0x3d, 0x12, - 0xe5, 0xe3, 0x31, 0x98, 0x0a, 0xef, 0xda, 0xa2, 0x25, 0x48, 0xb5, 0x6c, 0xbe, 0xc9, 0xc2, 0x8e, - 0x0c, 0x5c, 0x18, 0xb1, 0xd1, 0xbb, 0xb8, 0xc2, 0xe9, 0x55, 0x8f, 0x73, 0xee, 0x37, 0x25, 0x48, - 0x89, 0x64, 0x74, 0x02, 0x12, 0x1d, 0xdd, 0xdd, 0xa3, 0x70, 0x13, 0xe5, 0x98, 0x2c, 0xa9, 0xf4, - 0x9b, 0xa4, 0x3b, 0x1d, 0x9d, 0xed, 0x13, 0xf1, 0x74, 0xf2, 0x4d, 0xfa, 0xb5, 0x85, 0xf5, 0x26, - 0x8d, 0x2c, 0xd8, 0xed, 0x36, 0xb6, 0x5c, 0x47, 0xf4, 0x2b, 0x4f, 0xaf, 0xf0, 0x64, 0xf4, 0x08, - 0x4c, 0xbb, 0x5d, 0xdd, 0x6c, 0x85, 0x68, 0x13, 0x94, 0x56, 0x16, 0x19, 0x1e, 0x71, 0x11, 0x4e, - 0x09, 0xdc, 0x26, 0x76, 0x75, 0x63, 0x0f, 0x37, 0x7d, 0xa6, 0x24, 0x8d, 0x20, 0x9e, 0xe4, 0x04, - 0x4b, 0x3c, 0x5f, 0xf0, 0x2a, 0x9f, 0x89, 0xc1, 0xb4, 0x88, 0x85, 0x34, 0x3d, 0x61, 0xad, 0x02, - 0xe8, 0x96, 0x65, 0xbb, 0x41, 0x71, 0x0d, 0xaa, 0xf2, 0x00, 0xdf, 0x62, 0xc9, 0x63, 0x52, 0x03, - 0x00, 0x73, 0x5f, 0x90, 0x00, 0xfc, 0xac, 0xa1, 0x72, 0x9b, 0x87, 0x0c, 0xdf, 0x93, 0xa7, 0x07, - 0x3b, 0x58, 0xf8, 0x0c, 0x58, 0xd2, 0xb2, 0xd9, 0xa2, 0x41, 0xce, 0x6d, 0xbc, 0x6b, 0x5a, 0x7c, - 0x77, 0x86, 0x7d, 0x88, 0x20, 0x67, 0xc2, 0xdf, 0x9e, 0x54, 0x21, 0xe5, 0xe0, 0xb6, 0x6e, 0xb9, - 0xa6, 0xc1, 0xf7, 0x5b, 0xae, 0x1d, 0xa9, 0xf2, 0x8b, 0x75, 0xce, 0xad, 0x7a, 0x38, 0xca, 0x05, - 0x48, 0x89, 0x54, 0xe2, 0xf8, 0xad, 0xad, 0xaf, 0x55, 0xe5, 0x63, 0x68, 0x12, 0xe2, 0xf5, 0x6a, - 0x43, 0x96, 0xc8, 0x22, 0xb6, 0xb4, 0x52, 0x2b, 0xd5, 0xe5, 0x58, 0xf9, 0x6f, 0xc3, 0x8c, 0x61, - 0xb7, 0xfb, 0x0b, 0x2c, 0xcb, 0x7d, 0x01, 0x44, 0xe7, 0x86, 0xf4, 0xea, 0x63, 0x9c, 0x68, 0xd7, - 0x6e, 0xe9, 0xd6, 0xee, 0xa2, 0xdd, 0xdd, 0xf5, 0x8f, 0xc5, 0x90, 0xb5, 0x86, 0x13, 0x38, 0x1c, - 0xd3, 0xd9, 0xfe, 0x4b, 0x49, 0xfa, 0xd1, 0x58, 0xfc, 0xfa, 0x46, 0xf9, 0x27, 0x63, 0x73, 0xd7, - 0x19, 0xe3, 0x86, 0x68, 0x8e, 0x8a, 0x77, 0x5a, 0xd8, 0x20, 0x95, 0x87, 0x3f, 0x7e, 0x04, 0x66, - 0x77, 0xed, 0x5d, 0x9b, 0x22, 0x5d, 0x22, 0x7f, 0xf1, 0x73, 0x35, 0x69, 0x2f, 0x75, 0x6e, 0xe4, - 0x21, 0x9c, 0xe2, 0x1a, 0xcc, 0x70, 0x62, 0x8d, 0x6e, 0xdf, 0xb3, 0x50, 0x05, 0x3a, 0x34, 0x4e, - 0x5e, 0xf8, 0xb9, 0x3f, 0xa0, 0x5e, 0x89, 0x3a, 0xcd, 0x59, 0x49, 0x1e, 0x8b, 0x66, 0x14, 0x55, - 0x38, 0x1e, 0xc2, 0x63, 0x36, 0x02, 0x77, 0x47, 0x20, 0xfe, 0x5b, 0x8e, 0x38, 0x13, 0x40, 0xac, - 0x73, 0xd6, 0x62, 0x05, 0x72, 0x47, 0xc1, 0xfa, 0x55, 0x8e, 0x95, 0xc5, 0x41, 0x90, 0xeb, 0x90, - 0xa7, 0x20, 0x46, 0xcf, 0x71, 0xed, 0x36, 0x35, 0xc0, 0x87, 0xc3, 0xfc, 0xbb, 0x3f, 0x60, 0x83, - 0x76, 0x8a, 0xb0, 0x55, 0x3c, 0xae, 0x62, 0x11, 0xe8, 0x89, 0x85, 0x26, 0x36, 0x5a, 0x23, 0x10, - 0x7e, 0x8d, 0x57, 0xc4, 0xa3, 0x2f, 0x6e, 0xc1, 0x2c, 0xf9, 0x9b, 0xda, 0xc7, 0x60, 0x4d, 0x46, - 0x07, 0xd5, 0x0b, 0xff, 0xe9, 0x5b, 0x99, 0x5d, 0x98, 0xf1, 0x00, 0x02, 0x75, 0x0a, 0xf4, 0xe2, - 0x2e, 0x76, 0x5d, 0xdc, 0x75, 0x34, 0xbd, 0x15, 0x55, 0xbd, 0x40, 0x54, 0xb2, 0xf0, 0x43, 0x5f, - 0x0c, 0xf7, 0xe2, 0x75, 0xc6, 0x59, 0x6a, 0xb5, 0x8a, 0x9b, 0x70, 0x32, 0x42, 0x2b, 0xc6, 0xc0, - 0xfc, 0x10, 0xc7, 0x9c, 0x1d, 0xd0, 0x0c, 0x02, 0xbb, 0x01, 0x22, 0xdd, 0xeb, 0xcb, 0x31, 0x30, - 0x3f, 0xcc, 0x31, 0x11, 0xe7, 0x15, 0x5d, 0x4a, 0x10, 0x6f, 0xc2, 0xf4, 0x6d, 0xdc, 0xdd, 0xb6, - 0x1d, 0x1e, 0x09, 0x1e, 0x03, 0xee, 0x23, 0x1c, 0x2e, 0xcf, 0x19, 0x69, 0x68, 0x98, 0x60, 0x3d, - 0x03, 0xa9, 0x1d, 0xdd, 0xc0, 0x63, 0x40, 0xdc, 0xe5, 0x10, 0x93, 0x84, 0x9e, 0xb0, 0x96, 0x20, - 0xbb, 0x6b, 0xf3, 0x29, 0x72, 0x34, 0xfb, 0x47, 0x39, 0x7b, 0x46, 0xf0, 0x70, 0x88, 0x8e, 0xdd, - 0xe9, 0xb5, 0xc8, 0xfc, 0x39, 0x1a, 0xe2, 0x87, 0x05, 0x84, 0xe0, 0xe1, 0x10, 0x47, 0x10, 0xeb, - 0xc7, 0x04, 0x84, 0x13, 0x90, 0xe7, 0x8b, 0x90, 0xb1, 0xad, 0xd6, 0x81, 0x6d, 0x8d, 0x53, 0x89, - 0x1f, 0xe1, 0x08, 0xc0, 0x59, 0x08, 0xc0, 0xb3, 0x90, 0x1e, 0xb7, 0x23, 0x7e, 0xfc, 0x8b, 0x62, - 0x78, 0x88, 0x1e, 0xb8, 0x0e, 0x79, 0x61, 0xa0, 0x4c, 0xdb, 0x1a, 0x03, 0xe2, 0x27, 0x38, 0xc4, - 0x54, 0x80, 0x8d, 0x37, 0xc3, 0xc5, 0x8e, 0xbb, 0x8b, 0xc7, 0x01, 0xf9, 0xb8, 0x68, 0x06, 0x67, - 0xe1, 0xa2, 0xdc, 0xc6, 0x96, 0xb1, 0x37, 0x1e, 0xc2, 0x27, 0x84, 0x28, 0x05, 0x0f, 0x81, 0xa8, - 0x40, 0xae, 0xad, 0x77, 0x9d, 0x3d, 0xbd, 0x35, 0x56, 0x77, 0x7c, 0x92, 0x63, 0x64, 0x3d, 0x26, - 0x2e, 0x91, 0x9e, 0x75, 0x14, 0x98, 0x9f, 0x14, 0x12, 0x09, 0xb0, 0xf1, 0xa1, 0xe7, 0xb8, 0x34, - 0x6c, 0x7e, 0x14, 0xb4, 0x9f, 0x12, 0x43, 0x8f, 0xf1, 0xae, 0x06, 0x11, 0x9f, 0x85, 0xb4, 0x63, - 0xbe, 0x3e, 0x16, 0xcc, 0x3f, 0x12, 0x3d, 0x4d, 0x19, 0x08, 0xf3, 0x2b, 0x70, 0x2a, 0x72, 0x9a, - 0x18, 0x03, 0xec, 0xa7, 0x39, 0xd8, 0x89, 0x88, 0xa9, 0x82, 0x9b, 0x84, 0xa3, 0x42, 0xfe, 0x8c, - 0x30, 0x09, 0xb8, 0x0f, 0x6b, 0x83, 0x2c, 0x5a, 0x1c, 0x7d, 0xe7, 0x68, 0x52, 0xfb, 0xc7, 0x42, - 0x6a, 0x8c, 0x37, 0x24, 0xb5, 0x06, 0x9c, 0xe0, 0x88, 0x47, 0xeb, 0xd7, 0x9f, 0x15, 0x86, 0x95, - 0x71, 0x6f, 0x86, 0x7b, 0xf7, 0xeb, 0x61, 0xce, 0x13, 0xa7, 0xf0, 0x8e, 0x1d, 0xad, 0xad, 0x77, - 0xc6, 0x40, 0xfe, 0x39, 0x8e, 0x2c, 0x2c, 0xbe, 0xe7, 0x5e, 0x3b, 0xab, 0x7a, 0x87, 0x80, 0xbf, - 0x0c, 0x05, 0x01, 0xde, 0xb3, 0xba, 0xd8, 0xb0, 0x77, 0x2d, 0xf3, 0x75, 0xdc, 0x1c, 0x03, 0xfa, - 0x9f, 0xf4, 0x75, 0xd5, 0x66, 0x80, 0x9d, 0x20, 0xd7, 0x40, 0xf6, 0x7c, 0x15, 0xcd, 0x6c, 0x77, - 0xec, 0xae, 0x3b, 0x02, 0xf1, 0x53, 0xa2, 0xa7, 0x3c, 0xbe, 0x1a, 0x65, 0x2b, 0x56, 0x81, 0x9d, - 0x25, 0x19, 0x57, 0x25, 0x3f, 0xcd, 0x81, 0x72, 0x3e, 0x17, 0x37, 0x1c, 0x86, 0xdd, 0xee, 0xe8, - 0xdd, 0x71, 0xec, 0xdf, 0xcf, 0x0b, 0xc3, 0xc1, 0x59, 0xb8, 0xe1, 0x20, 0x1e, 0x1d, 0x99, 0xed, - 0xc7, 0x40, 0xf8, 0x05, 0x61, 0x38, 0x04, 0x0f, 0x87, 0x10, 0x0e, 0xc3, 0x18, 0x10, 0xff, 0x54, - 0x40, 0x08, 0x1e, 0x02, 0xf1, 0x2e, 0x7f, 0xa2, 0xed, 0xe2, 0x5d, 0xd3, 0x71, 0xf9, 0x61, 0xb0, - 0xc3, 0xa1, 0x7e, 0xf1, 0x8b, 0x61, 0x27, 0x4c, 0x0d, 0xb0, 0x12, 0x4b, 0xc4, 0x37, 0x52, 0xe8, - 0x92, 0x6d, 0x74, 0xc5, 0x7e, 0x49, 0x58, 0xa2, 0x00, 0x1b, 0xa9, 0x5b, 0xc0, 0x43, 0x24, 0x62, - 0x37, 0xc8, 0x42, 0x65, 0x0c, 0xb8, 0x7f, 0xd6, 0x57, 0xb9, 0xba, 0xe0, 0x25, 0x98, 0x01, 0xff, - 0xa7, 0x67, 0xdd, 0xc2, 0x07, 0x63, 0x69, 0xe7, 0x2f, 0xf7, 0xf9, 0x3f, 0x9b, 0x8c, 0x93, 0xd9, - 0x90, 0x7c, 0x9f, 0x3f, 0x85, 0x46, 0x9d, 0xf5, 0x2c, 0x7c, 0xcb, 0x97, 0x78, 0x7b, 0xc3, 0xee, - 0x54, 0x71, 0x85, 0x28, 0x79, 0xd8, 0xe9, 0x19, 0x0d, 0xf6, 0xad, 0x5f, 0xf2, 0xf4, 0x3c, 0xe4, - 0xf3, 0x14, 0x97, 0x21, 0x17, 0x72, 0x78, 0x46, 0x43, 0x7d, 0x1b, 0x87, 0xca, 0x06, 0xfd, 0x9d, - 0xe2, 0x93, 0x90, 0x20, 0xce, 0xcb, 0x68, 0xf6, 0xf7, 0x71, 0x76, 0x4a, 0x5e, 0x7c, 0x1e, 0x52, - 0xc2, 0x69, 0x19, 0xcd, 0xfa, 0xed, 0x9c, 0xd5, 0x63, 0x21, 0xec, 0xc2, 0x61, 0x19, 0xcd, 0xfe, - 0x77, 0x05, 0xbb, 0x60, 0x21, 0xec, 0xe3, 0x8b, 0xf0, 0x5f, 0x7d, 0x67, 0x82, 0x4f, 0x3a, 0x42, - 0x76, 0xcf, 0xc2, 0x24, 0xf7, 0x54, 0x46, 0x73, 0x7f, 0x07, 0x2f, 0x5c, 0x70, 0x14, 0x9f, 0x82, - 0x89, 0x31, 0x05, 0xfe, 0xdd, 0x9c, 0x95, 0xd1, 0x17, 0x2b, 0x90, 0x09, 0x78, 0x27, 0xa3, 0xd9, - 0xbf, 0x87, 0xb3, 0x07, 0xb9, 0x48, 0xd5, 0xb9, 0x77, 0x32, 0x1a, 0xe0, 0xef, 0x89, 0xaa, 0x73, - 0x0e, 0x22, 0x36, 0xe1, 0x98, 0x8c, 0xe6, 0xfe, 0x80, 0x90, 0xba, 0x60, 0x29, 0xbe, 0x08, 0x69, - 0x6f, 0xb2, 0x19, 0xcd, 0xff, 0xbd, 0x9c, 0xdf, 0xe7, 0x21, 0x12, 0x08, 0x4c, 0x76, 0xa3, 0x21, - 0xfe, 0xbe, 0x90, 0x40, 0x80, 0x8b, 0x0c, 0xa3, 0x7e, 0x07, 0x66, 0x34, 0xd2, 0xf7, 0x89, 0x61, - 0xd4, 0xe7, 0xbf, 0x90, 0xde, 0xa4, 0x36, 0x7f, 0x34, 0xc4, 0xf7, 0x8b, 0xde, 0xa4, 0xf4, 0xa4, - 0x1a, 0xfd, 0x1e, 0xc1, 0x68, 0x8c, 0x1f, 0x14, 0xd5, 0xe8, 0x73, 0x08, 0x8a, 0x1b, 0x80, 0x06, - 0xbd, 0x81, 0xd1, 0x78, 0x1f, 0xe4, 0x78, 0xd3, 0x03, 0xce, 0x40, 0xf1, 0xdd, 0x70, 0x22, 0xda, - 0x13, 0x18, 0x8d, 0xfa, 0x43, 0x5f, 0xea, 0x5b, 0xbb, 0x05, 0x1d, 0x81, 0x62, 0xc3, 0x9f, 0x52, - 0x82, 0x5e, 0xc0, 0x68, 0xd8, 0x0f, 0x7d, 0x29, 0x6c, 0xb8, 0x83, 0x4e, 0x40, 0xb1, 0x04, 0xe0, - 0x4f, 0xc0, 0xa3, 0xb1, 0x3e, 0xc2, 0xb1, 0x02, 0x4c, 0x64, 0x68, 0xf0, 0xf9, 0x77, 0x34, 0xff, - 0x5d, 0x31, 0x34, 0x38, 0x07, 0x19, 0x1a, 0x62, 0xea, 0x1d, 0xcd, 0xfd, 0x51, 0x31, 0x34, 0x04, - 0x0b, 0xd1, 0xec, 0xc0, 0xec, 0x36, 0x1a, 0xe1, 0x47, 0x84, 0x66, 0x07, 0xb8, 0x8a, 0x6b, 0x30, - 0x3d, 0x30, 0x21, 0x8e, 0x86, 0xfa, 0x51, 0x0e, 0x25, 0xf7, 0xcf, 0x87, 0xc1, 0xc9, 0x8b, 0x4f, - 0x86, 0xa3, 0xd1, 0x7e, 0xac, 0x6f, 0xf2, 0xe2, 0x73, 0x61, 0xf1, 0x59, 0x48, 0x59, 0xbd, 0x56, - 0x8b, 0x0c, 0x1e, 0x74, 0xf8, 0x69, 0xdf, 0xc2, 0x7f, 0xff, 0x0a, 0x97, 0x8e, 0x60, 0x28, 0x3e, - 0x09, 0x13, 0xb8, 0xbd, 0x8d, 0x9b, 0xa3, 0x38, 0xff, 0xe8, 0x2b, 0xc2, 0x60, 0x12, 0xea, 0xe2, - 0x8b, 0x00, 0x2c, 0x34, 0x42, 0xb7, 0xe1, 0x47, 0xf0, 0x7e, 0xe1, 0x2b, 0xfc, 0x78, 0x9d, 0xcf, - 0xe2, 0x03, 0xb0, 0xc3, 0x7a, 0x87, 0x03, 0x7c, 0x31, 0x0c, 0x40, 0x7b, 0xe4, 0x19, 0x98, 0x7c, - 0xcd, 0xb1, 0x2d, 0x57, 0xdf, 0x1d, 0xc5, 0xfd, 0xc7, 0x9c, 0x5b, 0xd0, 0x13, 0x81, 0xb5, 0xed, - 0x2e, 0x76, 0xf5, 0x5d, 0x67, 0x14, 0xef, 0x9f, 0x70, 0x5e, 0x8f, 0x81, 0x30, 0x1b, 0xba, 0xe3, - 0x8e, 0xd3, 0xee, 0xff, 0x21, 0x98, 0x05, 0x03, 0xa9, 0x34, 0xf9, 0xfb, 0x16, 0x3e, 0x18, 0xc5, - 0xfb, 0xa7, 0xa2, 0xd2, 0x9c, 0xbe, 0xf8, 0x3c, 0xa4, 0xc9, 0x9f, 0xec, 0xcc, 0xec, 0x08, 0xe6, - 0x3f, 0xe3, 0xcc, 0x3e, 0x07, 0x29, 0xd9, 0x71, 0x9b, 0xae, 0x39, 0x5a, 0xd8, 0x7f, 0xce, 0x7b, - 0x5a, 0xd0, 0x17, 0x4b, 0x90, 0x71, 0xdc, 0x66, 0xb3, 0xc7, 0xfd, 0xd3, 0x11, 0xec, 0xff, 0xf3, - 0x2b, 0x5e, 0xc8, 0xc2, 0xe3, 0x21, 0xbd, 0x7d, 0xe7, 0x96, 0xdb, 0xb1, 0xe9, 0x7e, 0xcb, 0x28, - 0x84, 0x2f, 0x71, 0x84, 0x00, 0x4b, 0xb1, 0x02, 0x59, 0xd2, 0x16, 0x71, 0x17, 0x61, 0x14, 0xc4, - 0x97, 0xb9, 0x00, 0x42, 0x4c, 0xe5, 0x6f, 0xfe, 0xb5, 0xcf, 0x9e, 0x91, 0x3e, 0xf3, 0xd9, 0x33, - 0xd2, 0xef, 0x7d, 0xf6, 0x8c, 0xf4, 0x81, 0xcf, 0x9d, 0x39, 0xf6, 0x99, 0xcf, 0x9d, 0x39, 0xf6, - 0xdb, 0x9f, 0x3b, 0x73, 0x2c, 0x3a, 0x4a, 0x0c, 0xd7, 0xed, 0xeb, 0x36, 0x8b, 0x0f, 0xbf, 0xfa, - 0xe0, 0xae, 0xe9, 0xee, 0xf5, 0xb6, 0x17, 0x0d, 0xbb, 0x7d, 0xc9, 0xb0, 0x9d, 0xb6, 0xed, 0x5c, - 0x0a, 0xc7, 0x75, 0xe9, 0x5f, 0xf0, 0xbf, 0x25, 0xb2, 0x66, 0x0e, 0x87, 0x73, 0x75, 0xeb, 0x60, - 0xd8, 0x65, 0xca, 0x6b, 0x10, 0x2f, 0x59, 0x07, 0xe8, 0x14, 0x33, 0x70, 0x5a, 0xaf, 0xdb, 0xe2, - 0x07, 0x37, 0x27, 0xc9, 0xf7, 0x66, 0xb7, 0x85, 0x66, 0xfd, 0xd3, 0xd5, 0xd2, 0x85, 0x2c, 0x3f, - 0x32, 0x5d, 0xfe, 0x1e, 0xe9, 0x68, 0x2d, 0x49, 0x95, 0xac, 0x03, 0xda, 0x90, 0x0d, 0xe9, 0xd5, - 0x47, 0x47, 0xc6, 0xb9, 0x6f, 0x59, 0xf6, 0x1d, 0x8b, 0x54, 0xbb, 0xb3, 0x2d, 0x62, 0xdc, 0x67, - 0xfa, 0x63, 0xdc, 0xef, 0xc6, 0xad, 0xd6, 0x4b, 0x84, 0xae, 0x41, 0x58, 0xb6, 0x93, 0xec, 0x8e, - 0x00, 0x7c, 0x5f, 0x0c, 0xce, 0x0c, 0x84, 0xb3, 0xb9, 0x12, 0x0c, 0x13, 0x42, 0x11, 0x52, 0x4b, - 0x42, 0xb7, 0x0a, 0x30, 0xe9, 0x60, 0xc3, 0xb6, 0x9a, 0x0e, 0x15, 0x44, 0x5c, 0x15, 0x9f, 0x44, - 0x10, 0x96, 0x6e, 0xd9, 0x0e, 0x3f, 0xfa, 0xcc, 0x3e, 0xca, 0x1f, 0x3e, 0xa2, 0x20, 0x72, 0xa2, - 0x24, 0x21, 0x8d, 0xcb, 0x63, 0x4a, 0x43, 0x34, 0x22, 0x14, 0xf9, 0x1f, 0x57, 0x2a, 0x3f, 0x18, - 0x83, 0xf9, 0x7e, 0xa9, 0x90, 0x91, 0xe5, 0xb8, 0x7a, 0xbb, 0x33, 0x4c, 0x2c, 0xcf, 0x42, 0xba, - 0x21, 0x68, 0x8e, 0x2c, 0x97, 0xbb, 0x47, 0x94, 0xcb, 0x94, 0x57, 0x94, 0x10, 0xcc, 0x95, 0x31, - 0x05, 0xe3, 0xb5, 0xe3, 0x9e, 0x24, 0xf3, 0xe1, 0x34, 0x9c, 0x62, 0xc3, 0x49, 0x63, 0x43, 0x89, - 0x7d, 0x70, 0x99, 0x64, 0x83, 0x59, 0xa3, 0xf7, 0x49, 0x94, 0x97, 0x60, 0xa6, 0x46, 0xac, 0x05, - 0x59, 0x05, 0xf9, 0x3b, 0x3c, 0x91, 0xa7, 0xc3, 0x17, 0x42, 0x0e, 0x3f, 0xdf, 0xdf, 0x0a, 0x26, - 0x29, 0xdf, 0x22, 0x81, 0x5c, 0x37, 0xf4, 0x96, 0xde, 0x7d, 0xab, 0x50, 0xe8, 0x29, 0x00, 0x76, - 0xdc, 0xc3, 0xbb, 0xb8, 0x39, 0x75, 0xa5, 0xb0, 0x18, 0x6c, 0xdc, 0x22, 0x2b, 0x89, 0x1e, 0xa1, - 0x4a, 0x53, 0x5a, 0xf2, 0xe7, 0xc5, 0x97, 0x01, 0xfc, 0x0c, 0x74, 0x1a, 0x4e, 0xd6, 0x2b, 0xa5, - 0x95, 0x92, 0x2a, 0x0e, 0x09, 0xd5, 0x37, 0xaa, 0x15, 0x76, 0xcd, 0xea, 0x18, 0x3a, 0x01, 0x28, - 0x98, 0xe9, 0x1d, 0x6a, 0x3a, 0x0e, 0xd3, 0xc1, 0x74, 0x76, 0xe7, 0x25, 0x56, 0xbc, 0x01, 0x79, - 0x76, 0x20, 0x5f, 0xd3, 0x9b, 0x4d, 0xdc, 0xd4, 0x4c, 0x0b, 0x8d, 0x38, 0xdf, 0x5e, 0xf8, 0xf5, - 0xff, 0x32, 0x41, 0x9b, 0x96, 0x63, 0x8c, 0x25, 0xc2, 0x57, 0xb3, 0x88, 0xcf, 0x69, 0xb6, 0x3b, - 0x2d, 0x4c, 0xf7, 0x30, 0x35, 0x53, 0xc8, 0x7f, 0xb4, 0x3b, 0x43, 0xf0, 0xe2, 0x17, 0xd2, 0xea, - 0x8c, 0xcf, 0xee, 0xf5, 0x5e, 0xf1, 0x25, 0x90, 0xc5, 0xc1, 0x51, 0xaf, 0x82, 0x23, 0x11, 0x7f, - 0x83, 0xd7, 0x50, 0x44, 0x33, 0x44, 0x15, 0x57, 0x60, 0x5a, 0x37, 0x0c, 0xdc, 0x09, 0xd5, 0x6f, - 0xc4, 0x0c, 0x22, 0x5a, 0x2b, 0x73, 0x4e, 0xbf, 0x6a, 0x4f, 0x41, 0xd2, 0xa1, 0x9d, 0x32, 0x0a, - 0x42, 0x54, 0x87, 0x93, 0x17, 0xab, 0x30, 0xc5, 0xd4, 0xc0, 0x6b, 0xd1, 0x08, 0x80, 0x7f, 0xcf, - 0x01, 0xb2, 0x94, 0x4d, 0xb4, 0xc6, 0x82, 0x69, 0x76, 0x6b, 0x11, 0x07, 0x5a, 0x73, 0x78, 0x14, - 0xe5, 0x9f, 0x7f, 0xea, 0x71, 0xba, 0x6f, 0x7c, 0x36, 0xac, 0x74, 0x11, 0x83, 0x45, 0x95, 0x39, - 0xb6, 0xdf, 0x5e, 0x0c, 0x53, 0xa2, 0x3c, 0xde, 0xee, 0xc3, 0x0b, 0xfb, 0x17, 0xbc, 0xb0, 0x33, - 0x51, 0x1a, 0x1e, 0x28, 0x29, 0xc7, 0x51, 0x59, 0x46, 0xb1, 0x0c, 0xb9, 0x1d, 0xb3, 0x15, 0xe8, - 0xee, 0xc3, 0x4b, 0xf9, 0x97, 0x9f, 0x7a, 0x9c, 0x0d, 0x34, 0xc2, 0xc4, 0x45, 0x53, 0xae, 0x0e, - 0xb3, 0x7a, 0xaf, 0x3e, 0x32, 0x38, 0x7f, 0xb3, 0xff, 0x1e, 0xa3, 0xe8, 0xcf, 0x06, 0xab, 0xea, - 0x5b, 0xa7, 0x04, 0x4c, 0xeb, 0x6d, 0xd3, 0xb2, 0x2f, 0xd1, 0x7f, 0xb9, 0x55, 0x9a, 0xa0, 0x1f, - 0x63, 0x6c, 0xdb, 0x5e, 0x63, 0xc6, 0x62, 0xb4, 0xde, 0xfe, 0xd9, 0x77, 0xfd, 0xc4, 0x84, 0x6f, - 0x50, 0x8a, 0xab, 0xbe, 0xee, 0x63, 0xcb, 0xb0, 0x9b, 0x63, 0xc5, 0x71, 0xfe, 0x5c, 0x60, 0x88, - 0x08, 0x60, 0x95, 0xb3, 0x16, 0x9f, 0x83, 0x94, 0x07, 0x33, 0xca, 0x77, 0x13, 0x20, 0x1e, 0x07, - 0xf1, 0xdc, 0x98, 0xd2, 0x8e, 0xe3, 0xa7, 0x7f, 0x49, 0xf0, 0x33, 0x1b, 0xb6, 0x46, 0x5a, 0x73, - 0x1d, 0xa6, 0x9a, 0xb6, 0xe5, 0x6a, 0x76, 0xdb, 0x74, 0x71, 0xbb, 0xe3, 0x8e, 0xf4, 0x7c, 0xbf, - 0xcc, 0x40, 0x52, 0x6a, 0x8e, 0xf0, 0xad, 0x0b, 0x36, 0x52, 0x13, 0x76, 0x2f, 0x72, 0x9c, 0x9a, - 0xfc, 0x85, 0x57, 0x13, 0xca, 0x43, 0x6a, 0x72, 0x4f, 0xda, 0xe1, 0x34, 0x6f, 0xf1, 0xe9, 0xce, - 0xdd, 0x67, 0x5a, 0xe0, 0x69, 0xc7, 0xc7, 0xe3, 0x70, 0x86, 0x13, 0x6f, 0xeb, 0x0e, 0xbe, 0x74, - 0xfb, 0xf2, 0x36, 0x76, 0xf5, 0xcb, 0x97, 0x0c, 0xdb, 0x14, 0xbe, 0xce, 0x0c, 0x9f, 0xce, 0x48, - 0xfe, 0x22, 0xcf, 0x9f, 0x8b, 0x3c, 0x10, 0x30, 0x37, 0x7c, 0x1a, 0x9c, 0x1b, 0xd4, 0x41, 0xa5, - 0x05, 0x89, 0x8a, 0x6d, 0x5a, 0x64, 0xf6, 0x6f, 0x62, 0xcb, 0x6e, 0xf3, 0x09, 0x89, 0x7d, 0xa0, - 0x1b, 0x90, 0xd4, 0xdb, 0x76, 0xcf, 0x72, 0xd9, 0x64, 0x54, 0x7e, 0xfc, 0xd7, 0xde, 0x9c, 0x3f, - 0xf6, 0x3b, 0x6f, 0xce, 0x1f, 0x67, 0xb0, 0x4e, 0xf3, 0xd6, 0xa2, 0x69, 0x5f, 0x6a, 0xeb, 0xee, - 0x1e, 0x31, 0x01, 0xbf, 0xf5, 0xe9, 0xc7, 0x80, 0x97, 0x57, 0xb3, 0xdc, 0x4f, 0xfc, 0xe1, 0xcf, - 0x5e, 0x94, 0x54, 0xce, 0x5f, 0x4c, 0x7c, 0xfe, 0x63, 0xf3, 0x92, 0xd2, 0x81, 0xc9, 0x25, 0x6c, - 0x1c, 0x52, 0x60, 0xad, 0xaf, 0xc0, 0xcb, 0xbc, 0xc0, 0xd3, 0x83, 0x05, 0xb2, 0x23, 0x8d, 0x4b, - 0xd8, 0x08, 0x14, 0xbb, 0x84, 0x8d, 0x70, 0x89, 0xe5, 0xa5, 0xdf, 0xfe, 0xfd, 0x33, 0xc7, 0xde, - 0xfb, 0xd9, 0x33, 0xc7, 0x86, 0x76, 0x99, 0x32, 0xba, 0xcb, 0xbc, 0x9e, 0xfa, 0x64, 0x82, 0xf4, - 0x54, 0x1b, 0xbb, 0xdb, 0x3b, 0xee, 0x25, 0xa3, 0x7b, 0xd0, 0x71, 0xed, 0x4b, 0xb7, 0x2f, 0x93, - 0x91, 0x6b, 0xef, 0xf0, 0x9e, 0x42, 0x22, 0x7f, 0x91, 0xe5, 0x2f, 0xde, 0x1e, 0xd2, 0x51, 0xca, - 0x0e, 0x4c, 0x6c, 0x10, 0x46, 0x22, 0x0a, 0xd7, 0x76, 0xf5, 0x16, 0xf7, 0xc8, 0xd8, 0x07, 0x49, - 0x65, 0xf7, 0x76, 0x63, 0x2c, 0xd5, 0x14, 0x57, 0x76, 0x5b, 0x58, 0xdf, 0x61, 0xd7, 0x9f, 0xe2, - 0xd4, 0x95, 0x4f, 0x91, 0x04, 0x7a, 0xd3, 0x69, 0x16, 0x26, 0xf4, 0x1e, 0x3b, 0x54, 0x14, 0x27, - 0x3e, 0x3e, 0xfd, 0x50, 0x56, 0x60, 0x92, 0x9f, 0x2d, 0x40, 0x32, 0xc4, 0x6f, 0xe1, 0x03, 0x5a, - 0x4e, 0x56, 0x25, 0x7f, 0xa2, 0x4b, 0x30, 0x41, 0x6b, 0xcf, 0xef, 0x75, 0x9e, 0x5a, 0x1c, 0xac, - 0xfe, 0x22, 0xad, 0xa5, 0xca, 0xe8, 0x94, 0x9b, 0x90, 0x5a, 0xb2, 0x89, 0x02, 0x85, 0xe1, 0xd2, - 0x0c, 0x8e, 0x56, 0xba, 0xd3, 0xe3, 0xdd, 0xa7, 0xb2, 0x0f, 0x74, 0x02, 0x92, 0xec, 0x3e, 0x1c, - 0x3f, 0x19, 0xc5, 0xbf, 0x94, 0x0a, 0x4c, 0x52, 0xec, 0xf5, 0x8e, 0x77, 0x07, 0x5d, 0x0a, 0xdc, - 0x41, 0xe7, 0xf0, 0x31, 0xbf, 0xb6, 0x08, 0x12, 0x4d, 0xdd, 0xd5, 0x79, 0xc3, 0xe9, 0xdf, 0xca, - 0x8b, 0x90, 0xe2, 0x20, 0x0e, 0x7a, 0x02, 0xe2, 0x76, 0xc7, 0xe1, 0x67, 0x9b, 0x4e, 0x0f, 0x6d, - 0xcb, 0x7a, 0xa7, 0x9c, 0x20, 0x8a, 0xa5, 0x12, 0xea, 0xf2, 0xea, 0x50, 0xd5, 0x78, 0x22, 0xa4, - 0x1a, 0xa2, 0xdb, 0xc5, 0x1f, 0x7a, 0xc7, 0xbc, 0x34, 0xa8, 0x0c, 0x9e, 0xae, 0xfc, 0x2f, 0x09, - 0xee, 0x8f, 0xd0, 0x95, 0x5b, 0xf8, 0xc0, 0x39, 0xb2, 0xaa, 0xbc, 0x0c, 0xe9, 0x0d, 0xfa, 0xba, - 0xcc, 0x4b, 0xf8, 0x00, 0xcd, 0xc1, 0x24, 0x6e, 0x5e, 0x79, 0xf2, 0xc9, 0xcb, 0xcf, 0xb0, 0x8e, - 0xbc, 0x71, 0x4c, 0x15, 0x09, 0xe8, 0x0c, 0xa4, 0x1d, 0x6c, 0x74, 0xae, 0x3c, 0x79, 0xed, 0xd6, - 0x65, 0x26, 0xb8, 0x1b, 0xc7, 0x54, 0x3f, 0xa9, 0x98, 0x22, 0x83, 0xe2, 0xf3, 0x3f, 0x32, 0x2f, - 0x95, 0x27, 0x20, 0xee, 0xf4, 0xda, 0xef, 0x54, 0xe3, 0xff, 0x22, 0x09, 0x67, 0xbd, 0x6c, 0x66, - 0xf6, 0x6e, 0x5f, 0xbe, 0x74, 0x5b, 0x6f, 0x99, 0x4d, 0xdd, 0x7f, 0x13, 0x68, 0xda, 0x13, 0x00, - 0x25, 0x19, 0xda, 0xfe, 0xb9, 0xc3, 0x05, 0xa9, 0x7c, 0x5a, 0x82, 0xec, 0x96, 0xc0, 0xae, 0x63, - 0x17, 0x3d, 0x07, 0xe0, 0x95, 0x25, 0xd4, 0xe1, 0xbe, 0xc5, 0x81, 0xd2, 0x16, 0x3d, 0x26, 0x35, - 0x40, 0x8f, 0x9e, 0x86, 0x54, 0xa7, 0x6b, 0x77, 0x6c, 0x87, 0xdf, 0x8f, 0x1d, 0xc5, 0xeb, 0x51, - 0xa3, 0x47, 0x01, 0xd1, 0xc1, 0xab, 0xdd, 0xb6, 0x5d, 0xd3, 0xda, 0xd5, 0x3a, 0xf6, 0x1d, 0xfe, - 0xec, 0x40, 0x5c, 0x95, 0x69, 0xce, 0x16, 0xcd, 0xd8, 0x20, 0xe9, 0xca, 0xa7, 0x24, 0x48, 0x7b, - 0x28, 0x64, 0x65, 0xa6, 0x37, 0x9b, 0x5d, 0xec, 0x38, 0x7c, 0x7c, 0x8a, 0x4f, 0xf4, 0x1c, 0x4c, - 0x76, 0x7a, 0xdb, 0x9a, 0x18, 0x0b, 0x99, 0x2b, 0xf7, 0x47, 0x6a, 0xb6, 0x50, 0x10, 0xae, 0xdb, - 0xc9, 0x4e, 0x6f, 0x9b, 0xa8, 0xcb, 0x59, 0xc8, 0x46, 0xd4, 0x26, 0x73, 0xdb, 0xaf, 0x08, 0x7d, - 0xd5, 0x88, 0x37, 0x41, 0xeb, 0x74, 0x4d, 0xbb, 0x6b, 0xba, 0x07, 0xf4, 0xe8, 0x5d, 0x5c, 0x95, - 0x45, 0xc6, 0x06, 0x4f, 0x57, 0x5a, 0x90, 0xaf, 0x53, 0x47, 0xdb, 0xaf, 0xfa, 0x35, 0xbf, 0x82, - 0xd2, 0x18, 0x15, 0x1c, 0x5a, 0xb5, 0xd8, 0x40, 0xd5, 0x2e, 0xfe, 0x57, 0x09, 0x32, 0xe5, 0x96, - 0x6d, 0xdc, 0xaa, 0x2d, 0x2d, 0xb7, 0xf4, 0x5d, 0x74, 0x19, 0x8e, 0x97, 0x57, 0xd6, 0x2b, 0x2f, - 0x69, 0xb5, 0x25, 0x6d, 0x79, 0xa5, 0x74, 0xdd, 0x3f, 0xec, 0x3b, 0x77, 0xe2, 0x8d, 0xbb, 0x0b, - 0x28, 0x40, 0xbb, 0x69, 0xd1, 0x85, 0x25, 0xba, 0x04, 0xb3, 0x61, 0x96, 0x52, 0xb9, 0x5e, 0x5d, - 0x6b, 0xc8, 0xd2, 0xdc, 0xf1, 0x37, 0xee, 0x2e, 0x4c, 0x07, 0x38, 0x4a, 0xdb, 0x0e, 0xb6, 0xdc, - 0x41, 0x86, 0xca, 0xfa, 0xea, 0x6a, 0xad, 0x21, 0xc7, 0x06, 0x18, 0x2a, 0x76, 0xbb, 0x6d, 0xba, - 0xe8, 0x61, 0x98, 0x0e, 0x33, 0xac, 0xd5, 0x56, 0xe4, 0xf8, 0x1c, 0x7a, 0xe3, 0xee, 0xc2, 0x54, - 0x80, 0x7a, 0xcd, 0x6c, 0xcd, 0xa5, 0xde, 0xff, 0x63, 0x67, 0x8e, 0x7d, 0xe2, 0x1f, 0x9e, 0x91, - 0xca, 0x2b, 0x43, 0x47, 0xde, 0x95, 0xf1, 0x47, 0x9e, 0x18, 0x5a, 0xde, 0xc0, 0xfb, 0x68, 0x0c, - 0xe6, 0xbd, 0xdc, 0xdb, 0xb8, 0xeb, 0x98, 0xb6, 0x45, 0x46, 0x0b, 0x53, 0x5b, 0xcf, 0x99, 0xe0, - 0x9d, 0xc3, 0x09, 0x86, 0x1b, 0x9e, 0xe7, 0x21, 0x5e, 0xea, 0x74, 0xd0, 0x1c, 0x1d, 0x11, 0xae, - 0x6d, 0xd8, 0x6c, 0x92, 0x4a, 0xa8, 0xde, 0x37, 0xc9, 0x73, 0xec, 0x1d, 0xf7, 0x8e, 0xde, 0xf5, - 0x9e, 0xa9, 0x10, 0xdf, 0xca, 0x33, 0x90, 0xae, 0xd8, 0x96, 0x83, 0x2d, 0xa7, 0x47, 0x03, 0x0c, - 0xdb, 0x44, 0x18, 0x1c, 0x81, 0x7d, 0x10, 0x23, 0xaf, 0x77, 0x3a, 0x94, 0x33, 0xa1, 0x92, 0x3f, - 0xf9, 0xc4, 0xbd, 0x36, 0x54, 0x3c, 0x57, 0xc7, 0x17, 0x8f, 0x2f, 0x00, 0x4f, 0x40, 0xdf, 0x7f, - 0x7f, 0xc0, 0x2c, 0x7b, 0x96, 0x29, 0x28, 0x9e, 0x08, 0xab, 0x34, 0x62, 0xd2, 0x9f, 0x1b, 0x6d, - 0xeb, 0xe6, 0x46, 0xf5, 0xca, 0x10, 0xcb, 0x37, 0x2a, 0xdc, 0xa3, 0x3c, 0x03, 0xb9, 0x0d, 0xbd, - 0xeb, 0xd6, 0xb1, 0x7b, 0x03, 0xeb, 0x4d, 0xdc, 0x0d, 0x7b, 0x13, 0x39, 0xe1, 0x4d, 0x20, 0x48, - 0x50, 0x97, 0x81, 0x4d, 0xa6, 0xf4, 0x6f, 0xc5, 0x84, 0x04, 0x3d, 0x7b, 0xed, 0x79, 0x1a, 0x9c, - 0x83, 0x79, 0x1a, 0xa4, 0xbb, 0x0e, 0x5c, 0xec, 0x88, 0x80, 0x21, 0xfd, 0x40, 0x4f, 0x0a, 0x7f, - 0x21, 0x3e, 0xc2, 0x5f, 0xe0, 0x56, 0x88, 0x7b, 0x0d, 0x6d, 0x98, 0xe4, 0x03, 0xc1, 0xab, 0x89, - 0xe4, 0xd7, 0x04, 0xad, 0x41, 0xbe, 0xa3, 0x77, 0x5d, 0x7a, 0xb5, 0x73, 0x8f, 0x36, 0x83, 0x5b, - 0xba, 0x85, 0x08, 0xc3, 0x1b, 0x6a, 0x2e, 0x2f, 0x26, 0xd7, 0x09, 0x26, 0x2a, 0x9f, 0x4f, 0x40, - 0x92, 0x8b, 0xe3, 0x05, 0x98, 0xe4, 0x02, 0xe7, 0xb6, 0xe9, 0xcc, 0x62, 0x84, 0xfa, 0x2f, 0x7a, - 0x6a, 0xca, 0x01, 0x05, 0x13, 0x7a, 0x08, 0x52, 0xc6, 0x9e, 0x6e, 0x5a, 0x9a, 0xd9, 0xe4, 0x3e, - 0x69, 0xe6, 0xb3, 0x6f, 0xce, 0x4f, 0x56, 0x48, 0x5a, 0x6d, 0x49, 0x9d, 0xa4, 0x99, 0xb5, 0x26, - 0xf1, 0x71, 0xf6, 0xb0, 0xb9, 0xbb, 0xe7, 0x72, 0x03, 0xcb, 0xbf, 0xd0, 0xd3, 0x90, 0x20, 0x5d, - 0xc6, 0xaf, 0xfe, 0xcf, 0x0d, 0x2c, 0x36, 0xbc, 0x78, 0x59, 0x39, 0x45, 0x0a, 0xfe, 0xc0, 0x7f, - 0x9b, 0x97, 0x54, 0xca, 0x81, 0x96, 0x20, 0xd7, 0xd2, 0x1d, 0x57, 0xa3, 0xe3, 0x84, 0x14, 0x3f, - 0xc1, 0x21, 0x06, 0x45, 0xc2, 0x65, 0xcb, 0xeb, 0x9e, 0x21, 0x6c, 0x2c, 0xa9, 0x89, 0x2e, 0x80, - 0x4c, 0x51, 0x0c, 0x6a, 0xaa, 0x98, 0xdf, 0x98, 0xa4, 0xa2, 0x9f, 0x22, 0xe9, 0xcc, 0x82, 0x51, - 0xef, 0xf1, 0x34, 0xa4, 0xe9, 0x6d, 0x63, 0x4a, 0xc2, 0x0e, 0xfd, 0xa7, 0x48, 0x02, 0xcd, 0x3c, - 0x0f, 0x79, 0x7f, 0x86, 0x64, 0x24, 0x29, 0x86, 0xe2, 0x27, 0x53, 0xc2, 0xc7, 0x61, 0xd6, 0xc2, - 0xfb, 0xf4, 0x1a, 0x42, 0x88, 0x3a, 0x4d, 0xa9, 0x11, 0xc9, 0xdb, 0x0a, 0x73, 0x3c, 0x08, 0x53, - 0x86, 0x90, 0x3e, 0xa3, 0x05, 0x4a, 0x9b, 0xf3, 0x52, 0x29, 0xd9, 0x29, 0x48, 0xe9, 0x9d, 0x0e, - 0x23, 0xc8, 0xf0, 0x09, 0xb2, 0xd3, 0xa1, 0x59, 0x17, 0x61, 0x9a, 0xb6, 0xb1, 0x8b, 0x9d, 0x5e, - 0xcb, 0xe5, 0x20, 0x59, 0x4a, 0x93, 0x27, 0x19, 0x2a, 0x4b, 0xa7, 0xb4, 0xe7, 0x20, 0x87, 0x6f, - 0x9b, 0x4d, 0x6c, 0x19, 0x98, 0xd1, 0xe5, 0x28, 0x5d, 0x56, 0x24, 0x52, 0xa2, 0x87, 0xc1, 0x9b, - 0xf7, 0x34, 0x31, 0x29, 0x4f, 0x31, 0x3c, 0x91, 0x5e, 0x62, 0xc9, 0x4a, 0x01, 0x12, 0x4b, 0xba, - 0xab, 0x13, 0x3b, 0xe6, 0xee, 0x33, 0x5f, 0x23, 0xab, 0x92, 0x3f, 0x95, 0x5f, 0x8a, 0x43, 0x62, - 0xcb, 0x76, 0x31, 0xba, 0x1a, 0xf0, 0x6d, 0xa7, 0x22, 0x55, 0xba, 0x6e, 0xee, 0x5a, 0xb8, 0xb9, - 0xea, 0xec, 0x06, 0xde, 0x06, 0xf2, 0x15, 0x2a, 0x16, 0x52, 0xa8, 0x59, 0x98, 0xe8, 0xda, 0x3d, - 0xab, 0x29, 0xce, 0xcb, 0xd3, 0x0f, 0xb4, 0x0c, 0x29, 0x4f, 0x4f, 0x12, 0x23, 0xf5, 0x24, 0x4f, - 0xf4, 0x84, 0xa8, 0x31, 0x4f, 0x50, 0x27, 0xb7, 0xb9, 0xba, 0x94, 0x21, 0xed, 0x59, 0x18, 0x4f, - 0xe1, 0xc6, 0xd1, 0x59, 0x9f, 0x8d, 0xb8, 0x13, 0x5e, 0xef, 0x7b, 0xe2, 0x63, 0x3a, 0x27, 0x7b, - 0x19, 0x5c, 0x7e, 0x21, 0xc5, 0xe2, 0x0f, 0x15, 0x4d, 0xd2, 0x86, 0xf9, 0x8a, 0xc5, 0x1e, 0x2b, - 0xba, 0x0f, 0xd2, 0x8e, 0xb9, 0x6b, 0xe9, 0x6e, 0xaf, 0x8b, 0xb9, 0xee, 0xf9, 0x09, 0x24, 0xd7, - 0xbf, 0x3c, 0xc2, 0x74, 0x2d, 0xf0, 0xe2, 0xdd, 0x25, 0x98, 0xf1, 0xdf, 0x9a, 0xf3, 0x51, 0x98, - 0x9e, 0x21, 0x2f, 0xab, 0x2e, 0x72, 0x94, 0x7f, 0x2d, 0x41, 0x92, 0x4f, 0xee, 0x7e, 0x3f, 0x48, - 0xd1, 0xfd, 0x10, 0x1b, 0xd6, 0x0f, 0xf1, 0xb7, 0xd4, 0x0f, 0xe0, 0xd5, 0xd3, 0xe1, 0xef, 0xd1, - 0x44, 0x79, 0xa1, 0xac, 0x92, 0x75, 0x73, 0x97, 0x8f, 0xfd, 0x00, 0x97, 0xf2, 0xa6, 0x44, 0xa6, - 0x5f, 0x9e, 0x8f, 0xca, 0x90, 0x13, 0x35, 0xd3, 0x76, 0x5a, 0xfa, 0x2e, 0x57, 0xc7, 0x33, 0xc3, - 0xab, 0x47, 0x7c, 0x16, 0x35, 0xc3, 0x6b, 0x44, 0xbd, 0xaf, 0xc8, 0x9e, 0x8d, 0x0d, 0xe9, 0xd9, - 0x90, 0x2a, 0xc5, 0xef, 0x4d, 0x95, 0x42, 0x9d, 0x9e, 0xe8, 0xeb, 0x74, 0xe5, 0x73, 0x12, 0x7f, - 0xec, 0xae, 0xc9, 0x2e, 0xbf, 0xfc, 0x95, 0xf5, 0xd6, 0xd7, 0x73, 0xfd, 0x6a, 0xe2, 0xa6, 0x36, - 0xd0, 0x6d, 0x0f, 0x44, 0x40, 0x86, 0x6b, 0xed, 0x77, 0x1f, 0x12, 0x30, 0x75, 0xbf, 0x1b, 0x7f, - 0x3e, 0x06, 0xd3, 0x03, 0xf4, 0x7f, 0x0d, 0xbb, 0x33, 0x3c, 0x86, 0x27, 0xc6, 0x1c, 0xc3, 0xc9, - 0xa1, 0x63, 0xf8, 0xe7, 0x63, 0x34, 0x32, 0xd0, 0xb1, 0x1d, 0xbd, 0xf5, 0x55, 0xb1, 0xc1, 0xa7, - 0x21, 0xdd, 0xb1, 0x5b, 0x1a, 0xcb, 0x61, 0x37, 0x97, 0x52, 0x1d, 0xbb, 0xa5, 0x0e, 0xa8, 0xda, - 0xc4, 0xdb, 0x65, 0xa0, 0x93, 0x6f, 0x43, 0x37, 0x4c, 0xf6, 0x8f, 0x2a, 0x17, 0xb2, 0x4c, 0x16, - 0xdc, 0x83, 0xba, 0x4c, 0x84, 0x40, 0x7d, 0x32, 0xa9, 0xdf, 0xe7, 0xf3, 0xea, 0xcd, 0x48, 0x55, - 0x4e, 0x48, 0x58, 0x98, 0xbf, 0x31, 0x18, 0x56, 0xea, 0xb3, 0x5c, 0x2a, 0x27, 0x54, 0x3e, 0x28, - 0x01, 0xac, 0x10, 0xe1, 0xd2, 0x16, 0x13, 0xe7, 0xc7, 0xa1, 0x95, 0xd0, 0x42, 0x65, 0xcf, 0x0f, - 0xed, 0x38, 0x5e, 0x83, 0xac, 0x13, 0xac, 0xfa, 0x12, 0xe4, 0x7c, 0x05, 0x77, 0xb0, 0xa8, 0xce, - 0xfc, 0x61, 0xcb, 0xf9, 0x3a, 0x76, 0xd5, 0xec, 0xed, 0xc0, 0x97, 0xf2, 0x6f, 0x24, 0x48, 0xd3, - 0x5a, 0xad, 0x62, 0x57, 0x0f, 0x75, 0xa4, 0xf4, 0x16, 0x3a, 0xf2, 0x7e, 0x00, 0x86, 0xe3, 0x98, - 0xaf, 0x63, 0xae, 0x5f, 0x69, 0x9a, 0x52, 0x37, 0x5f, 0xc7, 0xe8, 0x29, 0x4f, 0xea, 0xf1, 0x11, - 0x52, 0x17, 0xeb, 0x7d, 0x2e, 0xfb, 0x93, 0x30, 0x49, 0x5f, 0x66, 0xdd, 0x77, 0xf8, 0x12, 0x3e, - 0x69, 0xf5, 0xda, 0x8d, 0x7d, 0x47, 0xb9, 0x05, 0x93, 0x8d, 0x7d, 0x16, 0x71, 0x3c, 0x0d, 0xe9, - 0xae, 0x6d, 0x73, 0x6f, 0x90, 0x39, 0xe2, 0x29, 0x92, 0x40, 0x9d, 0x1f, 0x11, 0x64, 0x8b, 0xf9, - 0x41, 0x36, 0x3f, 0x4c, 0x18, 0x1f, 0x2f, 0x4c, 0x48, 0xd6, 0xed, 0xb9, 0xd0, 0x88, 0x42, 0x8f, - 0xc2, 0xc9, 0x7a, 0xed, 0xfa, 0x5a, 0x75, 0x49, 0x5b, 0xad, 0x5f, 0xef, 0x7b, 0x9d, 0x60, 0x2e, - 0xff, 0xc6, 0xdd, 0x85, 0x0c, 0x5f, 0xb0, 0x0f, 0xa3, 0xde, 0x50, 0xab, 0x5b, 0xeb, 0x8d, 0xaa, - 0x2c, 0x31, 0xea, 0x8d, 0x2e, 0xbe, 0x6d, 0xbb, 0xec, 0xed, 0xe3, 0xc7, 0xe1, 0x54, 0x04, 0xb5, - 0xb7, 0x6c, 0x9f, 0x7e, 0xe3, 0xee, 0x42, 0x6e, 0xa3, 0x8b, 0x99, 0xaa, 0x51, 0x8e, 0x45, 0x28, - 0x0c, 0x72, 0xac, 0x6f, 0xac, 0xd7, 0x4b, 0x2b, 0xf2, 0xc2, 0x9c, 0xfc, 0xc6, 0xdd, 0x85, 0xac, - 0xb0, 0x1d, 0x84, 0xfe, 0x9d, 0x5f, 0xb7, 0x27, 0x06, 0xcf, 0x3b, 0xdc, 0xe9, 0xea, 0x9d, 0x0e, - 0xee, 0x3a, 0xc3, 0x36, 0xf6, 0xcf, 0x41, 0x66, 0x29, 0x70, 0x6f, 0xd7, 0x3b, 0xe1, 0x21, 0xd1, - 0x3b, 0xbd, 0xec, 0x43, 0x51, 0x00, 0x96, 0x5b, 0xb6, 0xee, 0x46, 0xd0, 0xc4, 0x02, 0x34, 0x35, - 0xcb, 0xbd, 0x76, 0x35, 0x82, 0x26, 0x2e, 0x68, 0xce, 0x41, 0x66, 0x73, 0x18, 0x51, 0x22, 0x0c, - 0xf4, 0xc4, 0x95, 0x08, 0x9a, 0x89, 0x3e, 0xa0, 0x48, 0xa2, 0x9c, 0x20, 0x3a, 0x0b, 0xe9, 0xb2, - 0x6d, 0xb7, 0x22, 0x48, 0x52, 0x01, 0x9c, 0x7a, 0xe0, 0x4a, 0x72, 0x88, 0x28, 0x1d, 0xa8, 0x50, - 0x99, 0xac, 0x5b, 0x23, 0x68, 0xbc, 0x33, 0x30, 0x47, 0x3e, 0xfa, 0xf1, 0x6e, 0xde, 0x2f, 0x47, - 0x3d, 0xfa, 0x21, 0xfa, 0xf3, 0xde, 0x8e, 0x7e, 0x64, 0x03, 0x5b, 0x0f, 0x5e, 0x94, 0xa1, 0xa3, - 0x77, 0xf5, 0xb6, 0x73, 0xd4, 0x70, 0xea, 0x88, 0x93, 0x35, 0x73, 0x23, 0x34, 0x91, 0xac, 0x6c, - 0xf2, 0xde, 0x82, 0x79, 0x83, 0x56, 0x01, 0x5d, 0x0d, 0x46, 0x77, 0x32, 0xc3, 0xfd, 0x10, 0x46, - 0x2e, 0xa2, 0x3f, 0xcf, 0x43, 0x4a, 0x2c, 0xbc, 0xb8, 0x6d, 0x3e, 0x1b, 0xe5, 0x2d, 0x71, 0x12, - 0xce, 0xeb, 0xb1, 0xa0, 0xaf, 0x83, 0xb4, 0x67, 0xa9, 0xb9, 0x69, 0x52, 0x0e, 0xb3, 0xed, 0x1c, - 0xc0, 0x67, 0x42, 0x45, 0x3f, 0x3c, 0x90, 0x18, 0x1a, 0x71, 0xd8, 0x62, 0x14, 0x9c, 0xdb, 0x0b, - 0x0d, 0x3c, 0x09, 0x09, 0x7d, 0xdb, 0x30, 0xf9, 0x74, 0x7e, 0x7f, 0x04, 0x63, 0xa9, 0x5c, 0xa9, - 0x31, 0x2e, 0xfa, 0x20, 0x07, 0x25, 0x27, 0x95, 0x76, 0x0e, 0x2c, 0x63, 0xaf, 0x6b, 0x5b, 0x07, - 0x7c, 0x06, 0x8f, 0xaa, 0x74, 0x5d, 0xd0, 0x88, 0x4a, 0x7b, 0x4c, 0xa4, 0xd2, 0x3b, 0xd8, 0x9f, - 0xbd, 0xa3, 0x2b, 0xbd, 0xcc, 0x28, 0x44, 0xa5, 0x39, 0x83, 0x52, 0xe3, 0xf1, 0x54, 0xde, 0x6d, - 0xf4, 0x91, 0xaa, 0x7d, 0x8d, 0x45, 0x7a, 0xd8, 0x80, 0x4f, 0xb5, 0xf5, 0x7d, 0x3a, 0x68, 0xc8, - 0x54, 0x42, 0x32, 0x77, 0xf9, 0xc3, 0x25, 0x71, 0x35, 0xd9, 0xd6, 0xf7, 0xaf, 0xeb, 0xce, 0xcd, - 0x44, 0x2a, 0x2e, 0x27, 0x94, 0x4f, 0x12, 0xf7, 0x3b, 0xd4, 0x35, 0xe8, 0x11, 0x40, 0x84, 0x43, - 0xdf, 0xc5, 0x1a, 0x99, 0x84, 0x68, 0x27, 0x0b, 0xdc, 0x7c, 0x5b, 0xdf, 0x2f, 0xed, 0xe2, 0xb5, - 0x5e, 0x9b, 0x56, 0xc0, 0x41, 0xab, 0x20, 0x0b, 0x62, 0xa1, 0x80, 0x9e, 0xbf, 0x30, 0xf0, 0x50, - 0x36, 0x27, 0x60, 0x0e, 0xcd, 0x07, 0x89, 0x43, 0x33, 0xc5, 0xf0, 0xbc, 0x23, 0x5f, 0xa1, 0xa6, - 0xc4, 0xc3, 0x4d, 0x51, 0x5e, 0x84, 0x7c, 0x9f, 0x16, 0x20, 0x05, 0x72, 0x3c, 0x6a, 0x4d, 0x8f, - 0xd3, 0xb0, 0xb5, 0x7b, 0x5a, 0xcd, 0xb0, 0xe0, 0x34, 0x1d, 0x7d, 0xc5, 0xd4, 0x2f, 0x7e, 0x6c, - 0x5e, 0xa2, 0x5b, 0x97, 0x8f, 0x40, 0x2e, 0xa4, 0x06, 0x22, 0x70, 0x29, 0xf9, 0x81, 0x4b, 0x9f, - 0xf8, 0x55, 0xc8, 0x92, 0xa9, 0x14, 0x37, 0x39, 0xed, 0x43, 0x90, 0x67, 0x73, 0x7d, 0xbf, 0xac, - 0x99, 0x0f, 0xbf, 0x2a, 0x04, 0xae, 0x08, 0xa7, 0x3e, 0x2c, 0xf6, 0x8c, 0xa0, 0xba, 0xae, 0x3b, - 0xca, 0x0f, 0x48, 0x90, 0xef, 0xd3, 0x0d, 0xf4, 0x3c, 0xa4, 0x3b, 0x5d, 0x6c, 0x98, 0x81, 0x30, - 0xd7, 0x21, 0x22, 0x4c, 0x50, 0xf1, 0xf9, 0x1c, 0xc4, 0x4d, 0x12, 0xe7, 0x04, 0x9a, 0xb8, 0xa5, - 0x1f, 0x8c, 0xee, 0x05, 0x06, 0x21, 0x7e, 0xb5, 0x60, 0x89, 0x30, 0x29, 0xbf, 0x2a, 0x41, 0x2e, - 0xa4, 0x74, 0xa8, 0x09, 0xf7, 0x93, 0x29, 0x3a, 0x78, 0x36, 0x9d, 0xbf, 0xe6, 0x17, 0x58, 0xa3, - 0x65, 0xae, 0x9c, 0x1e, 0x28, 0xc7, 0x9f, 0x68, 0xa8, 0x73, 0x23, 0xa9, 0x73, 0x04, 0xc7, 0x3f, - 0xa2, 0xce, 0x9e, 0xfd, 0xbb, 0xc1, 0x9c, 0xf1, 0x75, 0x40, 0x9d, 0x6d, 0xb7, 0x1f, 0x3a, 0x36, - 0x2e, 0xb4, 0x4c, 0x98, 0x83, 0x80, 0x4a, 0x1d, 0xc0, 0x1f, 0xb8, 0xa8, 0x34, 0x4e, 0x23, 0xe2, - 0x87, 0xd5, 0xb0, 0x18, 0x2b, 0x48, 0xe5, 0x8d, 0x4f, 0x7c, 0xf6, 0x8c, 0xf4, 0x8e, 0xb8, 0x0e, - 0xbf, 0x5b, 0x87, 0xfb, 0x7c, 0xd2, 0x6d, 0xc3, 0xec, 0x0f, 0x68, 0xcb, 0x9e, 0x71, 0x20, 0xb9, - 0x64, 0x5a, 0x38, 0x7c, 0x3f, 0x6d, 0x64, 0xb8, 0x7b, 0xc4, 0x44, 0x34, 0x4e, 0x38, 0xfc, 0x1e, - 0xa3, 0xdd, 0xff, 0x31, 0x0d, 0x93, 0x2a, 0x7e, 0x4f, 0x0f, 0x3b, 0x2e, 0x7a, 0x02, 0x12, 0xd8, - 0xd8, 0xb3, 0x07, 0xb7, 0x9c, 0x78, 0x2b, 0x17, 0xab, 0xc6, 0x9e, 0xcd, 0x89, 0x6f, 0x1c, 0x53, - 0x29, 0x31, 0xba, 0x06, 0x13, 0x3b, 0xad, 0x1e, 0x0f, 0x84, 0x87, 0xa6, 0x29, 0xc1, 0xb5, 0x4c, - 0xb2, 0x7d, 0x36, 0x46, 0x4e, 0x0a, 0xa3, 0x3f, 0x27, 0x11, 0x1f, 0x56, 0x18, 0xfd, 0x15, 0x09, - 0xbf, 0x30, 0x42, 0x8c, 0x2a, 0x00, 0xa6, 0x65, 0xba, 0x1a, 0x8d, 0x11, 0xf3, 0x69, 0x42, 0x89, - 0x62, 0x35, 0x5d, 0x1a, 0x4f, 0xf6, 0xf9, 0xd3, 0xa6, 0x48, 0x23, 0x35, 0x7e, 0x4f, 0x0f, 0x77, - 0xc5, 0x54, 0x11, 0x51, 0xe3, 0x77, 0x91, 0xec, 0x40, 0x8d, 0x29, 0x39, 0x99, 0x5a, 0xd9, 0x53, - 0xa7, 0xee, 0x3e, 0x7f, 0xc0, 0x7b, 0x61, 0x90, 0x95, 0xbe, 0x74, 0xda, 0xd8, 0xf7, 0x99, 0x27, - 0x0d, 0x96, 0x82, 0x9e, 0xf1, 0x96, 0x70, 0x99, 0xfe, 0x35, 0x93, 0xc7, 0xcc, 0x56, 0x70, 0x1e, - 0x2f, 0x67, 0x40, 0xeb, 0x30, 0xd5, 0x32, 0x1d, 0x57, 0x73, 0x2c, 0xbd, 0xe3, 0xec, 0xd9, 0xae, - 0x43, 0x63, 0xb1, 0x99, 0x2b, 0x0f, 0x0d, 0x42, 0xac, 0x98, 0x8e, 0x5b, 0x17, 0x64, 0x3e, 0x52, - 0xae, 0x15, 0x4c, 0x27, 0x80, 0xf6, 0xce, 0x0e, 0xee, 0x7a, 0x88, 0x34, 0x68, 0x1b, 0x09, 0xb8, - 0x4e, 0xe8, 0x04, 0x67, 0x00, 0xd0, 0x0e, 0xa6, 0xa3, 0x6f, 0x80, 0x99, 0x96, 0xad, 0x37, 0x3d, - 0x3c, 0xcd, 0xd8, 0xeb, 0x59, 0xb7, 0x68, 0x88, 0x37, 0x73, 0xe5, 0x62, 0x44, 0x35, 0x6d, 0xbd, - 0x29, 0x98, 0x2b, 0x84, 0xd4, 0x47, 0x9e, 0x6e, 0xf5, 0xe7, 0x21, 0x0d, 0x66, 0xf5, 0x4e, 0xa7, - 0x75, 0xd0, 0x0f, 0x9f, 0xa7, 0xf0, 0x8f, 0x0c, 0xc2, 0x97, 0x08, 0xf5, 0x10, 0x7c, 0xa4, 0x0f, - 0x64, 0xa2, 0x4d, 0x90, 0x3b, 0x5d, 0x4c, 0xef, 0xad, 0x76, 0xf8, 0x22, 0x85, 0xbe, 0x11, 0x98, - 0xb9, 0x72, 0x61, 0x10, 0x7c, 0x83, 0x51, 0x8a, 0xd5, 0x8c, 0x8f, 0x9c, 0xef, 0x84, 0x73, 0x18, - 0xac, 0x6d, 0x60, 0xfa, 0x86, 0x29, 0x87, 0x9d, 0x1e, 0x0e, 0x4b, 0x29, 0x23, 0x61, 0x43, 0x39, - 0x68, 0x19, 0x32, 0x2c, 0xaa, 0xa5, 0x11, 0x13, 0x49, 0xdf, 0x16, 0xcc, 0x5c, 0x39, 0x17, 0x31, - 0x5c, 0x29, 0xd1, 0x96, 0xed, 0x62, 0x1f, 0x0c, 0xb0, 0x97, 0x88, 0xb6, 0xe1, 0x38, 0x7d, 0x67, - 0xf1, 0x40, 0x0b, 0xdb, 0xe3, 0xc2, 0x0c, 0x45, 0x7c, 0x74, 0x10, 0x91, 0xfe, 0xc8, 0xc0, 0xc1, - 0x56, 0xd0, 0x30, 0xfb, 0xd0, 0x33, 0xb7, 0x07, 0x73, 0x89, 0xa6, 0xed, 0x98, 0x96, 0xde, 0x32, - 0x5f, 0xc7, 0xcc, 0x79, 0xa1, 0x4f, 0x0c, 0x47, 0x6a, 0xda, 0x32, 0xa7, 0xa3, 0xce, 0x4c, 0x40, - 0xd3, 0x76, 0x82, 0xe9, 0xe5, 0x49, 0xbe, 0xe4, 0xf0, 0xde, 0xcc, 0x9c, 0x94, 0x53, 0xec, 0x9d, - 0xcc, 0x9b, 0x89, 0x14, 0xc8, 0x19, 0xe5, 0x3c, 0x64, 0x02, 0x76, 0x0a, 0x15, 0x60, 0x92, 0x4f, - 0xaa, 0xe2, 0x00, 0x3f, 0xff, 0x54, 0xa6, 0x20, 0x1b, 0x34, 0x4d, 0xca, 0x07, 0x24, 0xc8, 0x04, - 0x8c, 0x0e, 0xe1, 0x0c, 0x6e, 0x74, 0xa5, 0x7d, 0x3f, 0xf5, 0x9c, 0xf0, 0x2a, 0x44, 0x3e, 0xdb, - 0x6c, 0xcd, 0xd2, 0x44, 0xee, 0xd4, 0xa0, 0x79, 0xc8, 0x74, 0xae, 0x74, 0x3c, 0x92, 0x38, 0x25, - 0x81, 0xce, 0x95, 0x8e, 0x20, 0x38, 0x0b, 0x59, 0xd2, 0x74, 0x2d, 0xe8, 0x2e, 0xa7, 0xd5, 0x0c, - 0x49, 0xe3, 0x24, 0xca, 0x6f, 0xc6, 0x40, 0xee, 0x37, 0x66, 0xde, 0x06, 0x98, 0x74, 0xe4, 0x0d, - 0xb0, 0x53, 0xfd, 0x5b, 0x6f, 0xfe, 0x6e, 0xdb, 0x2a, 0xc8, 0xfe, 0x9e, 0x11, 0x9b, 0x7b, 0x0e, - 0xf1, 0xff, 0xfb, 0xd6, 0x2a, 0x6a, 0xde, 0xe8, 0x5b, 0xbc, 0x5c, 0x0f, 0x9d, 0x17, 0x49, 0x78, - 0x47, 0x5c, 0xfb, 0xf5, 0x49, 0xd0, 0x6c, 0x76, 0x9a, 0xba, 0x8b, 0x45, 0xc8, 0x3d, 0x70, 0x74, - 0xe4, 0x21, 0xc8, 0xeb, 0x9d, 0x8e, 0xe6, 0xb8, 0xba, 0x8b, 0xb9, 0xa3, 0xc7, 0x02, 0x99, 0x39, - 0xbd, 0xd3, 0xa1, 0xbf, 0x73, 0xc1, 0x1c, 0xbd, 0x07, 0x61, 0x8a, 0x58, 0x78, 0x53, 0x6f, 0x09, - 0x2f, 0x22, 0xc9, 0xfc, 0x41, 0x9e, 0xca, 0x3d, 0x91, 0x26, 0x64, 0x83, 0xc6, 0xdd, 0x0b, 0xcd, - 0x48, 0x81, 0xd0, 0x0c, 0xe2, 0x0f, 0x2f, 0x31, 0x09, 0x89, 0xc7, 0xaa, 0xa2, 0x37, 0x23, 0x67, - 0x69, 0x18, 0xe7, 0x36, 0x8b, 0xbd, 0xa6, 0x54, 0xf6, 0xa1, 0xbc, 0x02, 0x53, 0xe1, 0x79, 0x00, - 0x4d, 0x41, 0xcc, 0xdd, 0xe7, 0xa5, 0xc4, 0xdc, 0x7d, 0x74, 0x39, 0xf0, 0x0b, 0x21, 0x53, 0x51, - 0xb3, 0x1f, 0xe7, 0xf7, 0x43, 0xa7, 0x37, 0x13, 0xa9, 0x98, 0x1c, 0x57, 0xf2, 0x90, 0x0b, 0xcd, - 0x12, 0xca, 0x09, 0x98, 0x8d, 0xb2, 0xf9, 0x8a, 0x09, 0xb3, 0x51, 0xa6, 0x1b, 0x5d, 0x83, 0x94, - 0x67, 0xf4, 0x07, 0xa2, 0x6d, 0xa2, 0x74, 0x8f, 0xc9, 0xa3, 0x0d, 0xed, 0x16, 0xc6, 0x42, 0xbb, - 0x85, 0xca, 0x37, 0x43, 0x61, 0x98, 0x3d, 0xef, 0xdb, 0x3e, 0x48, 0x78, 0x82, 0x3b, 0x01, 0x49, - 0xfe, 0xda, 0x70, 0x8c, 0x86, 0x29, 0xf8, 0x17, 0x11, 0x28, 0xb3, 0xed, 0x71, 0x16, 0xbd, 0xa0, - 0x1f, 0x8a, 0x06, 0xa7, 0x86, 0x9a, 0xf4, 0xe1, 0xbb, 0xed, 0x0c, 0x88, 0xef, 0xb6, 0xd3, 0x0f, - 0xfa, 0x2b, 0x54, 0xd8, 0x12, 0x41, 0xc0, 0xb4, 0xca, 0xbf, 0x94, 0x0f, 0xc5, 0xe1, 0x44, 0xb4, - 0x5d, 0x47, 0x0b, 0x90, 0x25, 0x8b, 0x07, 0x37, 0xbc, 0xce, 0x80, 0xb6, 0xbe, 0xdf, 0xe0, 0x8b, - 0x0c, 0xbe, 0x53, 0x19, 0xf3, 0x76, 0x2a, 0xd1, 0x16, 0x4c, 0xb7, 0x6c, 0x43, 0x6f, 0x69, 0x81, - 0x9d, 0x62, 0x3e, 0x9c, 0x1e, 0x18, 0x66, 0xa7, 0xc5, 0x5e, 0x04, 0x31, 0x41, 0x7c, 0x20, 0xe4, - 0x29, 0xc8, 0x8a, 0xb7, 0xab, 0x8c, 0xaa, 0x90, 0x69, 0x9b, 0xce, 0x36, 0xde, 0xd3, 0x6f, 0x9b, - 0x76, 0x97, 0x8f, 0xab, 0x08, 0xed, 0x59, 0xf5, 0x89, 0xc4, 0x16, 0x76, 0x80, 0x2f, 0xd0, 0x29, - 0x13, 0x91, 0x5b, 0xeb, 0xc9, 0x23, 0x5b, 0x96, 0x61, 0x9b, 0xd4, 0x93, 0x43, 0x37, 0xa9, 0xa3, - 0x76, 0x84, 0x53, 0xd1, 0x3b, 0xc2, 0x6f, 0xd0, 0xce, 0x89, 0x9a, 0x1d, 0x07, 0x37, 0x89, 0x51, - 0x03, 0x66, 0x39, 0x7f, 0x33, 0x24, 0xfd, 0x81, 0x73, 0x67, 0x61, 0xa7, 0x2b, 0x20, 0x75, 0x24, - 0xf8, 0x87, 0x0b, 0x3e, 0x7e, 0x8f, 0x82, 0x17, 0x47, 0x35, 0x12, 0x81, 0xa3, 0x1a, 0xff, 0x8f, - 0x75, 0xc6, 0xfb, 0xe2, 0x62, 0xf3, 0x2c, 0xe0, 0x58, 0x44, 0x9e, 0x41, 0x19, 0xb6, 0xd7, 0x23, - 0x1a, 0x16, 0x3f, 0x72, 0xc3, 0x78, 0x6f, 0x27, 0x46, 0xf7, 0xf6, 0xc4, 0xdb, 0xd9, 0xdb, 0xc9, - 0x7b, 0xec, 0xed, 0x77, 0xb4, 0x1f, 0x3e, 0x22, 0xc1, 0xdc, 0x70, 0x77, 0x2c, 0xb2, 0x43, 0x8e, - 0xb4, 0x3b, 0x39, 0x6c, 0xc6, 0x7b, 0x10, 0xa6, 0xfa, 0xbc, 0x45, 0xa6, 0xcc, 0xb9, 0xd0, 0x72, - 0x5d, 0xf9, 0xf6, 0x38, 0xcc, 0x46, 0x39, 0x74, 0x11, 0x23, 0x56, 0x85, 0x99, 0x26, 0x36, 0xcc, - 0xe6, 0x3d, 0x0f, 0xd8, 0x69, 0xce, 0xfe, 0xff, 0xc7, 0x6b, 0x84, 0x9e, 0xfc, 0x38, 0x40, 0x4a, - 0xc5, 0x4e, 0x87, 0x38, 0x68, 0xec, 0xd7, 0x0e, 0x0d, 0xdc, 0x71, 0xfd, 0xb0, 0x56, 0xe4, 0xba, - 0x81, 0x93, 0x08, 0x3e, 0xb2, 0x7e, 0xf6, 0xf8, 0xd0, 0x55, 0x1e, 0x26, 0x18, 0xba, 0xe0, 0x67, - 0xee, 0xb7, 0xc7, 0xca, 0xe2, 0x04, 0x4f, 0x89, 0x38, 0x41, 0x7c, 0xd8, 0xea, 0x97, 0x3b, 0xe3, - 0x1e, 0x1f, 0x0f, 0x14, 0x5c, 0xe5, 0x81, 0x82, 0xc4, 0xb0, 0xe2, 0x98, 0xcf, 0xee, 0x17, 0x67, - 0xb2, 0x87, 0x4c, 0x83, 0x91, 0x82, 0xe4, 0xb0, 0xa6, 0x06, 0x9c, 0x6b, 0xbf, 0xa9, 0x7e, 0xa8, - 0xe0, 0x29, 0x11, 0x2a, 0x98, 0x1c, 0x56, 0x69, 0xee, 0x4d, 0xfa, 0x95, 0x66, 0xb1, 0x82, 0x17, - 0x02, 0xb1, 0x82, 0x74, 0x7f, 0x18, 0x7e, 0x20, 0x56, 0xe0, 0x71, 0x7b, 0xc1, 0x82, 0xa2, 0x17, - 0x2c, 0xc8, 0x0e, 0x8d, 0x34, 0x70, 0x37, 0xd0, 0x63, 0x16, 0xd1, 0x82, 0x8d, 0x81, 0x68, 0x01, - 0x5b, 0xdc, 0x9f, 0x1f, 0x19, 0x2d, 0xf0, 0xa0, 0xfa, 0xc2, 0x05, 0x1b, 0x03, 0xe1, 0x82, 0xa9, - 0x61, 0x88, 0x7d, 0x3e, 0xa7, 0x8f, 0x18, 0x8e, 0x17, 0x7c, 0x63, 0x74, 0xbc, 0x60, 0xe8, 0x82, - 0x3e, 0xc2, 0xbf, 0xf4, 0xa0, 0x23, 0x02, 0x06, 0xdf, 0x3c, 0x24, 0x60, 0x20, 0x0f, 0x5b, 0xd8, - 0x46, 0x79, 0x97, 0x5e, 0x01, 0x51, 0x11, 0x83, 0xad, 0x88, 0x88, 0x01, 0x5b, 0xda, 0x3f, 0x3c, - 0x46, 0xc4, 0xc0, 0x83, 0x1e, 0x08, 0x19, 0x6c, 0x45, 0x84, 0x0c, 0xd0, 0x70, 0xdc, 0x3e, 0xa7, - 0x28, 0x88, 0x1b, 0x8e, 0x19, 0x5c, 0x0f, 0xc7, 0x0c, 0x66, 0x0e, 0xf7, 0x45, 0xd9, 0xd4, 0xee, - 0xa1, 0x05, 0x83, 0x06, 0xc6, 0xb0, 0xa0, 0x01, 0x5b, 0xd7, 0x3f, 0x36, 0x66, 0xd0, 0xc0, 0xc3, - 0x8e, 0x8c, 0x1a, 0x6c, 0x0c, 0x44, 0x0d, 0x8e, 0x0f, 0x53, 0xb8, 0xbe, 0x49, 0xc6, 0x57, 0xb8, - 0xa1, 0x61, 0x03, 0xf6, 0x23, 0x1b, 0xec, 0xe7, 0x35, 0x40, 0xce, 0xdc, 0x4c, 0xa4, 0x32, 0x72, - 0x56, 0x79, 0x98, 0xb8, 0x35, 0x7d, 0x76, 0x8f, 0x2c, 0x22, 0x70, 0xb7, 0x6b, 0x77, 0xc5, 0x1e, - 0x28, 0xfd, 0x50, 0x2e, 0x40, 0x36, 0x68, 0xe2, 0x0e, 0x09, 0x31, 0xe4, 0x21, 0x17, 0xb2, 0x6a, - 0xca, 0x2f, 0x4a, 0x90, 0x0d, 0xda, 0xab, 0xd0, 0x02, 0x34, 0xcd, 0x17, 0xa0, 0x81, 0xc0, 0x43, - 0x2c, 0x1c, 0x78, 0x98, 0x87, 0x0c, 0x59, 0x84, 0xf5, 0xc5, 0x14, 0xf4, 0x8e, 0x17, 0x53, 0x10, - 0x07, 0x37, 0x59, 0x78, 0x82, 0xcf, 0x53, 0xec, 0xd4, 0x42, 0xde, 0x3b, 0xc4, 0xca, 0xc3, 0xfc, - 0x8f, 0xc1, 0x4c, 0x80, 0xd6, 0x5b, 0xdc, 0xb1, 0xe5, 0xb5, 0xec, 0x51, 0x97, 0xf8, 0x2a, 0xef, - 0x57, 0x25, 0x98, 0x1e, 0x30, 0x97, 0x91, 0x71, 0x03, 0xe9, 0xed, 0x8a, 0x1b, 0xc4, 0xee, 0x3d, - 0x6e, 0x10, 0x5c, 0xae, 0xc6, 0xc3, 0xcb, 0xd5, 0xbf, 0x94, 0x20, 0x17, 0x32, 0xdb, 0xa4, 0x13, - 0x0c, 0xbb, 0x29, 0x76, 0xcc, 0xe9, 0xdf, 0xc4, 0x4f, 0x69, 0xd9, 0xbb, 0x7c, 0x99, 0x48, 0xfe, - 0x24, 0x54, 0xde, 0x44, 0x94, 0xe6, 0xd3, 0x8c, 0xb7, 0xf6, 0x9c, 0x08, 0xde, 0x29, 0xe3, 0xf7, - 0xac, 0x92, 0xfe, 0x3d, 0x2b, 0x6f, 0xa3, 0x7c, 0x32, 0xb0, 0x51, 0x8e, 0x9e, 0x81, 0x34, 0xdd, - 0x05, 0xd0, 0xec, 0x8e, 0xff, 0xc3, 0xcc, 0xc3, 0xef, 0x58, 0x39, 0xf4, 0x92, 0x00, 0xbb, 0x98, - 0xe5, 0x7b, 0x21, 0xe9, 0x90, 0x17, 0x72, 0x1f, 0xa4, 0x49, 0xf5, 0xd9, 0x8f, 0x1b, 0x01, 0x7f, - 0x6a, 0x44, 0x24, 0x28, 0x3f, 0x15, 0x83, 0x7c, 0xdf, 0xac, 0x13, 0xd9, 0xf8, 0xa8, 0x13, 0x2b, - 0xe3, 0x09, 0xe4, 0x0c, 0xc0, 0xae, 0xee, 0x68, 0x77, 0x74, 0xcb, 0xe5, 0xbf, 0x61, 0x1a, 0x57, - 0x03, 0x29, 0x68, 0x0e, 0x52, 0xe4, 0xab, 0xe7, 0xf0, 0x5f, 0x31, 0x8d, 0xab, 0xde, 0x37, 0xaa, - 0x41, 0x12, 0xdf, 0xa6, 0xcf, 0x71, 0xb3, 0x47, 0xed, 0x4f, 0x46, 0x98, 0x27, 0x92, 0x5f, 0x2e, - 0x90, 0xee, 0xfe, 0xa3, 0x37, 0xe7, 0x65, 0x46, 0xfe, 0xa8, 0x77, 0x81, 0x55, 0xe5, 0x00, 0x61, - 0x31, 0xa4, 0xfa, 0xc4, 0x40, 0xc3, 0x85, 0x59, 0xb1, 0xf6, 0x27, 0x42, 0x65, 0x37, 0x71, 0xd4, - 0x5c, 0x1b, 0xb7, 0x3b, 0xb6, 0xdd, 0xd2, 0xd8, 0x38, 0x2f, 0xc1, 0x54, 0x78, 0x92, 0x65, 0xbf, - 0x3c, 0xe8, 0xea, 0xa6, 0xa5, 0x85, 0x7c, 0xe3, 0x2c, 0x4b, 0x64, 0xe3, 0xea, 0x66, 0x22, 0x25, - 0xc9, 0x31, 0x1e, 0xae, 0x79, 0x17, 0x1c, 0x8f, 0x9c, 0x63, 0xd1, 0xd3, 0x90, 0xf6, 0xe7, 0x67, - 0x76, 0x9f, 0xea, 0xb0, 0x38, 0x8c, 0x4f, 0xac, 0x6c, 0xc1, 0xf1, 0xc8, 0x49, 0x16, 0x3d, 0x0f, - 0x49, 0x76, 0x5e, 0x9b, 0x9f, 0xc9, 0x7b, 0x70, 0xf4, 0xec, 0xdc, 0x6b, 0xb9, 0x2a, 0x67, 0x52, - 0x2e, 0xc3, 0xa9, 0xa1, 0xb3, 0xac, 0x1f, 0x4d, 0x91, 0x02, 0xd1, 0x14, 0xe5, 0x67, 0x24, 0x98, - 0x1b, 0x3e, 0x73, 0xa2, 0x72, 0x5f, 0x85, 0x2e, 0x8e, 0x39, 0xef, 0x06, 0x6a, 0x45, 0x96, 0x1b, - 0x5d, 0xbc, 0x83, 0x5d, 0x63, 0x8f, 0x4d, 0xe1, 0xcc, 0x28, 0xe4, 0xd4, 0x1c, 0x4f, 0xa5, 0x3c, - 0x0e, 0x23, 0x7b, 0x0d, 0x1b, 0xae, 0xc6, 0x3a, 0xd5, 0xe1, 0x3f, 0x35, 0x9f, 0x63, 0xa9, 0x75, - 0x96, 0xa8, 0x3c, 0x02, 0x27, 0x87, 0xcc, 0xc5, 0x11, 0xc7, 0xcd, 0x5f, 0x25, 0xc4, 0x91, 0x13, - 0x2c, 0x7a, 0x11, 0x92, 0x8e, 0xab, 0xbb, 0x3d, 0x87, 0xb7, 0xec, 0xfc, 0xc8, 0xb9, 0xb9, 0x4e, - 0xc9, 0x55, 0xce, 0xa6, 0x3c, 0x0b, 0x68, 0x70, 0xa6, 0x8d, 0x58, 0x5b, 0x49, 0x51, 0x6b, 0xab, - 0x6d, 0x38, 0x7d, 0xc8, 0x9c, 0x8a, 0x2a, 0x7d, 0x95, 0x7b, 0x64, 0xac, 0x29, 0xb9, 0xaf, 0x82, - 0x7f, 0x12, 0x83, 0xe3, 0x91, 0x53, 0x6b, 0x60, 0x94, 0x4a, 0x6f, 0x75, 0x94, 0x3e, 0x0f, 0xe0, - 0xee, 0x8b, 0x4b, 0x06, 0xdc, 0xda, 0x47, 0xad, 0x27, 0xf6, 0xb1, 0x41, 0x0d, 0x16, 0x51, 0x8c, - 0xb4, 0xcb, 0xff, 0x22, 0x8b, 0xff, 0xc0, 0x7a, 0xb6, 0x47, 0x67, 0x02, 0x87, 0x2f, 0xf5, 0xc6, - 0x9e, 0x33, 0xfc, 0x85, 0x2f, 0x4b, 0x76, 0xd0, 0xab, 0x70, 0xb2, 0x6f, 0x46, 0xf3, 0xb0, 0x13, - 0x63, 0x4f, 0x6c, 0xc7, 0xc3, 0x13, 0x9b, 0xc0, 0x0e, 0xce, 0x4a, 0x13, 0xe1, 0x59, 0xe9, 0x55, - 0x00, 0x7f, 0x61, 0xeb, 0x9f, 0x87, 0x95, 0x82, 0xe7, 0x61, 0xaf, 0xc1, 0x04, 0xd1, 0x04, 0x21, - 0xaa, 0x08, 0x83, 0x41, 0xba, 0x34, 0xb0, 0x32, 0x66, 0xe4, 0xca, 0x6b, 0x42, 0xdb, 0x82, 0x31, - 0xc6, 0x21, 0x65, 0xbc, 0x10, 0x2e, 0x43, 0x19, 0x1e, 0xae, 0x8c, 0x2e, 0xeb, 0x6f, 0xc1, 0x04, - 0xed, 0xfe, 0xc8, 0x0b, 0xc8, 0xdf, 0x04, 0xa0, 0xbb, 0x6e, 0xd7, 0xdc, 0xee, 0xf9, 0x25, 0x2c, - 0x0c, 0xd1, 0x9f, 0x92, 0x20, 0x2c, 0xdf, 0xc7, 0x15, 0x69, 0xd6, 0xe7, 0x0d, 0x28, 0x53, 0x00, - 0x51, 0x59, 0x83, 0xa9, 0x30, 0x6f, 0xf4, 0x8d, 0x6a, 0xff, 0xdd, 0x26, 0x71, 0xae, 0xcd, 0x9f, - 0xc8, 0xf9, 0x5b, 0x6a, 0xf4, 0x43, 0xf9, 0x96, 0x18, 0x64, 0x83, 0xda, 0xf7, 0x37, 0x70, 0xb2, - 0x54, 0xbe, 0x5d, 0x82, 0x94, 0xd7, 0xfe, 0x43, 0x6e, 0x03, 0xf8, 0x77, 0xeb, 0xbd, 0x18, 0x3c, - 0xdb, 0xf5, 0x88, 0x7b, 0xbb, 0x1e, 0xcf, 0x79, 0x13, 0xc2, 0xd0, 0xc5, 0x7c, 0x50, 0xda, 0xe2, - 0x1c, 0x2e, 0x9f, 0xa0, 0x9e, 0x1d, 0xef, 0x72, 0xef, 0x2c, 0x4c, 0x04, 0xef, 0xe5, 0xb2, 0x0f, - 0x05, 0x07, 0x8e, 0x2b, 0xb1, 0xd1, 0x18, 0xbc, 0x05, 0x2c, 0x1d, 0xfd, 0x16, 0xb0, 0x57, 0x4c, - 0x2c, 0x58, 0xcc, 0x3f, 0x90, 0x20, 0x25, 0xc6, 0x05, 0x7a, 0x31, 0x78, 0x98, 0x4e, 0x9c, 0xcc, - 0x19, 0x6e, 0x97, 0x78, 0x01, 0x81, 0xb3, 0x74, 0x03, 0x57, 0x12, 0xe2, 0x47, 0xbe, 0x92, 0xc0, - 0xfd, 0x90, 0x2f, 0x4b, 0x20, 0xf7, 0x8f, 0xdb, 0xb7, 0x5e, 0xbf, 0xc1, 0xf9, 0x2a, 0x1e, 0x31, - 0x5f, 0x0d, 0xbb, 0x68, 0x90, 0x18, 0x76, 0xd1, 0x60, 0xb0, 0xdd, 0x13, 0xf7, 0xda, 0xee, 0xf7, - 0xc5, 0x20, 0x13, 0x88, 0xf1, 0xa1, 0x27, 0x43, 0xb7, 0x16, 0xce, 0x1e, 0x1a, 0x10, 0x0c, 0x5c, - 0x5b, 0x08, 0x49, 0x2a, 0x76, 0x0f, 0x92, 0x7a, 0xfb, 0x2f, 0x33, 0x46, 0xdf, 0x8c, 0x9f, 0x18, - 0x72, 0x33, 0xfe, 0xef, 0x48, 0x90, 0xf2, 0x82, 0x2f, 0x47, 0xdd, 0x93, 0x3b, 0x01, 0x49, 0xee, - 0x7b, 0xb1, 0x4d, 0x39, 0xfe, 0x15, 0x19, 0x1d, 0x9d, 0x83, 0x94, 0xf8, 0x95, 0x55, 0x3e, 0xc3, - 0x79, 0xdf, 0x17, 0xb7, 0x21, 0x13, 0xd8, 0xd6, 0x44, 0xa7, 0xe0, 0x78, 0xe5, 0x46, 0xb5, 0xf2, - 0x92, 0xd6, 0x78, 0xb9, 0xff, 0xb7, 0xf5, 0x06, 0xb2, 0xd4, 0x2a, 0xfd, 0x96, 0x25, 0x74, 0x12, - 0x66, 0xc2, 0x59, 0x2c, 0x23, 0x36, 0x97, 0x78, 0xff, 0x8f, 0x9d, 0x39, 0x76, 0xf1, 0xcb, 0x12, - 0xcc, 0x44, 0x78, 0xb9, 0xe8, 0x2c, 0xdc, 0xbf, 0xbe, 0xbc, 0x5c, 0x55, 0xb5, 0xfa, 0x5a, 0x69, - 0xa3, 0x7e, 0x63, 0xbd, 0xa1, 0xa9, 0xd5, 0xfa, 0xe6, 0x4a, 0x23, 0x50, 0xe8, 0x02, 0xdc, 0x17, - 0x4d, 0x52, 0xaa, 0x54, 0xaa, 0x1b, 0x0d, 0xf6, 0xe3, 0x7e, 0x43, 0x28, 0xca, 0xeb, 0x6a, 0x43, - 0x8e, 0x0d, 0x87, 0x50, 0xab, 0x37, 0xab, 0x95, 0x86, 0x1c, 0x47, 0xe7, 0xe1, 0xdc, 0x61, 0x14, - 0xda, 0xf2, 0xba, 0xba, 0x5a, 0x6a, 0xc8, 0x89, 0x91, 0x84, 0xf5, 0xea, 0xda, 0x52, 0x55, 0x95, - 0x27, 0x78, 0xbb, 0x3f, 0x16, 0x83, 0xc2, 0x30, 0x67, 0x9a, 0x60, 0x95, 0x36, 0x36, 0x56, 0x5e, - 0xf1, 0xb1, 0x2a, 0x37, 0x36, 0xd7, 0x5e, 0x1a, 0x14, 0xc1, 0x43, 0xa0, 0x1c, 0x46, 0xe8, 0x09, - 0xe2, 0x41, 0x38, 0x7b, 0x28, 0x1d, 0x17, 0xc7, 0x08, 0x32, 0xb5, 0xda, 0x50, 0x5f, 0x91, 0xe3, - 0x68, 0x11, 0x2e, 0x8e, 0x24, 0xf3, 0xf2, 0xe4, 0x04, 0xba, 0x04, 0x8f, 0x1c, 0x4e, 0xcf, 0x04, - 0x24, 0x18, 0x84, 0x88, 0xde, 0x90, 0xe0, 0x78, 0xa4, 0x57, 0x8e, 0xce, 0xc1, 0xfc, 0x86, 0xba, - 0x5e, 0xa9, 0xd6, 0xeb, 0xde, 0x9d, 0x05, 0xad, 0xde, 0x28, 0x35, 0x36, 0xeb, 0x01, 0xd9, 0x28, - 0x70, 0x66, 0x18, 0x91, 0x27, 0x97, 0x43, 0x68, 0xb8, 0x06, 0x08, 0x3d, 0xbd, 0x2b, 0xc1, 0xa9, - 0xa1, 0x5e, 0x38, 0xba, 0x00, 0x0f, 0x6c, 0x55, 0xd5, 0xda, 0xf2, 0x2b, 0xda, 0xd6, 0x7a, 0x23, - 0xf8, 0x2b, 0x92, 0x03, 0xb5, 0x3a, 0x0f, 0xe7, 0x0e, 0xa5, 0xf4, 0xaa, 0x36, 0x8a, 0xb0, 0xaf, - 0x7e, 0xdf, 0x26, 0x41, 0xbe, 0xcf, 0x16, 0xa2, 0xfb, 0xa0, 0xb0, 0x5a, 0xab, 0x97, 0xab, 0x37, - 0x4a, 0x5b, 0xb5, 0x75, 0xb5, 0x7f, 0xcc, 0x9e, 0x83, 0xf9, 0x81, 0xdc, 0xa5, 0xcd, 0x8d, 0x95, - 0x5a, 0xa5, 0xd4, 0xa8, 0x6a, 0xec, 0xa2, 0x09, 0x69, 0xd8, 0x00, 0xd1, 0x4a, 0xed, 0xfa, 0x8d, - 0x86, 0x56, 0x59, 0xa9, 0x55, 0xd7, 0x1a, 0x5a, 0xa9, 0xd1, 0x28, 0xf9, 0xc3, 0xb9, 0xfc, 0xd2, - 0xd0, 0x03, 0x9e, 0x97, 0xc7, 0x3f, 0xe0, 0xc9, 0x8f, 0x70, 0x7a, 0xe7, 0x3b, 0xff, 0xf3, 0x13, - 0xf0, 0x00, 0x7f, 0x98, 0xc8, 0x71, 0xf5, 0x5b, 0xa6, 0xb5, 0xeb, 0xbd, 0x10, 0xc5, 0xbf, 0xf9, - 0x39, 0xcf, 0x13, 0xfc, 0x15, 0x24, 0x91, 0x3a, 0xe2, 0x9d, 0xa8, 0xa1, 0xcf, 0x8b, 0x8e, 0xbc, - 0x1f, 0x30, 0xea, 0x98, 0xe6, 0x61, 0x6f, 0x50, 0x8d, 0x78, 0xe9, 0x2a, 0xe2, 0x8d, 0xaa, 0xb9, - 0xc3, 0xdf, 0x6b, 0x98, 0x3b, 0xf4, 0xf0, 0xab, 0xf2, 0x41, 0x09, 0xa6, 0x6e, 0x98, 0x8e, 0x6b, - 0x77, 0x4d, 0x43, 0x6f, 0x51, 0x47, 0xe2, 0xb9, 0xb1, 0x2f, 0xb4, 0x95, 0xd3, 0x64, 0x1a, 0xe3, - 0x2f, 0x59, 0xed, 0x89, 0x3b, 0x65, 0xc9, 0xdb, 0x7a, 0x8b, 0x5d, 0x26, 0x0b, 0x3e, 0x85, 0xd7, - 0x2f, 0xf6, 0xc0, 0xfc, 0x1a, 0x44, 0x61, 0xbc, 0xc5, 0x58, 0x41, 0x52, 0x7e, 0x20, 0x06, 0x79, - 0xba, 0xc0, 0x71, 0xe8, 0x82, 0x98, 0x2e, 0xb9, 0x6e, 0x42, 0xa2, 0xab, 0xbb, 0x7c, 0x19, 0x52, - 0xbe, 0x76, 0xe4, 0xe7, 0xaf, 0x58, 0x29, 0x14, 0x03, 0xbd, 0x0b, 0x52, 0x6d, 0x7d, 0x5f, 0xa3, - 0x78, 0xb1, 0xb7, 0x84, 0x37, 0xd9, 0xd6, 0xf7, 0x49, 0xfd, 0xd0, 0x37, 0x41, 0x9e, 0x40, 0x1a, - 0x7b, 0xba, 0xb5, 0x8b, 0x19, 0x72, 0xfc, 0x2d, 0x21, 0xe7, 0xda, 0xfa, 0x7e, 0x85, 0xa2, 0x11, - 0x7c, 0xfe, 0x4c, 0xd8, 0xaf, 0x48, 0x7c, 0x75, 0x49, 0x05, 0x83, 0x74, 0x90, 0x0d, 0xef, 0x8b, - 0x16, 0x2a, 0x82, 0xb6, 0xe7, 0x87, 0xc9, 0xbe, 0x4f, 0xac, 0xe5, 0x1c, 0xa9, 0xde, 0x67, 0xde, - 0x9c, 0x97, 0x58, 0xa9, 0x79, 0x63, 0x40, 0xec, 0x19, 0xb6, 0x6a, 0xd6, 0xa8, 0x7f, 0x13, 0x1b, - 0xe9, 0xdf, 0xe4, 0x84, 0x7f, 0xc3, 0x00, 0x81, 0x71, 0x93, 0x7c, 0xde, 0x86, 0x4f, 0x48, 0x90, - 0x59, 0x0a, 0x3c, 0xdd, 0x59, 0x80, 0xc9, 0xb6, 0x6d, 0x99, 0xb7, 0x70, 0xd7, 0x8b, 0xba, 0xb3, - 0x4f, 0xe2, 0x83, 0xb0, 0x5f, 0x80, 0x74, 0x0f, 0xc4, 0x03, 0x2a, 0xe2, 0x9b, 0x70, 0xdd, 0xc1, - 0xdb, 0x8e, 0x29, 0xe4, 0xac, 0x8a, 0x4f, 0xf4, 0x30, 0xc8, 0x0e, 0x36, 0x7a, 0x5d, 0xd3, 0x3d, - 0xd0, 0x0c, 0xdb, 0x72, 0x75, 0xc3, 0xe5, 0x8b, 0xb5, 0xbc, 0x48, 0xaf, 0xb0, 0x64, 0x02, 0xd2, - 0xc4, 0xae, 0x6e, 0xb6, 0xd8, 0x61, 0xb4, 0xb4, 0x2a, 0x3e, 0x79, 0x55, 0xef, 0x4e, 0x06, 0x97, - 0x2a, 0x15, 0x90, 0xed, 0x0e, 0xee, 0x86, 0x76, 0xdd, 0x99, 0x36, 0x16, 0x7e, 0xeb, 0xd3, 0x8f, - 0xcd, 0x72, 0x81, 0xf3, 0xfd, 0x5a, 0x76, 0x03, 0x4b, 0xcd, 0x0b, 0x0e, 0xb1, 0x1d, 0xff, 0x4a, - 0x28, 0xce, 0xde, 0xdb, 0xf6, 0xdf, 0x2e, 0x9a, 0x1d, 0x10, 0x6a, 0xc9, 0x3a, 0x28, 0x17, 0x7e, - 0xc3, 0x87, 0xe6, 0x8b, 0x99, 0x0d, 0xba, 0x70, 0x09, 0xc6, 0xdc, 0x29, 0x0c, 0x71, 0xef, 0x5e, - 0xd3, 0xcd, 0x96, 0xf8, 0xb1, 0x5c, 0x95, 0x7f, 0xa1, 0xa2, 0x17, 0x47, 0x4a, 0x50, 0x6f, 0x59, - 0x19, 0xa6, 0x1b, 0x65, 0xdb, 0x6a, 0x86, 0xc3, 0x47, 0xa8, 0x02, 0x49, 0xd7, 0xbe, 0x85, 0x2d, - 0x2e, 0xa0, 0xf2, 0x23, 0x47, 0x78, 0xe7, 0x4e, 0xe5, 0xac, 0xe8, 0x1b, 0x40, 0x6e, 0xe2, 0x16, - 0xde, 0x65, 0x97, 0x4d, 0xf7, 0xf4, 0x2e, 0x66, 0xaf, 0x1e, 0xdc, 0xd3, 0x2b, 0x76, 0x79, 0x0f, - 0xaa, 0x4e, 0x91, 0xd0, 0x46, 0xf8, 0x71, 0xd8, 0x49, 0x6f, 0x8b, 0x38, 0xb2, 0x8d, 0x01, 0xcd, - 0x0b, 0x5a, 0x9f, 0xd0, 0x63, 0xb2, 0x0f, 0x83, 0xdc, 0xb3, 0xb6, 0x6d, 0x8b, 0xfe, 0xc6, 0x24, - 0xf7, 0xb0, 0x53, 0x6c, 0xef, 0xc5, 0x4b, 0xe7, 0x7b, 0x2f, 0x1b, 0x30, 0xe5, 0x93, 0xd2, 0x11, - 0x92, 0x3e, 0xea, 0x08, 0xc9, 0x79, 0x00, 0x84, 0x04, 0xad, 0x02, 0xf8, 0x63, 0x90, 0x46, 0xfe, - 0x33, 0xc3, 0x7b, 0xcc, 0x1f, 0xcd, 0xc1, 0xc6, 0x04, 0x00, 0x90, 0x05, 0x33, 0x6d, 0xd3, 0xd2, - 0x1c, 0xdc, 0xda, 0xd1, 0xb8, 0xe4, 0x08, 0x6e, 0x86, 0x8a, 0xff, 0x85, 0x23, 0xf4, 0xe6, 0xef, - 0x7c, 0xfa, 0xb1, 0xbc, 0xff, 0xfc, 0xdf, 0xc2, 0xe3, 0x8b, 0x57, 0x9f, 0x52, 0xa7, 0xdb, 0xa6, - 0x55, 0xc7, 0xad, 0x9d, 0x25, 0x0f, 0x18, 0x3d, 0x07, 0xa7, 0x7d, 0x81, 0xd8, 0x96, 0xb6, 0x67, - 0xb7, 0x9a, 0x5a, 0x17, 0xef, 0x68, 0x06, 0x7d, 0xbc, 0x30, 0x4b, 0xc5, 0x78, 0xd2, 0x23, 0x59, - 0xb7, 0x6e, 0xd8, 0xad, 0xa6, 0x8a, 0x77, 0x2a, 0x24, 0x1b, 0x9d, 0x03, 0x5f, 0x1a, 0x9a, 0xd9, - 0x74, 0x0a, 0xb9, 0x85, 0xf8, 0x85, 0x84, 0x9a, 0xf5, 0x12, 0x6b, 0x4d, 0xa7, 0x98, 0x7a, 0xff, - 0xc7, 0xe6, 0x8f, 0x7d, 0xfe, 0x63, 0xf3, 0xc7, 0x94, 0x65, 0xfa, 0xba, 0x19, 0x1f, 0x5a, 0xd8, - 0x41, 0xd7, 0x20, 0xad, 0x8b, 0x0f, 0x76, 0x69, 0xe9, 0x90, 0xa1, 0xe9, 0x93, 0x2a, 0x9f, 0x94, - 0x20, 0xb9, 0xb4, 0xb5, 0xa1, 0x9b, 0x5d, 0x54, 0x85, 0x69, 0x5f, 0x57, 0xc7, 0x1d, 0xe5, 0xbe, - 0x7a, 0x8b, 0x61, 0xbe, 0x36, 0xec, 0x88, 0x4e, 0xba, 0x7c, 0xf6, 0xb7, 0x3e, 0xfd, 0xd8, 0xfd, - 0x1c, 0x66, 0xab, 0xef, 0xb4, 0x8e, 0xc0, 0xeb, 0x3f, 0xc5, 0x13, 0x68, 0xf3, 0x4d, 0x98, 0x64, - 0x55, 0x75, 0xd0, 0x8b, 0x30, 0xd1, 0x21, 0x7f, 0xf0, 0x00, 0xee, 0x99, 0xa1, 0x3a, 0x4f, 0xe9, - 0x83, 0x1a, 0xc2, 0xf8, 0x94, 0xef, 0x8c, 0x01, 0x2c, 0x6d, 0x6d, 0x35, 0xba, 0x66, 0xa7, 0x85, - 0xdd, 0xb7, 0xab, 0xed, 0x9b, 0x70, 0x3c, 0x70, 0xb7, 0xbc, 0x6b, 0x1c, 0xbd, 0xfd, 0x33, 0xfe, - 0x2d, 0xf3, 0xae, 0x11, 0x09, 0xdb, 0x74, 0x5c, 0x0f, 0x36, 0x7e, 0x74, 0xd8, 0x25, 0xc7, 0x1d, - 0x94, 0xec, 0xcb, 0x90, 0xf1, 0x85, 0xe1, 0xa0, 0x1a, 0xa4, 0x5c, 0xfe, 0x37, 0x17, 0xb0, 0x32, - 0x5c, 0xc0, 0x82, 0x2d, 0x28, 0x64, 0x8f, 0x5d, 0xf9, 0x4b, 0x09, 0x20, 0x30, 0x46, 0xbe, 0x36, - 0x75, 0x0c, 0xd5, 0x20, 0xc9, 0x8d, 0x73, 0xfc, 0x9e, 0x9f, 0x18, 0x65, 0x00, 0x01, 0xa1, 0x7e, - 0x77, 0x0c, 0x66, 0x36, 0xc5, 0xe8, 0xfd, 0xda, 0x97, 0xc1, 0x26, 0x4c, 0x62, 0xcb, 0xed, 0x9a, - 0xde, 0x06, 0xc4, 0xe3, 0xc3, 0xfa, 0x3c, 0xa2, 0x51, 0x55, 0xcb, 0xed, 0x1e, 0x04, 0x35, 0x40, - 0x60, 0x05, 0xe4, 0xf1, 0xe1, 0x38, 0x14, 0x86, 0xb1, 0xa2, 0xf3, 0x90, 0x37, 0xba, 0x98, 0x26, - 0x84, 0xef, 0xd0, 0x4d, 0x89, 0x64, 0x3e, 0xed, 0xa8, 0x40, 0x1c, 0x35, 0xa2, 0x5c, 0x84, 0xf4, - 0xde, 0x3c, 0xb3, 0x29, 0x1f, 0x81, 0x4e, 0x3c, 0x0d, 0xc8, 0x8b, 0x93, 0xf7, 0xdb, 0x7a, 0x4b, - 0xb7, 0x0c, 0xe1, 0xc1, 0x1e, 0x69, 0xce, 0x17, 0xa7, 0xf7, 0xcb, 0x0c, 0x02, 0x55, 0x61, 0x52, - 0xa0, 0x25, 0x8e, 0x8e, 0x26, 0x78, 0xd1, 0x59, 0xc8, 0x06, 0x27, 0x06, 0xea, 0x8d, 0x24, 0xd4, - 0x4c, 0x60, 0x5e, 0x18, 0x35, 0xf3, 0x24, 0x0f, 0x9d, 0x79, 0xb8, 0xc3, 0xf7, 0xc3, 0x71, 0x98, - 0x56, 0x71, 0xf3, 0xaf, 0x7f, 0xb7, 0x6c, 0x00, 0xb0, 0xa1, 0x4a, 0x2c, 0x29, 0xef, 0x99, 0x7b, - 0x18, 0xef, 0x69, 0x06, 0xb2, 0xe4, 0xb8, 0x5f, 0xad, 0x1e, 0xfa, 0xdd, 0x18, 0x64, 0x83, 0x3d, - 0xf4, 0x37, 0x72, 0xd2, 0x42, 0x6b, 0xbe, 0x99, 0x62, 0x77, 0x07, 0x1e, 0x1e, 0x66, 0xa6, 0x06, - 0xb4, 0x79, 0x84, 0x7d, 0xfa, 0x42, 0x1c, 0x92, 0xfc, 0x0c, 0xcf, 0xfa, 0x80, 0x6f, 0x3b, 0xf2, - 0x02, 0x75, 0x4e, 0xdc, 0x41, 0x8f, 0x74, 0x6d, 0x1f, 0x84, 0x29, 0xb2, 0x46, 0x0e, 0x1d, 0x0c, - 0x92, 0x2e, 0xe4, 0xe8, 0x52, 0xd7, 0x3f, 0x18, 0x8b, 0xe6, 0x21, 0x43, 0xc8, 0x7c, 0x3b, 0x4c, - 0x68, 0xa0, 0xad, 0xef, 0x57, 0x59, 0x0a, 0xba, 0x0c, 0x68, 0xcf, 0x0b, 0x5c, 0x68, 0xbe, 0x20, - 0xa4, 0x0b, 0x39, 0xfa, 0x9a, 0xc0, 0xb4, 0x9f, 0x2b, 0x58, 0xee, 0x07, 0x20, 0x35, 0xd1, 0xd8, - 0xcb, 0xda, 0xfc, 0xdd, 0x72, 0x92, 0xb2, 0x44, 0x5f, 0xd7, 0xfe, 0x36, 0x89, 0xb9, 0xc9, 0x7d, - 0xab, 0x69, 0xbe, 0x4a, 0x69, 0x8c, 0x31, 0x30, 0xfe, 0xfc, 0xcd, 0xf9, 0xb9, 0x03, 0xbd, 0xdd, - 0x2a, 0x2a, 0x11, 0x38, 0x4a, 0xd4, 0x02, 0x9f, 0x38, 0xcf, 0xe1, 0xd5, 0x38, 0xaa, 0x81, 0x7c, - 0x0b, 0x1f, 0x68, 0x5d, 0xfe, 0xc3, 0xec, 0xda, 0x0e, 0x16, 0xef, 0x18, 0x9c, 0x5a, 0x8c, 0x78, - 0xe7, 0x7c, 0xb1, 0x62, 0x9b, 0x16, 0xdf, 0xa3, 0x98, 0xba, 0x85, 0x0f, 0x54, 0xce, 0xb7, 0x8c, - 0x71, 0xf1, 0x01, 0x32, 0x5a, 0xde, 0xf8, 0xc3, 0x9f, 0xbd, 0x78, 0x3a, 0xf0, 0x66, 0xf7, 0xbe, - 0x17, 0x27, 0x63, 0x5d, 0x4c, 0x1c, 0x5f, 0xe4, 0x4f, 0x42, 0x81, 0xc3, 0x60, 0x10, 0x58, 0x2b, - 0x48, 0x87, 0xaf, 0x41, 0x7c, 0xfe, 0xd0, 0x1a, 0x24, 0x30, 0x44, 0x5f, 0xf0, 0xe7, 0x80, 0xd8, - 0xa8, 0xd6, 0x04, 0xb5, 0x93, 0x33, 0xd1, 0x91, 0x7f, 0x4c, 0xf9, 0x0f, 0x12, 0x9c, 0x1a, 0xd0, - 0x66, 0xaf, 0xca, 0x06, 0xa0, 0x6e, 0x20, 0x93, 0x6a, 0x85, 0xd8, 0x0f, 0xbc, 0xb7, 0xc1, 0x31, - 0xdd, 0x1d, 0x98, 0x08, 0xde, 0x9e, 0xc9, 0x8c, 0x5b, 0xb2, 0x5f, 0x97, 0x60, 0x36, 0x58, 0x01, - 0xaf, 0x29, 0x75, 0xc8, 0x06, 0x8b, 0xe6, 0x8d, 0x78, 0x60, 0x9c, 0x46, 0x04, 0xeb, 0x1f, 0x02, - 0x41, 0x5b, 0xbe, 0xc5, 0x60, 0xd1, 0xb9, 0xcb, 0x63, 0x0b, 0x45, 0x54, 0x2c, 0xd2, 0x72, 0xb0, - 0xbe, 0xf9, 0x82, 0x04, 0x89, 0x0d, 0xdb, 0x6e, 0xa1, 0xf7, 0xc0, 0xb4, 0x65, 0xbb, 0x1a, 0x19, - 0x59, 0xb8, 0xa9, 0xf1, 0xd0, 0x01, 0xb3, 0xc6, 0xd5, 0x43, 0x65, 0xf5, 0x47, 0x6f, 0xce, 0x0f, - 0x72, 0x46, 0xbd, 0x9b, 0x9f, 0xb7, 0x6c, 0xb7, 0x4c, 0x89, 0x1a, 0x2c, 0xba, 0xb0, 0x03, 0xb9, - 0x70, 0x71, 0xcc, 0x62, 0x97, 0x46, 0x15, 0x97, 0x1b, 0x59, 0x54, 0x76, 0x3b, 0x50, 0x0e, 0x7b, - 0x21, 0xfc, 0x4f, 0x49, 0xcf, 0x7d, 0x13, 0xc8, 0x5b, 0xfd, 0xa7, 0x4d, 0x96, 0x61, 0x52, 0x9c, - 0x2e, 0x91, 0xc6, 0x3d, 0xb9, 0x12, 0x94, 0x27, 0x67, 0xa6, 0xe1, 0xcf, 0xcf, 0xc4, 0xe0, 0x54, - 0xc5, 0xb6, 0x1c, 0x1e, 0xe8, 0xe1, 0xa3, 0x9a, 0xc5, 0x6a, 0x0f, 0xd0, 0xc3, 0x43, 0xc2, 0x50, - 0xd9, 0xc1, 0x60, 0xd3, 0x16, 0xe4, 0xc9, 0x14, 0x6b, 0xd8, 0xd6, 0x5b, 0x8c, 0x35, 0xe5, 0xec, - 0x56, 0x93, 0xd7, 0xe8, 0x16, 0x3e, 0x20, 0xb8, 0x16, 0xbe, 0x13, 0xc2, 0x8d, 0xdf, 0x1b, 0xae, - 0x85, 0xef, 0x04, 0x70, 0xfd, 0x0d, 0xcd, 0x44, 0x68, 0x43, 0xf3, 0x1a, 0xc4, 0x89, 0x29, 0x9c, - 0x38, 0x82, 0xf1, 0x20, 0x0c, 0x81, 0x69, 0xad, 0x0e, 0xa7, 0x78, 0xa4, 0xc0, 0x59, 0xdf, 0xa1, - 0x12, 0xc5, 0xb4, 0x41, 0x2f, 0xe1, 0x83, 0x88, 0xb0, 0x41, 0x76, 0xac, 0xb0, 0xc1, 0xc5, 0x5f, - 0x90, 0x00, 0xfc, 0x98, 0x19, 0x7a, 0x14, 0x4e, 0x96, 0xd7, 0xd7, 0x96, 0xfc, 0xbd, 0x9d, 0xc0, - 0x8f, 0x07, 0x89, 0x77, 0xbc, 0x9c, 0x0e, 0x36, 0xcc, 0x1d, 0x13, 0x37, 0xd1, 0x43, 0x30, 0x1b, - 0xa6, 0x26, 0x5f, 0xd5, 0x25, 0x59, 0x9a, 0xcb, 0xbe, 0x71, 0x77, 0x21, 0xc5, 0xd6, 0x08, 0xb8, - 0x89, 0x2e, 0xc0, 0xf1, 0x41, 0xba, 0xda, 0xda, 0x75, 0x39, 0x36, 0x97, 0x7b, 0xe3, 0xee, 0x42, - 0xda, 0x5b, 0x4c, 0x20, 0x05, 0x50, 0x90, 0x92, 0xe3, 0xc5, 0xe7, 0xe0, 0x8d, 0xbb, 0x0b, 0x49, - 0x36, 0x64, 0xf8, 0xa6, 0xd0, 0x37, 0x02, 0xd4, 0xac, 0x9d, 0xae, 0x6e, 0x50, 0xd3, 0x30, 0x07, - 0x27, 0x6a, 0x6b, 0xcb, 0x6a, 0xa9, 0xd2, 0xa8, 0xad, 0xaf, 0xf5, 0xfd, 0xe6, 0x51, 0x38, 0x6f, - 0x69, 0x7d, 0xb3, 0xbc, 0x52, 0xd5, 0xea, 0xb5, 0xeb, 0x6b, 0x6c, 0x07, 0x37, 0x94, 0xf7, 0xee, - 0xb5, 0x46, 0x6d, 0xb5, 0x2a, 0xc7, 0xca, 0xd7, 0x86, 0x6e, 0xf6, 0xdc, 0x17, 0x1a, 0x8c, 0xfe, - 0x74, 0x14, 0xfa, 0x31, 0x89, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xdf, 0xae, 0x10, 0xc3, 0x37, - 0xa7, 0x00, 0x00, + // 11876 bytes of a gzipped FileDescriptorSet + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6b, 0x94, 0x24, 0xd7, + 0x59, 0xd8, 0x56, 0x77, 0x4f, 0x4f, 0xf7, 0xd7, 0xaf, 0x9a, 0x3b, 0xb3, 0xbb, 0xb3, 0xb3, 0xd2, + 0xce, 0x6c, 0xad, 0xa4, 0x5d, 0xad, 0xa4, 0x59, 0xed, 0x4a, 0xbb, 0x92, 0x5a, 0x96, 0x44, 0xf7, + 0x4c, 0xef, 0x6c, 0xaf, 0xe6, 0xe5, 0xea, 0x9e, 0xb5, 0x24, 0x1e, 0x45, 0x4d, 0xf5, 0x9d, 0x99, + 0xd2, 0x76, 0x57, 0xb5, 0xab, 0xaa, 0x77, 0x77, 0x94, 0x73, 0x72, 0x4c, 0xc0, 0x8e, 0x11, 0x8f, + 0x98, 0x40, 0xc0, 0xd8, 0x5e, 0x23, 0x20, 0x60, 0x1b, 0x02, 0x81, 0xd8, 0x10, 0x1c, 0x4e, 0x1e, + 0xe4, 0x24, 0x04, 0xc8, 0x09, 0x71, 0xf8, 0x11, 0x38, 0x9c, 0x83, 0x02, 0x36, 0xe7, 0xe0, 0x60, + 0x43, 0x80, 0x18, 0x0e, 0x27, 0x3e, 0xc9, 0xc9, 0xb9, 0xaf, 0x7a, 0x74, 0x57, 0x4f, 0xf7, 0xac, + 0x24, 0x43, 0x20, 0x7f, 0x76, 0xa7, 0xee, 0xfd, 0xbe, 0xef, 0xde, 0xfb, 0xdd, 0xef, 0x7e, 0xaf, + 0xfb, 0x68, 0xf8, 0xbd, 0xab, 0xb0, 0xb0, 0x6b, 0xdb, 0xbb, 0x6d, 0x7c, 0xa1, 0xeb, 0xd8, 0x9e, + 0xbd, 0xdd, 0xdb, 0xb9, 0xd0, 0xc2, 0xae, 0xe1, 0x98, 0x5d, 0xcf, 0x76, 0x16, 0x69, 0x19, 0x2a, + 0x31, 0x88, 0x45, 0x01, 0xa1, 0xac, 0xc1, 0xd4, 0x55, 0xb3, 0x8d, 0x97, 0x7d, 0xc0, 0x06, 0xf6, + 0xd0, 0xd3, 0x90, 0xda, 0x31, 0xdb, 0x78, 0x56, 0x5a, 0x48, 0x9e, 0xcb, 0x5d, 0x7a, 0x60, 0xb1, + 0x0f, 0x69, 0x31, 0x8a, 0xb1, 0x49, 0x8a, 0x55, 0x8a, 0xa1, 0xfc, 0x9f, 0x14, 0x4c, 0xc7, 0xd4, + 0x22, 0x04, 0x29, 0x4b, 0xef, 0x10, 0x8a, 0xd2, 0xb9, 0xac, 0x4a, 0xff, 0x46, 0xb3, 0x30, 0xd9, + 0xd5, 0x8d, 0x9b, 0xfa, 0x2e, 0x9e, 0x4d, 0xd0, 0x62, 0xf1, 0x89, 0x4e, 0x01, 0xb4, 0x70, 0x17, + 0x5b, 0x2d, 0x6c, 0x19, 0xfb, 0xb3, 0xc9, 0x85, 0xe4, 0xb9, 0xac, 0x1a, 0x2a, 0x41, 0x8f, 0xc0, + 0x54, 0xb7, 0xb7, 0xdd, 0x36, 0x0d, 0x2d, 0x04, 0x06, 0x0b, 0xc9, 0x73, 0x13, 0xaa, 0xcc, 0x2a, + 0x96, 0x03, 0xe0, 0xb3, 0x50, 0xba, 0x8d, 0xf5, 0x9b, 0x61, 0xd0, 0x1c, 0x05, 0x2d, 0x92, 0xe2, + 0x10, 0xe0, 0x12, 0xe4, 0x3b, 0xd8, 0x75, 0xf5, 0x5d, 0xac, 0x79, 0xfb, 0x5d, 0x3c, 0x9b, 0xa2, + 0xa3, 0x5f, 0x18, 0x18, 0x7d, 0xff, 0xc8, 0x73, 0x1c, 0xab, 0xb9, 0xdf, 0xc5, 0xa8, 0x02, 0x59, + 0x6c, 0xf5, 0x3a, 0x8c, 0xc2, 0xc4, 0x10, 0xfe, 0xd5, 0xac, 0x5e, 0xa7, 0x9f, 0x4a, 0x86, 0xa0, + 0x71, 0x12, 0x93, 0x2e, 0x76, 0x6e, 0x99, 0x06, 0x9e, 0x4d, 0x53, 0x02, 0x67, 0x07, 0x08, 0x34, + 0x58, 0x7d, 0x3f, 0x0d, 0x81, 0x87, 0x96, 0x20, 0x8b, 0xef, 0x78, 0xd8, 0x72, 0x4d, 0xdb, 0x9a, + 0x9d, 0xa4, 0x44, 0x1e, 0x8c, 0x99, 0x45, 0xdc, 0x6e, 0xf5, 0x93, 0x08, 0xf0, 0xd0, 0x15, 0x98, + 0xb4, 0xbb, 0x9e, 0x69, 0x5b, 0xee, 0x6c, 0x66, 0x41, 0x3a, 0x97, 0xbb, 0x74, 0x5f, 0xac, 0x20, + 0x6c, 0x30, 0x18, 0x55, 0x00, 0xa3, 0x3a, 0xc8, 0xae, 0xdd, 0x73, 0x0c, 0xac, 0x19, 0x76, 0x0b, + 0x6b, 0xa6, 0xb5, 0x63, 0xcf, 0x66, 0x29, 0x81, 0xf9, 0xc1, 0x81, 0x50, 0xc0, 0x25, 0xbb, 0x85, + 0xeb, 0xd6, 0x8e, 0xad, 0x16, 0xdd, 0xc8, 0x37, 0x3a, 0x06, 0x69, 0x77, 0xdf, 0xf2, 0xf4, 0x3b, + 0xb3, 0x79, 0x2a, 0x21, 0xfc, 0x8b, 0x88, 0x0e, 0x6e, 0x99, 0xa4, 0xb9, 0xd9, 0x02, 0x13, 0x1d, + 0xfe, 0xa9, 0x7c, 0x36, 0x0d, 0xa5, 0x71, 0x84, 0xef, 0x59, 0x98, 0xd8, 0x21, 0xe3, 0x9f, 0x4d, + 0x1c, 0x86, 0x3b, 0x0c, 0x27, 0xca, 0xde, 0xf4, 0x3d, 0xb2, 0xb7, 0x02, 0x39, 0x0b, 0xbb, 0x1e, + 0x6e, 0x31, 0x59, 0x49, 0x8e, 0x29, 0x6d, 0xc0, 0x90, 0x06, 0x85, 0x2d, 0x75, 0x4f, 0xc2, 0xf6, + 0x12, 0x94, 0xfc, 0x2e, 0x69, 0x8e, 0x6e, 0xed, 0x0a, 0xa9, 0xbd, 0x30, 0xaa, 0x27, 0x8b, 0x35, + 0x81, 0xa7, 0x12, 0x34, 0xb5, 0x88, 0x23, 0xdf, 0x68, 0x19, 0xc0, 0xb6, 0xb0, 0xbd, 0xa3, 0xb5, + 0xb0, 0xd1, 0x9e, 0xcd, 0x0c, 0xe1, 0xd2, 0x06, 0x01, 0x19, 0xe0, 0x92, 0xcd, 0x4a, 0x8d, 0x36, + 0x7a, 0x26, 0x10, 0xc2, 0xc9, 0x21, 0x32, 0xb4, 0xc6, 0x96, 0xdf, 0x80, 0x1c, 0x6e, 0x41, 0xd1, + 0xc1, 0x64, 0x45, 0xe0, 0x16, 0x1f, 0x59, 0x96, 0x76, 0x62, 0x71, 0xe4, 0xc8, 0x54, 0x8e, 0xc6, + 0x06, 0x56, 0x70, 0xc2, 0x9f, 0xe8, 0x0c, 0xf8, 0x05, 0x1a, 0x15, 0x2b, 0xa0, 0xfa, 0x29, 0x2f, + 0x0a, 0xd7, 0xf5, 0x0e, 0x9e, 0x7b, 0x0d, 0x8a, 0x51, 0xf6, 0xa0, 0x19, 0x98, 0x70, 0x3d, 0xdd, + 0xf1, 0xa8, 0x14, 0x4e, 0xa8, 0xec, 0x03, 0xc9, 0x90, 0xc4, 0x56, 0x8b, 0xea, 0xbf, 0x09, 0x95, + 0xfc, 0x89, 0xbe, 0x2e, 0x18, 0x70, 0x92, 0x0e, 0xf8, 0xa1, 0xc1, 0x19, 0x8d, 0x50, 0xee, 0x1f, + 0xf7, 0xdc, 0x53, 0x50, 0x88, 0x0c, 0x60, 0xdc, 0xa6, 0x95, 0x9f, 0x4a, 0xc1, 0xd1, 0x58, 0xda, + 0xe8, 0x25, 0x98, 0xe9, 0x59, 0xa6, 0xe5, 0x61, 0xa7, 0xeb, 0x60, 0x22, 0xb2, 0xac, 0xad, 0xd9, + 0x3f, 0x98, 0x1c, 0x22, 0x74, 0x5b, 0x61, 0x68, 0x46, 0x45, 0x9d, 0xee, 0x0d, 0x16, 0xa2, 0x97, + 0x21, 0x47, 0xe4, 0x43, 0x77, 0x74, 0x4a, 0x90, 0xad, 0xc6, 0x4b, 0xe3, 0x0d, 0x79, 0x71, 0x39, + 0xc0, 0xac, 0x26, 0x3f, 0x28, 0x25, 0xd4, 0x30, 0x2d, 0xb4, 0x07, 0xf9, 0x5b, 0xd8, 0x31, 0x77, + 0x4c, 0x83, 0xd1, 0x26, 0xec, 0x2c, 0x5e, 0x7a, 0x7a, 0x4c, 0xda, 0x37, 0x42, 0xa8, 0x0d, 0x4f, + 0xf7, 0x70, 0x19, 0xb6, 0xd6, 0x6f, 0xd4, 0xd4, 0xfa, 0xd5, 0x7a, 0x6d, 0x59, 0x8d, 0x50, 0x9e, + 0xfb, 0xb4, 0x04, 0xb9, 0x50, 0x5f, 0x88, 0xda, 0xb2, 0x7a, 0x9d, 0x6d, 0xec, 0x70, 0x8e, 0xf3, + 0x2f, 0x74, 0x12, 0xb2, 0x3b, 0xbd, 0x76, 0x9b, 0x89, 0x0d, 0xb3, 0x79, 0x19, 0x52, 0x40, 0x44, + 0x86, 0x68, 0x29, 0xae, 0x08, 0xa8, 0x96, 0x22, 0x7f, 0xa3, 0x33, 0x90, 0x33, 0x5d, 0xcd, 0xc1, + 0x5d, 0xac, 0x7b, 0xb8, 0x35, 0x9b, 0x5a, 0x90, 0xce, 0x65, 0xaa, 0x89, 0x59, 0x49, 0x05, 0xd3, + 0x55, 0x79, 0x29, 0x9a, 0x83, 0x8c, 0x90, 0xbd, 0xd9, 0x09, 0x02, 0xa1, 0xfa, 0xdf, 0xac, 0x8e, + 0x63, 0xa7, 0x45, 0x1d, 0xfb, 0x56, 0x9e, 0x84, 0xa9, 0x81, 0x41, 0xa2, 0x12, 0xe4, 0x96, 0x6b, + 0x4b, 0xab, 0x15, 0xb5, 0xd2, 0xac, 0x6f, 0xac, 0xcb, 0x47, 0x50, 0x11, 0x42, 0xe3, 0x96, 0xa5, + 0xf3, 0xd9, 0xcc, 0x17, 0x27, 0xe5, 0xf7, 0xbd, 0xef, 0x7d, 0xef, 0x4b, 0x28, 0xbf, 0x94, 0x86, + 0x99, 0x38, 0x2d, 0x17, 0xab, 0x70, 0x03, 0x9e, 0x24, 0x23, 0x3c, 0xa9, 0xc0, 0x44, 0x5b, 0xdf, + 0xc6, 0x6d, 0x3a, 0xb8, 0xe2, 0xa5, 0x47, 0xc6, 0xd2, 0xa3, 0x8b, 0xab, 0x04, 0x45, 0x65, 0x98, + 0xe8, 0x79, 0xce, 0xb9, 0x09, 0x4a, 0xe1, 0xfc, 0x78, 0x14, 0x88, 0xf6, 0xe3, 0x5c, 0x3e, 0x09, + 0x59, 0xf2, 0x3f, 0x9b, 0x96, 0x34, 0x9b, 0x16, 0x52, 0x40, 0xa7, 0x65, 0x0e, 0x32, 0x54, 0xb1, + 0xb5, 0xb0, 0x3f, 0x65, 0xe2, 0x9b, 0xa8, 0x82, 0x16, 0xde, 0xd1, 0x7b, 0x6d, 0x4f, 0xbb, 0xa5, + 0xb7, 0x7b, 0x98, 0xaa, 0xa8, 0xac, 0x9a, 0xe7, 0x85, 0x37, 0x48, 0x19, 0x9a, 0x87, 0x1c, 0xd3, + 0x83, 0xa6, 0xd5, 0xc2, 0x77, 0xa8, 0x25, 0x9c, 0x50, 0x99, 0x6a, 0xac, 0x93, 0x12, 0xd2, 0xfc, + 0xab, 0xae, 0x6d, 0x09, 0x65, 0x42, 0x9b, 0x20, 0x05, 0xb4, 0xf9, 0xa7, 0xfa, 0x8d, 0xf0, 0xfd, + 0xf1, 0xc3, 0x1b, 0xd0, 0x7e, 0x67, 0xa1, 0x44, 0x21, 0x9e, 0xe0, 0x6b, 0x55, 0x6f, 0xcf, 0x4e, + 0x51, 0x01, 0x28, 0xb2, 0xe2, 0x0d, 0x5e, 0xaa, 0xfc, 0x7c, 0x02, 0x52, 0xd4, 0x14, 0x94, 0x20, + 0xd7, 0x7c, 0x79, 0xb3, 0xa6, 0x2d, 0x6f, 0x6c, 0x55, 0x57, 0x6b, 0xb2, 0x44, 0xa6, 0x9e, 0x16, + 0x5c, 0x5d, 0xdd, 0xa8, 0x34, 0xe5, 0x84, 0xff, 0x5d, 0x5f, 0x6f, 0x5e, 0x79, 0x52, 0x4e, 0xfa, + 0x08, 0x5b, 0xac, 0x20, 0x15, 0x06, 0x78, 0xe2, 0x92, 0x3c, 0x81, 0x64, 0xc8, 0x33, 0x02, 0xf5, + 0x97, 0x6a, 0xcb, 0x57, 0x9e, 0x94, 0xd3, 0xd1, 0x92, 0x27, 0x2e, 0xc9, 0x93, 0xa8, 0x00, 0x59, + 0x5a, 0x52, 0xdd, 0xd8, 0x58, 0x95, 0x33, 0x3e, 0xcd, 0x46, 0x53, 0xad, 0xaf, 0xaf, 0xc8, 0x59, + 0x9f, 0xe6, 0x8a, 0xba, 0xb1, 0xb5, 0x29, 0x83, 0x4f, 0x61, 0xad, 0xd6, 0x68, 0x54, 0x56, 0x6a, + 0x72, 0xce, 0x87, 0xa8, 0xbe, 0xdc, 0xac, 0x35, 0xe4, 0x7c, 0xa4, 0x5b, 0x4f, 0x5c, 0x92, 0x0b, + 0x7e, 0x13, 0xb5, 0xf5, 0xad, 0x35, 0xb9, 0x88, 0xa6, 0xa0, 0xc0, 0x9a, 0x10, 0x9d, 0x28, 0xf5, + 0x15, 0x5d, 0x79, 0x52, 0x96, 0x83, 0x8e, 0x30, 0x2a, 0x53, 0x91, 0x82, 0x2b, 0x4f, 0xca, 0x48, + 0x59, 0x82, 0x09, 0x2a, 0x86, 0x08, 0x41, 0x71, 0xb5, 0x52, 0xad, 0xad, 0x6a, 0x1b, 0x9b, 0x64, + 0xd1, 0x54, 0x56, 0x65, 0x29, 0x28, 0x53, 0x6b, 0xef, 0xde, 0xaa, 0xab, 0xb5, 0x65, 0x39, 0x11, + 0x2e, 0xdb, 0xac, 0x55, 0x9a, 0xb5, 0x65, 0x39, 0xa9, 0x18, 0x30, 0x13, 0x67, 0x02, 0x63, 0x97, + 0x50, 0x48, 0x16, 0x12, 0x43, 0x64, 0x81, 0xd2, 0xea, 0x97, 0x05, 0xe5, 0x0b, 0x09, 0x98, 0x8e, + 0x71, 0x03, 0x62, 0x1b, 0x79, 0x01, 0x26, 0x98, 0x2c, 0x33, 0x55, 0xfc, 0x70, 0xac, 0x3f, 0x41, + 0x25, 0x7b, 0xc0, 0x39, 0xa2, 0x78, 0x61, 0xb7, 0x31, 0x39, 0xc4, 0x6d, 0x24, 0x24, 0x06, 0x04, + 0xf6, 0x1b, 0x07, 0xcc, 0x35, 0xf3, 0x68, 0xae, 0x8c, 0xe3, 0xd1, 0xd0, 0xb2, 0xc3, 0x99, 0xed, + 0x89, 0x18, 0xb3, 0xfd, 0x2c, 0x4c, 0x0d, 0x10, 0x1a, 0xdb, 0x7c, 0x7e, 0xab, 0x04, 0xb3, 0xc3, + 0x98, 0x33, 0x42, 0x25, 0x26, 0x22, 0x2a, 0xf1, 0xd9, 0x7e, 0x0e, 0x9e, 0x1e, 0x3e, 0x09, 0x03, + 0x73, 0xfd, 0x09, 0x09, 0x8e, 0xc5, 0x87, 0x07, 0xb1, 0x7d, 0x78, 0x1e, 0xd2, 0x1d, 0xec, 0xed, + 0xd9, 0xc2, 0x11, 0x7e, 0x28, 0xc6, 0xbd, 0x22, 0xd5, 0xfd, 0x93, 0xcd, 0xb1, 0xc2, 0xfe, 0x59, + 0x72, 0x98, 0x8f, 0xcf, 0x7a, 0x33, 0xd0, 0xd3, 0x6f, 0x4f, 0xc0, 0xd1, 0x58, 0xe2, 0xb1, 0x1d, + 0xbd, 0x1f, 0xc0, 0xb4, 0xba, 0x3d, 0x8f, 0x39, 0xbb, 0x4c, 0x13, 0x67, 0x69, 0x09, 0x55, 0x5e, + 0x44, 0xcb, 0xf6, 0x3c, 0xbf, 0x9e, 0x19, 0x51, 0x60, 0x45, 0x14, 0xe0, 0xe9, 0xa0, 0xa3, 0x29, + 0xda, 0xd1, 0x53, 0x43, 0x46, 0x3a, 0x20, 0x98, 0x8f, 0x83, 0x6c, 0xb4, 0x4d, 0x6c, 0x79, 0x9a, + 0xeb, 0x39, 0x58, 0xef, 0x98, 0xd6, 0x2e, 0xb3, 0xb3, 0xe5, 0x89, 0x1d, 0xbd, 0xed, 0x62, 0xb5, + 0xc4, 0xaa, 0x1b, 0xa2, 0x96, 0x60, 0x50, 0x01, 0x72, 0x42, 0x18, 0xe9, 0x08, 0x06, 0xab, 0xf6, + 0x31, 0x94, 0xef, 0xc9, 0x42, 0x2e, 0x14, 0x4c, 0xa1, 0xd3, 0x90, 0x7f, 0x55, 0xbf, 0xa5, 0x6b, + 0x22, 0x40, 0x66, 0x9c, 0xc8, 0x91, 0xb2, 0x4d, 0x1e, 0x24, 0x3f, 0x0e, 0x33, 0x14, 0xc4, 0xee, + 0x79, 0xd8, 0xd1, 0x8c, 0xb6, 0xee, 0xba, 0x94, 0x69, 0x19, 0x0a, 0x8a, 0x48, 0xdd, 0x06, 0xa9, + 0x5a, 0x12, 0x35, 0xe8, 0x32, 0x4c, 0x53, 0x8c, 0x4e, 0xaf, 0xed, 0x99, 0xdd, 0x36, 0xd6, 0x48, + 0xc8, 0xee, 0x52, 0x93, 0xe3, 0xf7, 0x6c, 0x8a, 0x40, 0xac, 0x71, 0x00, 0xd2, 0x23, 0x17, 0x2d, + 0xc3, 0xfd, 0x14, 0x6d, 0x17, 0x5b, 0xd8, 0xd1, 0x3d, 0xac, 0xe1, 0xf7, 0xf6, 0xf4, 0xb6, 0xab, + 0xe9, 0x56, 0x4b, 0xdb, 0xd3, 0xdd, 0xbd, 0xd9, 0x19, 0xdf, 0x2d, 0x39, 0x41, 0x00, 0x57, 0x38, + 0x5c, 0x8d, 0x82, 0x55, 0xac, 0xd6, 0x35, 0xdd, 0xdd, 0x43, 0x65, 0x38, 0x46, 0xa9, 0xb8, 0x9e, + 0x63, 0x5a, 0xbb, 0x9a, 0xb1, 0x87, 0x8d, 0x9b, 0x5a, 0xcf, 0xdb, 0x79, 0x7a, 0xf6, 0x64, 0xb8, + 0x7d, 0xda, 0xc3, 0x06, 0x85, 0x59, 0x22, 0x20, 0x5b, 0xde, 0xce, 0xd3, 0xa8, 0x01, 0x79, 0x32, + 0x19, 0x1d, 0xf3, 0x35, 0xac, 0xed, 0xd8, 0x0e, 0xb5, 0xa1, 0xc5, 0x18, 0xd5, 0x14, 0xe2, 0xe0, + 0xe2, 0x06, 0x47, 0x58, 0xb3, 0x5b, 0xb8, 0x3c, 0xd1, 0xd8, 0xac, 0xd5, 0x96, 0xd5, 0x9c, 0xa0, + 0x72, 0xd5, 0x76, 0x88, 0x40, 0xed, 0xda, 0x3e, 0x83, 0x73, 0x4c, 0xa0, 0x76, 0x6d, 0xc1, 0xde, + 0xcb, 0x30, 0x6d, 0x18, 0x6c, 0xcc, 0xa6, 0xa1, 0xf1, 0xc0, 0xda, 0x9d, 0x95, 0x23, 0xcc, 0x32, + 0x8c, 0x15, 0x06, 0xc0, 0x65, 0xdc, 0x45, 0xcf, 0xc0, 0xd1, 0x80, 0x59, 0x61, 0xc4, 0xa9, 0x81, + 0x51, 0xf6, 0xa3, 0x5e, 0x86, 0xe9, 0xee, 0xfe, 0x20, 0x22, 0x8a, 0xb4, 0xd8, 0xdd, 0xef, 0x47, + 0x7b, 0x0a, 0x66, 0xba, 0x7b, 0xdd, 0x41, 0xbc, 0xf3, 0x61, 0x3c, 0xd4, 0xdd, 0xeb, 0xf6, 0x23, + 0x3e, 0x48, 0xb3, 0x2c, 0x0e, 0x36, 0xa8, 0x77, 0x78, 0x3c, 0x0c, 0x1e, 0xaa, 0x40, 0x8b, 0x20, + 0x1b, 0x86, 0x86, 0x2d, 0x7d, 0xbb, 0x8d, 0x35, 0xdd, 0xc1, 0x96, 0xee, 0xce, 0xce, 0x53, 0xe0, + 0x94, 0xe7, 0xf4, 0xb0, 0x5a, 0x34, 0x8c, 0x1a, 0xad, 0xac, 0xd0, 0x3a, 0x74, 0x1e, 0xa6, 0xec, + 0xed, 0x57, 0x0d, 0x26, 0x91, 0x5a, 0xd7, 0xc1, 0x3b, 0xe6, 0x9d, 0xd9, 0x07, 0x28, 0x7b, 0x4b, + 0xa4, 0x82, 0xca, 0xe3, 0x26, 0x2d, 0x46, 0x0f, 0x83, 0x6c, 0xb8, 0x7b, 0xba, 0xd3, 0xa5, 0x2a, + 0xd9, 0xed, 0xea, 0x06, 0x9e, 0x7d, 0x90, 0x81, 0xb2, 0xf2, 0x75, 0x51, 0x4c, 0x56, 0x84, 0x7b, + 0xdb, 0xdc, 0xf1, 0x04, 0xc5, 0xb3, 0x6c, 0x45, 0xd0, 0x32, 0x4e, 0xed, 0x1c, 0xc8, 0x84, 0x13, + 0x91, 0x86, 0xcf, 0x51, 0xb0, 0x62, 0x77, 0xaf, 0x1b, 0x6e, 0xf7, 0x0c, 0x14, 0x08, 0x64, 0xd0, + 0xe8, 0xc3, 0xcc, 0x71, 0xeb, 0xee, 0x85, 0x5a, 0x7c, 0x12, 0x8e, 0x11, 0xa0, 0x0e, 0xf6, 0xf4, + 0x96, 0xee, 0xe9, 0x21, 0xe8, 0x47, 0x29, 0x34, 0x61, 0xfb, 0x1a, 0xaf, 0x8c, 0xf4, 0xd3, 0xe9, + 0x6d, 0xef, 0xfb, 0x82, 0xf5, 0x18, 0xeb, 0x27, 0x29, 0x13, 0xa2, 0xf5, 0x8e, 0x45, 0x53, 0x4a, + 0x19, 0xf2, 0x61, 0xb9, 0x47, 0x59, 0x60, 0x92, 0x2f, 0x4b, 0xc4, 0x09, 0x5a, 0xda, 0x58, 0x26, + 0xee, 0xcb, 0x2b, 0x35, 0x39, 0x41, 0xdc, 0xa8, 0xd5, 0x7a, 0xb3, 0xa6, 0xa9, 0x5b, 0xeb, 0xcd, + 0xfa, 0x5a, 0x4d, 0x4e, 0x86, 0x1c, 0xfb, 0xeb, 0xa9, 0xcc, 0x43, 0xf2, 0x59, 0xe5, 0x17, 0x93, + 0x50, 0x8c, 0xc6, 0xd6, 0xe8, 0x5d, 0x70, 0x5c, 0xa4, 0xc8, 0x5c, 0xec, 0x69, 0xb7, 0x4d, 0x87, + 0x2e, 0xc8, 0x8e, 0xce, 0x8c, 0xa3, 0x2f, 0x3f, 0x33, 0x1c, 0xaa, 0x81, 0xbd, 0xf7, 0x98, 0x0e, + 0x59, 0x6e, 0x1d, 0xdd, 0x43, 0xab, 0x30, 0x6f, 0xd9, 0x9a, 0xeb, 0xe9, 0x56, 0x4b, 0x77, 0x5a, + 0x5a, 0x90, 0x9c, 0xd4, 0x74, 0xc3, 0xc0, 0xae, 0x6b, 0x33, 0x43, 0xe8, 0x53, 0xb9, 0xcf, 0xb2, + 0x1b, 0x1c, 0x38, 0xb0, 0x10, 0x15, 0x0e, 0xda, 0x27, 0xbe, 0xc9, 0x61, 0xe2, 0x7b, 0x12, 0xb2, + 0x1d, 0xbd, 0xab, 0x61, 0xcb, 0x73, 0xf6, 0xa9, 0x7f, 0x9e, 0x51, 0x33, 0x1d, 0xbd, 0x5b, 0x23, + 0xdf, 0xe8, 0x06, 0x3c, 0x14, 0x80, 0x6a, 0x6d, 0xbc, 0xab, 0x1b, 0xfb, 0x1a, 0x75, 0xc6, 0x69, + 0xa2, 0x47, 0x33, 0x6c, 0x6b, 0xa7, 0x6d, 0x1a, 0x9e, 0x4b, 0xf5, 0x03, 0xd3, 0x71, 0x4a, 0x80, + 0xb1, 0x4a, 0x11, 0xae, 0xbb, 0xb6, 0x45, 0x7d, 0xf0, 0x25, 0x01, 0xfd, 0xce, 0xcd, 0x70, 0x74, + 0x96, 0x52, 0xf2, 0xc4, 0xf5, 0x54, 0x66, 0x42, 0x4e, 0x5f, 0x4f, 0x65, 0xd2, 0xf2, 0xe4, 0xf5, + 0x54, 0x26, 0x23, 0x67, 0xaf, 0xa7, 0x32, 0x59, 0x19, 0x94, 0xf7, 0x67, 0x21, 0x1f, 0x8e, 0x0c, + 0x48, 0xa0, 0x65, 0x50, 0xdb, 0x28, 0x51, 0xed, 0x79, 0xe6, 0xc0, 0x38, 0x62, 0x71, 0x89, 0x18, + 0xcd, 0x72, 0x9a, 0xb9, 0xe1, 0x2a, 0xc3, 0x24, 0x0e, 0x0b, 0x11, 0x6b, 0xcc, 0xdc, 0x9e, 0x8c, + 0xca, 0xbf, 0xd0, 0x0a, 0xa4, 0x5f, 0x75, 0x29, 0xed, 0x34, 0xa5, 0xfd, 0xc0, 0xc1, 0xb4, 0xaf, + 0x37, 0x28, 0xf1, 0xec, 0xf5, 0x86, 0xb6, 0xbe, 0xa1, 0xae, 0x55, 0x56, 0x55, 0x8e, 0x8e, 0x4e, + 0x40, 0xaa, 0xad, 0xbf, 0xb6, 0x1f, 0x35, 0xaf, 0xb4, 0x08, 0x2d, 0x42, 0xa9, 0x67, 0xb1, 0xa8, + 0x9b, 0x4c, 0x15, 0x81, 0x2a, 0x85, 0xa1, 0x8a, 0x41, 0xed, 0x2a, 0x81, 0x1f, 0x53, 0x3c, 0x4e, + 0x40, 0xea, 0x36, 0xd6, 0x6f, 0x46, 0x8d, 0x20, 0x2d, 0x42, 0xe7, 0x20, 0xdf, 0xc2, 0xdb, 0xbd, + 0x5d, 0xcd, 0xc1, 0x2d, 0xdd, 0xf0, 0xa2, 0xaa, 0x3f, 0x47, 0xab, 0x54, 0x5a, 0x83, 0x5e, 0x84, + 0x2c, 0x99, 0x23, 0x8b, 0xce, 0xf1, 0x14, 0x65, 0xc1, 0x63, 0x07, 0xb3, 0x80, 0x4f, 0xb1, 0x40, + 0x52, 0x03, 0x7c, 0x74, 0x1d, 0xd2, 0x9e, 0xee, 0xec, 0x62, 0x8f, 0x6a, 0xfe, 0x62, 0x4c, 0xba, + 0x2a, 0x86, 0x52, 0x93, 0x62, 0x10, 0xb6, 0x52, 0x19, 0xe5, 0x14, 0xd0, 0x35, 0x98, 0x64, 0x7f, + 0xb9, 0xb3, 0xd3, 0x0b, 0xc9, 0xc3, 0x13, 0x53, 0x05, 0xfa, 0x3b, 0xa8, 0xb3, 0x2e, 0xc0, 0x04, + 0x15, 0x36, 0x04, 0xc0, 0xc5, 0x4d, 0x3e, 0x82, 0x32, 0x90, 0x5a, 0xda, 0x50, 0x89, 0xde, 0x92, + 0x21, 0xcf, 0x4a, 0xb5, 0xcd, 0x7a, 0x6d, 0xa9, 0x26, 0x27, 0x94, 0xcb, 0x90, 0x66, 0x12, 0x44, + 0x74, 0x9a, 0x2f, 0x43, 0xf2, 0x11, 0xfe, 0xc9, 0x69, 0x48, 0xa2, 0x76, 0x6b, 0xad, 0x5a, 0x53, + 0xe5, 0x84, 0xb2, 0x05, 0xa5, 0x3e, 0xae, 0xa3, 0xa3, 0x30, 0xa5, 0xd6, 0x9a, 0xb5, 0x75, 0x12, + 0xb5, 0x69, 0x5b, 0xeb, 0x2f, 0xae, 0x6f, 0xbc, 0x67, 0x5d, 0x3e, 0x12, 0x2d, 0x16, 0x0a, 0x52, + 0x42, 0x33, 0x20, 0x07, 0xc5, 0x8d, 0x8d, 0x2d, 0x95, 0xf6, 0xe6, 0x3b, 0x13, 0x20, 0xf7, 0xb3, + 0x0d, 0x1d, 0x87, 0xe9, 0x66, 0x45, 0x5d, 0xa9, 0x35, 0x35, 0x16, 0x89, 0xfa, 0xa4, 0x67, 0x40, + 0x0e, 0x57, 0x5c, 0xad, 0xd3, 0x40, 0x7b, 0x1e, 0x4e, 0x86, 0x4b, 0x6b, 0x2f, 0x35, 0x6b, 0xeb, + 0x0d, 0xda, 0x78, 0x65, 0x7d, 0x85, 0x68, 0xeb, 0x3e, 0x7a, 0x22, 0xf6, 0x4d, 0x92, 0xae, 0x46, + 0xe9, 0xd5, 0x56, 0x97, 0xe5, 0x54, 0x7f, 0xf1, 0xc6, 0x7a, 0x6d, 0xe3, 0xaa, 0x3c, 0xd1, 0xdf, + 0x3a, 0x8d, 0x87, 0xd3, 0x68, 0x0e, 0x8e, 0xf5, 0x97, 0x6a, 0xb5, 0xf5, 0xa6, 0xfa, 0xb2, 0x3c, + 0xd9, 0xdf, 0x70, 0xa3, 0xa6, 0xde, 0xa8, 0x2f, 0xd5, 0xe4, 0x0c, 0x3a, 0x06, 0x28, 0xda, 0xa3, + 0xe6, 0xb5, 0x8d, 0x65, 0x39, 0x3b, 0xa0, 0x9f, 0x14, 0x17, 0xf2, 0xe1, 0xa0, 0xf4, 0x6b, 0xa2, + 0x1a, 0x95, 0x0f, 0x27, 0x20, 0x17, 0x0a, 0x32, 0x49, 0x74, 0xa0, 0xb7, 0xdb, 0xf6, 0x6d, 0x4d, + 0x6f, 0x9b, 0xba, 0xcb, 0xb5, 0x17, 0xd0, 0xa2, 0x0a, 0x29, 0x19, 0x57, 0x5b, 0x8c, 0x6f, 0x2f, + 0xd2, 0x7f, 0x1d, 0xed, 0xc5, 0x84, 0x9c, 0x56, 0x3e, 0x2e, 0x81, 0xdc, 0x1f, 0x3d, 0xf6, 0x0d, + 0x5f, 0x1a, 0x36, 0xfc, 0xaf, 0xc9, 0xdc, 0x7d, 0x4c, 0x82, 0x62, 0x34, 0x64, 0xec, 0xeb, 0xde, + 0xe9, 0xbf, 0xd2, 0xee, 0xfd, 0x6e, 0x02, 0x0a, 0x91, 0x40, 0x71, 0xdc, 0xde, 0xbd, 0x17, 0xa6, + 0xcc, 0x16, 0xee, 0x74, 0x6d, 0x0f, 0x5b, 0xc6, 0xbe, 0xd6, 0xc6, 0xb7, 0x70, 0x7b, 0x56, 0xa1, + 0x2a, 0xfe, 0xc2, 0xc1, 0xa1, 0xe8, 0x62, 0x3d, 0xc0, 0x5b, 0x25, 0x68, 0xe5, 0xe9, 0xfa, 0x72, + 0x6d, 0x6d, 0x73, 0xa3, 0x59, 0x5b, 0x5f, 0x7a, 0x59, 0x68, 0x17, 0x55, 0x36, 0xfb, 0xc0, 0xde, + 0x41, 0xa5, 0xbd, 0x09, 0x72, 0x7f, 0xa7, 0x88, 0xae, 0x88, 0xe9, 0x96, 0x7c, 0x04, 0x4d, 0x43, + 0x69, 0x7d, 0x43, 0x6b, 0xd4, 0x97, 0x6b, 0x5a, 0xed, 0xea, 0xd5, 0xda, 0x52, 0xb3, 0xc1, 0x92, + 0x8b, 0x3e, 0x74, 0x53, 0x4e, 0x84, 0x59, 0xfc, 0x91, 0x24, 0x4c, 0xc7, 0xf4, 0x04, 0x55, 0x78, + 0x5a, 0x80, 0x65, 0x2a, 0x1e, 0x1b, 0xa7, 0xf7, 0x8b, 0xc4, 0x31, 0xdf, 0xd4, 0x1d, 0x8f, 0x67, + 0x11, 0x1e, 0x06, 0xc2, 0x25, 0xcb, 0x23, 0x7e, 0x82, 0xc3, 0x93, 0xb6, 0x2c, 0x57, 0x50, 0x0a, + 0xca, 0x59, 0xde, 0xf6, 0x51, 0x40, 0x5d, 0xdb, 0x35, 0x3d, 0xf3, 0x16, 0xd6, 0x4c, 0x4b, 0x64, + 0x78, 0x53, 0x0b, 0xd2, 0xb9, 0x94, 0x2a, 0x8b, 0x9a, 0xba, 0xe5, 0xf9, 0xd0, 0x16, 0xde, 0xd5, + 0xfb, 0xa0, 0x89, 0x1f, 0x93, 0x54, 0x65, 0x51, 0xe3, 0x43, 0x9f, 0x86, 0x7c, 0xcb, 0xee, 0x91, + 0x80, 0x8a, 0xc1, 0x11, 0x6d, 0x21, 0xa9, 0x39, 0x56, 0xe6, 0x83, 0xf0, 0x50, 0x39, 0x48, 0x2d, + 0xe7, 0xd5, 0x1c, 0x2b, 0x63, 0x20, 0x67, 0xa1, 0xa4, 0xef, 0xee, 0x3a, 0x84, 0xb8, 0x20, 0xc4, + 0x82, 0xff, 0xa2, 0x5f, 0x4c, 0x01, 0xe7, 0xae, 0x43, 0x46, 0xf0, 0x81, 0xf8, 0xc3, 0x84, 0x13, + 0x5a, 0x97, 0x65, 0xb4, 0x12, 0xe7, 0xb2, 0x6a, 0xc6, 0x12, 0x95, 0xa7, 0x21, 0x6f, 0xba, 0x5a, + 0xb0, 0xb7, 0x99, 0x58, 0x48, 0x9c, 0xcb, 0xa8, 0x39, 0xd3, 0xf5, 0xf7, 0x48, 0x94, 0x4f, 0x24, + 0xa0, 0x18, 0xdd, 0xb5, 0x45, 0xcb, 0x90, 0x69, 0xdb, 0x7c, 0x93, 0x85, 0x1d, 0x19, 0x38, 0x37, + 0x62, 0xa3, 0x77, 0x71, 0x95, 0xc3, 0xab, 0x3e, 0xe6, 0xdc, 0xaf, 0x4b, 0x90, 0x11, 0xc5, 0xe8, + 0x18, 0xa4, 0xba, 0xba, 0xb7, 0x47, 0xc9, 0x4d, 0x54, 0x13, 0xb2, 0xa4, 0xd2, 0x6f, 0x52, 0xee, + 0x76, 0x75, 0xb6, 0x4f, 0xc4, 0xcb, 0xc9, 0x37, 0x99, 0xd7, 0x36, 0xd6, 0x5b, 0x34, 0xb3, 0x60, + 0x77, 0x3a, 0xd8, 0xf2, 0x5c, 0x31, 0xaf, 0xbc, 0x7c, 0x89, 0x17, 0xa3, 0x47, 0x60, 0xca, 0x73, + 0x74, 0xb3, 0x1d, 0x81, 0x4d, 0x51, 0x58, 0x59, 0x54, 0xf8, 0xc0, 0x65, 0x38, 0x21, 0xe8, 0xb6, + 0xb0, 0xa7, 0x1b, 0x7b, 0xb8, 0x15, 0x20, 0xa5, 0x69, 0x06, 0xf1, 0x38, 0x07, 0x58, 0xe6, 0xf5, + 0x02, 0x57, 0xf9, 0x5c, 0x02, 0xa6, 0x44, 0x2e, 0xa4, 0xe5, 0x33, 0x6b, 0x0d, 0x40, 0xb7, 0x2c, + 0xdb, 0x0b, 0xb3, 0x6b, 0x50, 0x94, 0x07, 0xf0, 0x16, 0x2b, 0x3e, 0x92, 0x1a, 0x22, 0x30, 0xf7, + 0x25, 0x09, 0x20, 0xa8, 0x1a, 0xca, 0xb7, 0x79, 0xc8, 0xf1, 0x3d, 0x79, 0x7a, 0xb0, 0x83, 0xa5, + 0xcf, 0x80, 0x15, 0x5d, 0x35, 0xdb, 0x34, 0xc9, 0xb9, 0x8d, 0x77, 0x4d, 0x8b, 0xef, 0xce, 0xb0, + 0x0f, 0x91, 0xe4, 0x4c, 0x05, 0xdb, 0x93, 0x2a, 0x64, 0x5c, 0xdc, 0xd1, 0x2d, 0xcf, 0x34, 0xf8, + 0x7e, 0xcb, 0x95, 0x43, 0x75, 0x7e, 0xb1, 0xc1, 0xb1, 0x55, 0x9f, 0x8e, 0x72, 0x0e, 0x32, 0xa2, + 0x94, 0x38, 0x7e, 0xeb, 0x1b, 0xeb, 0x35, 0xf9, 0x08, 0x9a, 0x84, 0x64, 0xa3, 0xd6, 0x94, 0x25, + 0x12, 0xc4, 0x56, 0x56, 0xeb, 0x95, 0x86, 0x9c, 0xa8, 0xfe, 0x5d, 0x98, 0x36, 0xec, 0x4e, 0x7f, + 0x83, 0x55, 0xb9, 0x2f, 0x81, 0xe8, 0x5e, 0x93, 0x5e, 0x79, 0x8c, 0x03, 0xed, 0xda, 0x6d, 0xdd, + 0xda, 0x5d, 0xb4, 0x9d, 0xdd, 0xe0, 0x58, 0x0c, 0x89, 0x35, 0xdc, 0xd0, 0xe1, 0x98, 0xee, 0xf6, + 0x5f, 0x4a, 0xd2, 0x8f, 0x24, 0x92, 0x2b, 0x9b, 0xd5, 0x9f, 0x48, 0xcc, 0xad, 0x30, 0xc4, 0x4d, + 0x31, 0x1c, 0x15, 0xef, 0xb4, 0xb1, 0x41, 0x3a, 0x0f, 0x1f, 0x4d, 0xc1, 0x94, 0xde, 0x31, 0x2d, + 0xfb, 0x02, 0xfd, 0x97, 0x1f, 0xaa, 0x99, 0xa0, 0x1f, 0x73, 0x23, 0x4f, 0xdf, 0x94, 0xaf, 0x30, + 0x05, 0x86, 0x46, 0xed, 0x61, 0xcf, 0xfe, 0xe9, 0x77, 0xfe, 0xf8, 0x44, 0x90, 0xfb, 0x2c, 0xaf, + 0x81, 0x2c, 0xc2, 0x6e, 0x6c, 0x19, 0x36, 0x91, 0xb6, 0xd1, 0x34, 0xfe, 0x4c, 0xd0, 0x28, 0x71, + 0xdc, 0x1a, 0x47, 0x2d, 0xbf, 0x0b, 0x32, 0x3e, 0x99, 0x83, 0xb7, 0x93, 0x66, 0xff, 0xa7, 0x20, + 0xe2, 0x63, 0x94, 0x5f, 0x00, 0x60, 0xce, 0x0e, 0x4b, 0xcb, 0x1e, 0x8c, 0xff, 0x15, 0x81, 0x9f, + 0xa5, 0x38, 0x44, 0x0b, 0x95, 0x57, 0xa0, 0xd8, 0xb2, 0x2d, 0x4f, 0xb3, 0x3b, 0xa6, 0x87, 0x3b, + 0x5d, 0x6f, 0x7f, 0x14, 0x91, 0x3f, 0x67, 0x44, 0x32, 0x6a, 0x81, 0xe0, 0x6d, 0x08, 0x34, 0xd2, + 0x13, 0xb6, 0xb3, 0x36, 0x4e, 0x4f, 0xfe, 0xc2, 0xef, 0x09, 0xc5, 0x21, 0x3d, 0xa9, 0xd6, 0x7e, + 0xe5, 0xf3, 0xa7, 0xa4, 0xcf, 0x7d, 0xfe, 0x94, 0xf4, 0xbb, 0x9f, 0x3f, 0x25, 0x7d, 0xe8, 0x0b, + 0xa7, 0x8e, 0x7c, 0xee, 0x0b, 0xa7, 0x8e, 0xfc, 0xd6, 0x17, 0x4e, 0x1d, 0x79, 0xe5, 0x91, 0x5d, + 0xd3, 0xdb, 0xeb, 0x6d, 0x2f, 0x1a, 0x76, 0xe7, 0x82, 0x61, 0xbb, 0x1d, 0xdb, 0xe5, 0xff, 0x3d, + 0xe6, 0xb6, 0x6e, 0x72, 0xf9, 0xf1, 0xee, 0x30, 0x29, 0xd8, 0x4e, 0xb3, 0x1d, 0x35, 0xf8, 0xa3, + 0x47, 0x60, 0x66, 0xd7, 0xde, 0xb5, 0xe9, 0xe7, 0x05, 0xf2, 0x17, 0x17, 0x90, 0xac, 0x5f, 0x3a, + 0x86, 0x90, 0xac, 0xc3, 0x34, 0x07, 0xd6, 0xe8, 0xe1, 0x0e, 0x96, 0xc8, 0x42, 0x07, 0xee, 0xa2, + 0xcc, 0xfe, 0xec, 0xef, 0x53, 0x9f, 0x55, 0x9d, 0xe2, 0xa8, 0xa4, 0x8e, 0xe5, 0xba, 0xca, 0x2a, + 0x1c, 0x8d, 0xd0, 0x63, 0x16, 0x04, 0x3b, 0x23, 0x28, 0xfe, 0x7b, 0x4e, 0x71, 0x3a, 0x44, 0xb1, + 0xc1, 0x51, 0xcb, 0x4b, 0x50, 0x38, 0x0c, 0xad, 0x5f, 0xe6, 0xb4, 0xf2, 0x38, 0x4c, 0x64, 0x05, + 0x4a, 0x94, 0x88, 0xd1, 0x73, 0x3d, 0xbb, 0x43, 0xe7, 0xf0, 0x60, 0x32, 0xff, 0xe1, 0xf7, 0x99, + 0x4a, 0x2f, 0x12, 0xb4, 0x25, 0x1f, 0xab, 0x5c, 0x06, 0x7a, 0x9e, 0xa5, 0x85, 0x8d, 0xf6, 0x08, + 0x0a, 0xbf, 0xc2, 0x3b, 0xe2, 0xc3, 0x97, 0x6f, 0xc0, 0x0c, 0xf9, 0x9b, 0x5a, 0xcf, 0x70, 0x4f, + 0x46, 0x6f, 0xb9, 0xcc, 0xfe, 0x97, 0x6f, 0x65, 0x56, 0x63, 0xda, 0x27, 0x10, 0xea, 0x53, 0x68, + 0x16, 0x77, 0xb1, 0xe7, 0x61, 0xc7, 0xd5, 0xf4, 0x76, 0x5c, 0xf7, 0x42, 0x39, 0xeb, 0xd9, 0x1f, + 0xfc, 0x72, 0x74, 0x16, 0x57, 0x18, 0x66, 0xa5, 0xdd, 0x2e, 0x6f, 0xc1, 0xf1, 0x18, 0xa9, 0x18, + 0x83, 0xe6, 0x47, 0x38, 0xcd, 0x99, 0x01, 0xc9, 0x20, 0x64, 0x37, 0x41, 0x94, 0xfb, 0x73, 0x39, + 0x06, 0xcd, 0x8f, 0x72, 0x9a, 0x88, 0xe3, 0x8a, 0x29, 0x25, 0x14, 0xaf, 0xc3, 0xd4, 0x2d, 0xec, + 0x6c, 0xdb, 0x2e, 0xdf, 0x27, 0x18, 0x83, 0xdc, 0xc7, 0x38, 0xb9, 0x12, 0x47, 0xa4, 0x1b, 0x07, + 0x84, 0xd6, 0x33, 0x90, 0xd9, 0xd1, 0x0d, 0x3c, 0x06, 0x89, 0xbb, 0x9c, 0xc4, 0x24, 0x81, 0x27, + 0xa8, 0x15, 0xc8, 0xef, 0xda, 0xdc, 0x81, 0x1a, 0x8d, 0xfe, 0x71, 0x8e, 0x9e, 0x13, 0x38, 0x9c, + 0x44, 0xd7, 0xee, 0xf6, 0xda, 0xc4, 0xbb, 0x1a, 0x4d, 0xe2, 0x87, 0x04, 0x09, 0x81, 0xc3, 0x49, + 0x1c, 0x82, 0xad, 0x6f, 0x08, 0x12, 0x6e, 0x88, 0x9f, 0x2f, 0x40, 0xce, 0xb6, 0xda, 0xfb, 0xb6, + 0x35, 0x4e, 0x27, 0x7e, 0x98, 0x53, 0x00, 0x8e, 0x42, 0x08, 0x3c, 0x0b, 0xd9, 0x71, 0x27, 0xe2, + 0xc7, 0xbe, 0x2c, 0x96, 0x87, 0x98, 0x81, 0x15, 0x28, 0x09, 0x05, 0x65, 0xda, 0xd6, 0x18, 0x24, + 0x7e, 0x9c, 0x93, 0x28, 0x86, 0xd0, 0xf8, 0x30, 0x3c, 0xec, 0x7a, 0xbb, 0x78, 0x1c, 0x22, 0x9f, + 0x10, 0xc3, 0xe0, 0x28, 0x9c, 0x95, 0xdb, 0xd8, 0x32, 0xf6, 0xc6, 0xa3, 0xf0, 0x49, 0xc1, 0x4a, + 0x81, 0x43, 0x48, 0x2c, 0x41, 0xa1, 0xa3, 0x3b, 0xee, 0x9e, 0xde, 0x1e, 0x6b, 0x3a, 0x3e, 0xc5, + 0x69, 0xe4, 0x7d, 0x24, 0xce, 0x91, 0x9e, 0x75, 0x18, 0x32, 0x3f, 0x21, 0x38, 0x12, 0x42, 0xe3, + 0x4b, 0xcf, 0xf5, 0xe8, 0xa6, 0xca, 0x61, 0xa8, 0xfd, 0xa4, 0x58, 0x7a, 0x0c, 0x77, 0x2d, 0x4c, + 0xf1, 0x59, 0xc8, 0xba, 0xe6, 0x6b, 0x63, 0x91, 0xf9, 0x27, 0x62, 0xa6, 0x29, 0x02, 0x41, 0x7e, + 0x19, 0x4e, 0xc4, 0x9a, 0x89, 0x31, 0x88, 0xfd, 0x14, 0x27, 0x76, 0x2c, 0xc6, 0x54, 0x70, 0x95, + 0x70, 0x58, 0x92, 0x3f, 0x2d, 0x54, 0x02, 0xee, 0xa3, 0xb5, 0x49, 0x42, 0x5a, 0x57, 0xdf, 0x39, + 0x1c, 0xd7, 0xfe, 0xa9, 0xe0, 0x1a, 0xc3, 0x8d, 0x70, 0xad, 0x09, 0xc7, 0x38, 0xc5, 0xc3, 0xcd, + 0xeb, 0xcf, 0x08, 0xc5, 0xca, 0xb0, 0xb7, 0xa2, 0xb3, 0xfb, 0xf5, 0x30, 0xe7, 0xb3, 0x53, 0xc4, + 0x4e, 0xae, 0xd6, 0xd1, 0xbb, 0x63, 0x50, 0xfe, 0x59, 0x4e, 0x59, 0x68, 0x7c, 0x3f, 0xf8, 0x72, + 0xd7, 0xf4, 0x2e, 0x21, 0xfe, 0x12, 0xcc, 0x0a, 0xe2, 0x3d, 0xcb, 0xc1, 0x86, 0xbd, 0x6b, 0x99, + 0xaf, 0xe1, 0xd6, 0x18, 0xa4, 0xff, 0x59, 0xdf, 0x54, 0x6d, 0x85, 0xd0, 0x09, 0xe5, 0x3a, 0xc8, + 0xbe, 0xaf, 0xa2, 0x99, 0x9d, 0xae, 0xed, 0x78, 0x23, 0x28, 0x7e, 0x5a, 0xcc, 0x94, 0x8f, 0x57, + 0xa7, 0x68, 0xe5, 0x1a, 0xb0, 0x93, 0x46, 0xe3, 0x8a, 0xe4, 0x67, 0x38, 0xa1, 0x42, 0x80, 0xc5, + 0x15, 0x87, 0x61, 0x77, 0xba, 0xba, 0x33, 0x8e, 0xfe, 0xfb, 0x39, 0xa1, 0x38, 0x38, 0x0a, 0x57, + 0x1c, 0xc4, 0x5f, 0x23, 0xd6, 0x7e, 0x0c, 0x0a, 0x3f, 0x2f, 0x14, 0x87, 0xc0, 0xe1, 0x24, 0x84, + 0xc3, 0x30, 0x06, 0x89, 0x7f, 0x2e, 0x48, 0x08, 0x1c, 0x42, 0xe2, 0xdd, 0x81, 0xa1, 0x75, 0xf0, + 0xae, 0xe9, 0x7a, 0xfc, 0xa8, 0xe0, 0xc1, 0xa4, 0x7e, 0xe1, 0xcb, 0x51, 0x27, 0x4c, 0x0d, 0xa1, + 0x12, 0x4d, 0xc4, 0x3d, 0x7b, 0x1a, 0xd0, 0x8f, 0xee, 0xd8, 0x67, 0x85, 0x26, 0x0a, 0xa1, 0x91, + 0xbe, 0x85, 0x3c, 0x44, 0xc2, 0x76, 0x83, 0x84, 0xb1, 0x63, 0x90, 0xfb, 0x17, 0x7d, 0x9d, 0x6b, + 0x08, 0x5c, 0x42, 0x33, 0xe4, 0xff, 0xf4, 0xac, 0x9b, 0x78, 0x7f, 0x2c, 0xe9, 0xfc, 0xc5, 0x3e, + 0xff, 0x67, 0x8b, 0x61, 0x32, 0x1d, 0x52, 0xea, 0xf3, 0xa7, 0x46, 0x47, 0x40, 0xdf, 0xf2, 0x15, + 0x3e, 0xde, 0xa8, 0x3b, 0x55, 0x5e, 0x25, 0x42, 0x1e, 0x75, 0x7a, 0x46, 0x13, 0xfb, 0xd6, 0xaf, + 0xf8, 0x72, 0x1e, 0xf1, 0x79, 0xca, 0x57, 0xa1, 0x10, 0x71, 0x78, 0x46, 0x93, 0xfa, 0x36, 0x4e, + 0x2a, 0x1f, 0xf6, 0x77, 0xca, 0x97, 0x21, 0x45, 0x9c, 0x97, 0xd1, 0xe8, 0xef, 0xe7, 0xe8, 0x14, + 0xbc, 0xfc, 0x1c, 0x64, 0x84, 0xd3, 0x32, 0x1a, 0xf5, 0x03, 0x1c, 0xd5, 0x47, 0x21, 0xe8, 0xc2, + 0x61, 0x19, 0x8d, 0xfe, 0xf7, 0x05, 0xba, 0x40, 0x21, 0xe8, 0xe3, 0xb3, 0xf0, 0xdf, 0x7c, 0x47, + 0x8a, 0x1b, 0x1d, 0xc1, 0xbb, 0x67, 0x61, 0x92, 0x7b, 0x2a, 0xa3, 0xb1, 0xbf, 0x9d, 0x37, 0x2e, + 0x30, 0xca, 0x4f, 0xc1, 0xc4, 0x98, 0x0c, 0xff, 0x2e, 0x8e, 0xca, 0xe0, 0xcb, 0x4b, 0x90, 0x0b, + 0x79, 0x27, 0xa3, 0xd1, 0xbf, 0x9b, 0xa3, 0x87, 0xb1, 0x48, 0xd7, 0xb9, 0x77, 0x32, 0x9a, 0xc0, + 0x3f, 0x10, 0x5d, 0xe7, 0x18, 0x84, 0x6d, 0xc2, 0x31, 0x19, 0x8d, 0xfd, 0x21, 0xc1, 0x75, 0x81, + 0x52, 0x7e, 0x01, 0xb2, 0xbe, 0xb1, 0x19, 0x8d, 0xff, 0x3d, 0x1c, 0x3f, 0xc0, 0x21, 0x1c, 0x08, + 0x19, 0xbb, 0xd1, 0x24, 0xfe, 0xa1, 0xe0, 0x40, 0x08, 0x8b, 0x2c, 0xa3, 0x7e, 0x07, 0x66, 0x34, + 0xa5, 0xef, 0x15, 0xcb, 0xa8, 0xcf, 0x7f, 0x21, 0xb3, 0x49, 0x75, 0xfe, 0x68, 0x12, 0xdf, 0x27, + 0x66, 0x93, 0xc2, 0x93, 0x6e, 0xf4, 0x7b, 0x04, 0xa3, 0x69, 0xfc, 0x80, 0xe8, 0x46, 0x9f, 0x43, + 0x50, 0xde, 0x04, 0x34, 0xe8, 0x0d, 0x8c, 0xa6, 0xf7, 0x61, 0x4e, 0x6f, 0x6a, 0xc0, 0x19, 0x28, + 0xbf, 0x07, 0x8e, 0xc5, 0x7b, 0x02, 0xa3, 0xa9, 0xfe, 0xe0, 0x57, 0xfa, 0x62, 0xb7, 0xb0, 0x23, + 0x50, 0x6e, 0x06, 0x26, 0x25, 0xec, 0x05, 0x8c, 0x26, 0xfb, 0x91, 0xaf, 0x44, 0x15, 0x77, 0xd8, + 0x09, 0x28, 0x57, 0x00, 0x02, 0x03, 0x3c, 0x9a, 0xd6, 0xc7, 0x38, 0xad, 0x10, 0x12, 0x59, 0x1a, + 0xdc, 0xfe, 0x8e, 0xc6, 0xbf, 0x2b, 0x96, 0x06, 0xc7, 0x20, 0x4b, 0x43, 0x98, 0xde, 0xd1, 0xd8, + 0x1f, 0x17, 0x4b, 0x43, 0xa0, 0x10, 0xc9, 0x0e, 0x59, 0xb7, 0xd1, 0x14, 0x7e, 0x58, 0x48, 0x76, + 0x08, 0xab, 0xbc, 0x0e, 0x53, 0x03, 0x06, 0x71, 0x34, 0xa9, 0x1f, 0xe1, 0xa4, 0xe4, 0x7e, 0x7b, + 0x18, 0x36, 0x5e, 0xdc, 0x18, 0x8e, 0xa6, 0xf6, 0xa3, 0x7d, 0xc6, 0x8b, 0xdb, 0xc2, 0xf2, 0xb3, + 0x90, 0xb1, 0x7a, 0xed, 0x36, 0x59, 0x3c, 0xa3, 0x52, 0x5e, 0xff, 0xfd, 0xab, 0x9c, 0x3b, 0x02, + 0xa1, 0x7c, 0x19, 0x26, 0x70, 0x67, 0x1b, 0xb7, 0x46, 0x61, 0xfe, 0xe1, 0x57, 0x85, 0xc2, 0x24, + 0xd0, 0xe5, 0x17, 0x00, 0x58, 0x6a, 0x84, 0x1e, 0xd2, 0x18, 0x81, 0xfb, 0xa5, 0xaf, 0xf2, 0xc3, + 0x97, 0x01, 0x4a, 0x40, 0x60, 0x9c, 0x4c, 0xdd, 0x97, 0xa3, 0x04, 0xe8, 0x8c, 0x3c, 0x03, 0x93, + 0xaf, 0xba, 0xb6, 0xe5, 0xe9, 0x23, 0x33, 0x96, 0x7f, 0xc4, 0xb1, 0x05, 0x3c, 0x61, 0x58, 0xc7, + 0x76, 0xb0, 0xa7, 0xef, 0xba, 0xa3, 0x70, 0xff, 0x98, 0xe3, 0xfa, 0x08, 0x04, 0xd9, 0xd0, 0x5d, + 0x6f, 0x9c, 0x71, 0xff, 0x0f, 0x81, 0x2c, 0x10, 0x48, 0xa7, 0xc9, 0xdf, 0x37, 0xf1, 0xc8, 0x0c, + 0xe7, 0x9f, 0x88, 0x4e, 0x73, 0xf8, 0xf2, 0x73, 0x90, 0x25, 0x7f, 0xb2, 0x13, 0xd5, 0x23, 0x90, + 0xff, 0x94, 0x23, 0x07, 0x18, 0xa4, 0x65, 0xd7, 0x6b, 0x79, 0xe6, 0x68, 0x66, 0xff, 0x19, 0x9f, + 0x69, 0x01, 0x5f, 0xae, 0x40, 0xce, 0xf5, 0x5a, 0xad, 0x1e, 0xf7, 0x4f, 0x47, 0xe5, 0x87, 0xbf, + 0xea, 0xa7, 0x2c, 0x7c, 0x1c, 0x32, 0xdb, 0xb7, 0x6f, 0x7a, 0x5d, 0x9b, 0xee, 0xc6, 0x8d, 0xcc, + 0x10, 0x73, 0x0a, 0x21, 0x94, 0xf2, 0x12, 0xe4, 0xc9, 0x58, 0xc4, 0x4d, 0x95, 0x91, 0xf9, 0x61, + 0xce, 0x80, 0x08, 0x52, 0xf5, 0x9b, 0x87, 0x25, 0x77, 0xe3, 0xf7, 0x10, 0x60, 0xc5, 0x5e, 0xb1, + 0xd9, 0xee, 0xc1, 0x2b, 0x0f, 0x0e, 0x66, 0x7f, 0xa3, 0x79, 0x5d, 0xfa, 0x17, 0xfc, 0x2f, 0x09, + 0xee, 0x37, 0xec, 0x0e, 0xf6, 0xb6, 0x77, 0xbc, 0x0b, 0x86, 0xb3, 0xdf, 0xf5, 0xec, 0x0b, 0xb7, + 0x2e, 0x5e, 0xb8, 0x89, 0xf7, 0x5d, 0x9e, 0xf8, 0x45, 0xa2, 0x7a, 0x91, 0x55, 0x2f, 0xde, 0xba, + 0x38, 0x17, 0x9b, 0x22, 0x56, 0x5e, 0x82, 0xec, 0x26, 0xbd, 0xb9, 0xfa, 0x22, 0xde, 0x47, 0x73, + 0x30, 0x89, 0x5b, 0x97, 0x2e, 0x5f, 0xbe, 0xf8, 0x0c, 0xdd, 0x8b, 0xcf, 0x5f, 0x3b, 0xa2, 0x8a, + 0x02, 0x74, 0x0a, 0xb2, 0x2e, 0x36, 0xba, 0x97, 0x2e, 0x5f, 0xb9, 0x79, 0x91, 0xee, 0xe3, 0x90, + 0xda, 0xa0, 0xa8, 0x9c, 0xf9, 0xe2, 0x1b, 0xf3, 0xd2, 0x17, 0x7f, 0x78, 0x5e, 0xaa, 0x4e, 0x40, + 0xd2, 0xed, 0x75, 0xaa, 0x6b, 0x43, 0x93, 0xdc, 0x4f, 0x44, 0x86, 0x29, 0xc6, 0x21, 0xfe, 0xd0, + 0xbb, 0xe6, 0x85, 0xc1, 0xd1, 0xf9, 0xc9, 0xee, 0x4f, 0xa5, 0xe0, 0x54, 0xcc, 0xe0, 0xbb, 0x8e, + 0x6d, 0xef, 0x1c, 0x7a, 0xf4, 0x3b, 0x30, 0xb1, 0x49, 0x10, 0xd1, 0x0c, 0x4c, 0x78, 0xb6, 0xa7, + 0xb7, 0xe9, 0xb8, 0x93, 0x2a, 0xfb, 0x20, 0xa5, 0xec, 0xf2, 0x4c, 0x82, 0x95, 0x9a, 0xe2, 0xde, + 0x4c, 0x1b, 0xeb, 0x3b, 0xec, 0x0c, 0x72, 0x92, 0x6e, 0x8f, 0x66, 0x48, 0x01, 0x3d, 0x6e, 0x3c, + 0x03, 0x13, 0x7a, 0x8f, 0xed, 0xec, 0x25, 0xcf, 0xe5, 0x55, 0xf6, 0xa1, 0xac, 0xc2, 0x24, 0x4f, + 0xe1, 0x22, 0x19, 0x92, 0x37, 0xf1, 0x3e, 0xe3, 0xaf, 0x4a, 0xfe, 0x44, 0x17, 0x60, 0x82, 0xf6, + 0x9e, 0x5f, 0xae, 0x38, 0xb1, 0x38, 0xd8, 0xfd, 0x45, 0xda, 0x4b, 0x95, 0xc1, 0x29, 0xd7, 0x21, + 0xb3, 0x6c, 0x77, 0x4c, 0xcb, 0x8e, 0x92, 0xcb, 0x32, 0x72, 0xb4, 0xd3, 0xdd, 0x9e, 0xc7, 0x37, + 0xdb, 0xd8, 0x07, 0x3a, 0x06, 0x69, 0x76, 0x28, 0x9d, 0x6f, 0x4f, 0xf2, 0x2f, 0x65, 0x09, 0x26, + 0x29, 0xed, 0x8d, 0xae, 0x7f, 0x11, 0x4c, 0x0a, 0x5d, 0x04, 0xe3, 0xe4, 0x13, 0x41, 0x6f, 0x11, + 0xa4, 0x5a, 0xba, 0xa7, 0xf3, 0x81, 0xd3, 0xbf, 0x95, 0x17, 0x20, 0xc3, 0x89, 0xb8, 0xe8, 0x09, + 0x48, 0xda, 0x5d, 0x97, 0x6f, 0x30, 0x9e, 0x1c, 0x3a, 0x96, 0x8d, 0x6e, 0x35, 0xf5, 0x2b, 0x6f, + 0xce, 0x1f, 0x51, 0x09, 0xf4, 0x3b, 0x25, 0x2b, 0xdf, 0x9b, 0x80, 0x53, 0x03, 0xfb, 0x1e, 0x5c, + 0x5b, 0x0c, 0xbb, 0x98, 0x5e, 0x86, 0xcc, 0xb2, 0x50, 0x42, 0xb3, 0x30, 0xe9, 0x62, 0xc3, 0xb6, + 0x5a, 0x2e, 0x97, 0x0b, 0xf1, 0x49, 0x98, 0x6c, 0xe9, 0x96, 0xed, 0xf2, 0x1b, 0x14, 0xec, 0xa3, + 0xfa, 0x51, 0xe9, 0x70, 0x6b, 0xbf, 0x20, 0x5a, 0xa2, 0xeb, 0x7f, 0x53, 0x7a, 0xe5, 0xe2, 0xc8, + 0xcd, 0xc3, 0x9b, 0x96, 0x7d, 0xdb, 0xf2, 0x07, 0x11, 0xd9, 0x40, 0x3c, 0xd5, 0xbf, 0x81, 0xf8, + 0x1e, 0xdc, 0x6e, 0xbf, 0x48, 0xe0, 0x9b, 0x04, 0xd5, 0xe7, 0xca, 0xc7, 0x53, 0x83, 0x5c, 0xb9, + 0xed, 0xe8, 0xdd, 0x2e, 0x76, 0xdc, 0x61, 0x5c, 0x39, 0x03, 0xb9, 0xe5, 0xd0, 0x21, 0x81, 0x19, + 0x71, 0x59, 0x47, 0xa2, 0x07, 0x08, 0xd8, 0x87, 0xa2, 0x00, 0x5c, 0x6d, 0xdb, 0xba, 0x17, 0x03, + 0x93, 0x08, 0xc1, 0xd4, 0x2d, 0xef, 0xca, 0x93, 0x31, 0x30, 0x49, 0x01, 0x73, 0x06, 0x72, 0x5b, + 0xc3, 0x80, 0x52, 0x51, 0x42, 0x4f, 0x5c, 0x8a, 0x81, 0x99, 0xe8, 0x23, 0x14, 0x0b, 0x54, 0x10, + 0x40, 0xa7, 0x21, 0x5b, 0xb5, 0xed, 0x76, 0x0c, 0x48, 0x26, 0x44, 0xa7, 0x11, 0x3a, 0xff, 0x10, + 0x01, 0xca, 0x86, 0x3a, 0x54, 0xdd, 0xf7, 0xb0, 0x1b, 0x03, 0x93, 0xe7, 0x30, 0x87, 0x17, 0x90, + 0xf7, 0xf0, 0x79, 0x39, 0xac, 0x80, 0x88, 0xf9, 0xbc, 0x27, 0x01, 0xf9, 0x81, 0x7c, 0x48, 0xc5, + 0x32, 0xaa, 0x44, 0xc3, 0xea, 0x8e, 0xde, 0x11, 0x02, 0x32, 0xe5, 0xaf, 0x6b, 0x5a, 0x3f, 0x54, + 0xc3, 0xce, 0x8d, 0x58, 0x7f, 0x73, 0x23, 0x24, 0x51, 0xf9, 0x6c, 0x12, 0x4a, 0x4b, 0xb6, 0xe5, + 0x62, 0xcb, 0xed, 0xb9, 0x9b, 0xb4, 0x0b, 0xe8, 0x49, 0x98, 0xd8, 0x6e, 0xdb, 0xc6, 0x4d, 0xca, + 0xdb, 0xdc, 0xa5, 0x53, 0x8b, 0x03, 0x9d, 0x59, 0xac, 0x92, 0x7a, 0x06, 0xae, 0x32, 0x60, 0xf4, + 0x1c, 0x64, 0xf0, 0x2d, 0xb3, 0x85, 0x2d, 0x03, 0x73, 0x4d, 0x7b, 0x3a, 0x06, 0xb1, 0xc6, 0x41, + 0x38, 0xae, 0x8f, 0x82, 0xbe, 0x0e, 0xb2, 0xb7, 0xf4, 0xb6, 0xd9, 0xd2, 0x3d, 0xdb, 0xe1, 0x57, + 0x8e, 0x94, 0x18, 0xfc, 0x1b, 0x02, 0x86, 0x13, 0x08, 0x90, 0x50, 0x19, 0x26, 0x6f, 0x61, 0x87, + 0x9e, 0x6f, 0x61, 0x37, 0x81, 0x16, 0xe2, 0xf0, 0x19, 0x04, 0xc7, 0x16, 0x08, 0xe8, 0x32, 0xa4, + 0xf4, 0x6d, 0xc3, 0xa4, 0x47, 0x1f, 0x72, 0x97, 0xee, 0x8f, 0x41, 0xac, 0x54, 0x97, 0xea, 0x0c, + 0x8b, 0x9e, 0xfe, 0xa3, 0xe0, 0xa4, 0xd3, 0xee, 0xbe, 0x65, 0xec, 0x39, 0xb6, 0xb5, 0x4f, 0x0f, + 0xfb, 0xc4, 0x77, 0xba, 0x21, 0x60, 0x44, 0xa7, 0x7d, 0x24, 0xd2, 0xe9, 0x1d, 0xac, 0x7b, 0x3d, + 0x07, 0xf3, 0x7b, 0xf0, 0x71, 0x9d, 0xbe, 0xca, 0x20, 0x44, 0xa7, 0x39, 0x82, 0x52, 0x87, 0x5c, + 0x68, 0x1e, 0xd8, 0x89, 0xf8, 0x3b, 0xda, 0x36, 0x59, 0x24, 0x7c, 0xc1, 0x67, 0x3a, 0xfa, 0x1d, + 0xba, 0x68, 0xd0, 0x71, 0x98, 0x24, 0x95, 0xbb, 0xfc, 0x94, 0x64, 0x52, 0x4d, 0x77, 0xf4, 0x3b, + 0x2b, 0xba, 0x7b, 0x3d, 0x95, 0x49, 0xca, 0x29, 0xe5, 0x53, 0x12, 0x14, 0xa3, 0x53, 0x83, 0x1e, + 0x01, 0x44, 0x30, 0xf4, 0x5d, 0xac, 0x59, 0xbd, 0x8e, 0x46, 0x27, 0x59, 0xd0, 0x2d, 0x75, 0xf4, + 0x3b, 0x95, 0x5d, 0xbc, 0xde, 0xeb, 0xd0, 0x0e, 0xb8, 0x68, 0x0d, 0x64, 0x01, 0x2c, 0x04, 0xd0, + 0x37, 0xb7, 0x03, 0xb7, 0xf2, 0x39, 0x40, 0x35, 0x43, 0x0c, 0xd4, 0x87, 0xff, 0xdb, 0xbc, 0xa4, + 0x16, 0x19, 0x3d, 0xdf, 0x30, 0x44, 0x86, 0x92, 0x8c, 0x0e, 0x45, 0x79, 0x01, 0x4a, 0x7d, 0x52, + 0x80, 0x14, 0x28, 0x74, 0x7b, 0xdb, 0xda, 0x4d, 0xbc, 0x4f, 0xaf, 0x89, 0x31, 0xf3, 0x98, 0x55, + 0x73, 0xdd, 0xde, 0xf6, 0x8b, 0x78, 0x9f, 0xae, 0xbe, 0x72, 0xe6, 0x17, 0x88, 0x03, 0xf5, 0xc6, + 0xbc, 0xa4, 0x3c, 0x02, 0x85, 0x88, 0x18, 0x10, 0x2b, 0xac, 0x77, 0xbb, 0x5c, 0xff, 0x91, 0x3f, + 0x43, 0xc0, 0xaf, 0x40, 0x9e, 0x38, 0x1e, 0xb8, 0xc5, 0x61, 0x1f, 0x82, 0x12, 0x65, 0x85, 0xd6, + 0xcf, 0xeb, 0x02, 0x2d, 0x5e, 0x13, 0x0c, 0x57, 0xa0, 0x10, 0xc0, 0x05, 0x6c, 0xcf, 0x09, 0xa8, + 0x15, 0xdd, 0x55, 0xbe, 0x5f, 0x82, 0x52, 0x9f, 0x6c, 0xa0, 0xe7, 0x20, 0xdb, 0x75, 0xb0, 0x61, + 0xba, 0xec, 0x18, 0xd1, 0x08, 0x16, 0xa6, 0x28, 0xfb, 0x02, 0x0c, 0xb4, 0x0c, 0x05, 0x71, 0xa4, + 0xa4, 0x85, 0xdb, 0xfa, 0xfe, 0xe8, 0x59, 0x60, 0x24, 0xc4, 0x13, 0x29, 0xcb, 0x04, 0x49, 0xf9, + 0x65, 0x09, 0x0a, 0x11, 0xa1, 0x43, 0x2d, 0xb8, 0xff, 0x96, 0xed, 0xe1, 0x70, 0xaa, 0x83, 0x5f, + 0x1d, 0xda, 0xc3, 0xe6, 0xee, 0x9e, 0xc7, 0xbb, 0x7a, 0x72, 0xa0, 0x9d, 0xc0, 0xd0, 0x50, 0x87, + 0x44, 0x52, 0xe7, 0x08, 0x9d, 0x20, 0xe3, 0xc1, 0xee, 0x18, 0x5d, 0xa3, 0x44, 0xd0, 0x06, 0xa0, + 0xee, 0xb6, 0xd7, 0x4f, 0x3a, 0x31, 0x2e, 0x69, 0x99, 0x20, 0x87, 0x09, 0x2a, 0x0d, 0x80, 0x60, + 0xe1, 0xa2, 0xca, 0x38, 0x83, 0x48, 0x1e, 0xd4, 0xc3, 0x72, 0x62, 0x56, 0xaa, 0x6e, 0x7e, 0xf2, + 0xf3, 0xa7, 0x86, 0x1a, 0x9a, 0x57, 0x2e, 0x8d, 0xef, 0x51, 0x09, 0xdd, 0xef, 0x5b, 0x86, 0xbf, + 0x48, 0xc3, 0xe9, 0x41, 0xcb, 0xe0, 0xab, 0xb8, 0xc3, 0x1a, 0x87, 0x83, 0xa3, 0x18, 0xe5, 0x33, + 0x12, 0xe4, 0xfd, 0x95, 0xd4, 0xc0, 0x1e, 0x7a, 0x17, 0x80, 0xdf, 0x96, 0x70, 0x31, 0xef, 0x3b, + 0x48, 0x09, 0xab, 0x21, 0x78, 0xf4, 0x34, 0x64, 0xba, 0x8e, 0xdd, 0xb5, 0x5d, 0x7e, 0xf1, 0x75, + 0x14, 0xae, 0x0f, 0x8d, 0x1e, 0x05, 0x44, 0x03, 0x02, 0xed, 0x96, 0xed, 0x99, 0xd6, 0xae, 0xd6, + 0xb5, 0x6f, 0xf3, 0xf7, 0x04, 0x92, 0xaa, 0x4c, 0x6b, 0x6e, 0xd0, 0x8a, 0x4d, 0x52, 0xae, 0x7c, + 0x5a, 0x82, 0xac, 0x4f, 0x85, 0xf8, 0x90, 0x7a, 0xab, 0xe5, 0x60, 0xd7, 0xe5, 0xae, 0x80, 0xf8, + 0x44, 0xef, 0x82, 0x49, 0xae, 0x14, 0xfc, 0x6b, 0xd5, 0x71, 0xde, 0xb2, 0x88, 0xce, 0xb8, 0xbf, + 0x9c, 0x66, 0x3a, 0x03, 0x9d, 0x86, 0x7c, 0x4c, 0x6f, 0x72, 0xb7, 0x82, 0x8e, 0xd0, 0xe7, 0x8a, + 0xf8, 0x10, 0xb4, 0xae, 0x63, 0xda, 0x8e, 0xe9, 0xed, 0x53, 0xd3, 0x93, 0x54, 0x65, 0x51, 0xb1, + 0xc9, 0xcb, 0x95, 0x36, 0x94, 0x1a, 0x66, 0xa7, 0x4b, 0x3d, 0x3c, 0xde, 0xf5, 0x2b, 0x41, 0x07, + 0xa5, 0x31, 0x3a, 0x38, 0xb4, 0x6b, 0x89, 0x81, 0xae, 0x9d, 0xff, 0x4d, 0x89, 0xdb, 0x86, 0xfa, + 0xf2, 0xd5, 0xb6, 0xbe, 0x8b, 0x2e, 0xc2, 0xd1, 0xea, 0xea, 0xc6, 0xd2, 0x8b, 0x5a, 0x7d, 0x59, + 0xbb, 0xba, 0x5a, 0x59, 0x09, 0x4e, 0xf1, 0xce, 0x1d, 0x7b, 0xfd, 0xee, 0x02, 0x0a, 0xc1, 0x6e, + 0x59, 0xd4, 0xc5, 0x41, 0x17, 0x60, 0x26, 0x8a, 0x52, 0xa9, 0x36, 0x6a, 0xeb, 0x4d, 0x59, 0x9a, + 0x3b, 0xfa, 0xfa, 0xdd, 0x85, 0xa9, 0x10, 0x46, 0x65, 0xdb, 0xc5, 0x96, 0x37, 0x88, 0xb0, 0xb4, + 0xb1, 0xb6, 0x56, 0x6f, 0xca, 0x89, 0x01, 0x84, 0x25, 0xbb, 0xd3, 0x31, 0x3d, 0xf4, 0x30, 0x4c, + 0x45, 0x11, 0xd6, 0xeb, 0xab, 0x72, 0x72, 0x0e, 0xbd, 0x7e, 0x77, 0xa1, 0x18, 0x82, 0x5e, 0x37, + 0xdb, 0x73, 0x99, 0x0f, 0xfe, 0xe8, 0xa9, 0x23, 0x9f, 0xfc, 0xc7, 0xa7, 0xa4, 0xea, 0xea, 0x3b, + 0xb2, 0xf0, 0x7e, 0x20, 0x01, 0xf3, 0xfd, 0x9e, 0x92, 0x67, 0x76, 0xb0, 0xeb, 0xe9, 0x9d, 0xee, + 0x30, 0xa7, 0xfd, 0x59, 0xc8, 0x36, 0x05, 0xcc, 0xa1, 0x63, 0x99, 0xbb, 0x87, 0x74, 0x55, 0x8b, + 0x7e, 0x53, 0xc2, 0x57, 0xbd, 0x34, 0xa6, 0xaf, 0xea, 0x8f, 0xe3, 0x9e, 0x9c, 0xd5, 0xdf, 0x69, + 0xc0, 0x7d, 0x01, 0x13, 0xb7, 0x0d, 0x93, 0x28, 0x11, 0xb6, 0x9a, 0x19, 0x5b, 0x64, 0x5f, 0x66, + 0x49, 0x2d, 0x51, 0x46, 0x07, 0xab, 0x9d, 0xb9, 0x11, 0xe9, 0x85, 0xb9, 0x11, 0xbe, 0xf1, 0xdc, + 0x68, 0x0d, 0x39, 0x44, 0x1d, 0x8e, 0x9a, 0x61, 0xe5, 0x3f, 0x67, 0x61, 0x52, 0xc5, 0xef, 0xed, + 0x61, 0xd7, 0x43, 0x4f, 0x40, 0x0a, 0x1b, 0x7b, 0xf6, 0xe0, 0xca, 0xe4, 0xa3, 0x5c, 0xac, 0x19, + 0x7b, 0x36, 0x07, 0xbe, 0x76, 0x44, 0xa5, 0xc0, 0xe8, 0x0a, 0x4c, 0xec, 0xb4, 0x7b, 0xee, 0x1e, + 0x57, 0x38, 0xa7, 0x06, 0xb1, 0xae, 0x92, 0xea, 0x00, 0x8d, 0x81, 0x93, 0xc6, 0xe8, 0x73, 0x5a, + 0xc9, 0x61, 0x8d, 0xd1, 0x57, 0xb4, 0x82, 0xc6, 0x08, 0x30, 0x5a, 0x02, 0x30, 0x2d, 0xd3, 0xd3, + 0x8c, 0x3d, 0xdd, 0xb4, 0xb8, 0xe7, 0xaa, 0xc4, 0xa1, 0x9a, 0xde, 0x12, 0x01, 0x09, 0xf0, 0xb3, + 0xa6, 0x28, 0x23, 0x3d, 0x7e, 0x6f, 0x0f, 0x3b, 0xc2, 0x7b, 0x8d, 0xe9, 0xf1, 0xbb, 0x49, 0x75, + 0xa8, 0xc7, 0x14, 0x9c, 0x78, 0xfb, 0xec, 0xaa, 0xb7, 0x77, 0x87, 0x3f, 0x60, 0xb2, 0x30, 0x88, + 0x4a, 0x6f, 0x7a, 0x37, 0xef, 0x04, 0xc8, 0x93, 0x06, 0x2b, 0x41, 0xcf, 0x40, 0xda, 0xa0, 0x4a, + 0x80, 0x5e, 0xc0, 0xcc, 0x5d, 0x9a, 0x8f, 0x41, 0xa6, 0xf5, 0x01, 0x2e, 0x47, 0x40, 0x1b, 0x50, + 0x6c, 0x9b, 0xae, 0xa7, 0xb9, 0x96, 0xde, 0x75, 0xf7, 0x6c, 0xcf, 0xa5, 0x6f, 0x88, 0xe5, 0x2e, + 0x3d, 0x34, 0x48, 0x62, 0xd5, 0x74, 0xbd, 0x86, 0x00, 0x0b, 0x28, 0x15, 0xda, 0xe1, 0x72, 0x42, + 0xd0, 0xde, 0xd9, 0xc1, 0x8e, 0x4f, 0x91, 0xbe, 0x3d, 0x16, 0x4b, 0x70, 0x83, 0xc0, 0x09, 0xcc, + 0x10, 0x41, 0x3b, 0x5c, 0x8e, 0xbe, 0x01, 0xa6, 0xdb, 0xb6, 0xde, 0xf2, 0xe9, 0x69, 0xc6, 0x5e, + 0xcf, 0xba, 0x39, 0x5b, 0xa4, 0x54, 0xcf, 0xc7, 0x74, 0xd3, 0xd6, 0x5b, 0x02, 0x79, 0x89, 0x80, + 0x06, 0x94, 0xa7, 0xda, 0xfd, 0x75, 0x48, 0x83, 0x19, 0xbd, 0xdb, 0x6d, 0xef, 0xf7, 0x93, 0x2f, + 0x51, 0xf2, 0x8f, 0x0c, 0x92, 0xaf, 0x10, 0xe8, 0x21, 0xf4, 0x91, 0x3e, 0x50, 0x89, 0xb6, 0x40, + 0xee, 0x3a, 0x98, 0x9e, 0xcc, 0x60, 0x56, 0x4c, 0x6f, 0xd3, 0x3b, 0x92, 0xb9, 0x4b, 0xe7, 0x06, + 0x89, 0x6f, 0x32, 0xc8, 0x4d, 0x0e, 0x18, 0x50, 0x2e, 0x75, 0xa3, 0x35, 0x8c, 0xac, 0x6d, 0x60, + 0x7a, 0x87, 0x9b, 0x93, 0x9d, 0x1a, 0x4e, 0x96, 0x42, 0xc6, 0x92, 0x8d, 0xd4, 0xa0, 0xab, 0x90, + 0x63, 0xef, 0xf6, 0x10, 0xe7, 0x01, 0xd3, 0xbb, 0x95, 0xb9, 0x4b, 0x67, 0x62, 0x96, 0x2b, 0x05, + 0xba, 0x61, 0x7b, 0x38, 0x20, 0x06, 0xd8, 0x2f, 0x44, 0xdb, 0x70, 0x94, 0xde, 0x33, 0xdd, 0xd7, + 0xa2, 0x2e, 0xe2, 0xec, 0x34, 0xa5, 0xf8, 0xe8, 0x20, 0x45, 0xfa, 0xc8, 0xd2, 0xfe, 0x8d, 0xb0, + 0xaf, 0x18, 0x90, 0x9e, 0xbe, 0x35, 0x58, 0x4b, 0x24, 0x6d, 0xc7, 0xb4, 0xf4, 0xb6, 0xf9, 0x1a, + 0x66, 0xf1, 0x14, 0x7d, 0x62, 0x21, 0x56, 0xd2, 0xae, 0x72, 0x38, 0x6a, 0x07, 0x43, 0x92, 0xb6, + 0x13, 0x2e, 0xaf, 0x4e, 0xf2, 0x2c, 0x88, 0x7f, 0x67, 0x78, 0x52, 0xce, 0xb0, 0x7b, 0xc2, 0xd7, + 0x53, 0x19, 0x90, 0x73, 0xca, 0x59, 0xc8, 0x85, 0xf4, 0x14, 0x31, 0x52, 0xdc, 0xcf, 0xe7, 0xb9, + 0x15, 0xf1, 0xa9, 0x14, 0x21, 0x1f, 0x56, 0x4d, 0xca, 0x87, 0x24, 0xc8, 0x85, 0x94, 0x0e, 0xc1, + 0x14, 0xc1, 0x35, 0xc7, 0x14, 0xa1, 0xf3, 0x19, 0x11, 0xe8, 0x88, 0xfa, 0x04, 0x0d, 0xa3, 0xf2, + 0xb4, 0x90, 0xc7, 0x59, 0x68, 0x1e, 0x72, 0xdd, 0x4b, 0x5d, 0x1f, 0x24, 0x49, 0x41, 0xa0, 0x7b, + 0xa9, 0x2b, 0x00, 0x4e, 0x43, 0x9e, 0x0c, 0x5d, 0x0b, 0x47, 0xf0, 0x59, 0x35, 0x47, 0xca, 0x38, + 0x88, 0xf2, 0xeb, 0x09, 0x90, 0xfb, 0x95, 0x19, 0x7a, 0x1a, 0x52, 0x44, 0x8b, 0x73, 0x35, 0x3d, + 0x37, 0x10, 0x23, 0xf8, 0x56, 0x93, 0x45, 0x9b, 0x1f, 0x22, 0xb1, 0x0e, 0xc5, 0x40, 0x27, 0x88, + 0x06, 0xd3, 0x4d, 0x4b, 0x33, 0x5b, 0xe2, 0x9d, 0x4a, 0xfa, 0x5d, 0x6f, 0x91, 0x68, 0xd6, 0x10, + 0x39, 0x11, 0x8d, 0xd9, 0x9e, 0x03, 0x52, 0x12, 0x7d, 0xe9, 0x13, 0xb5, 0x64, 0xf4, 0xe5, 0x53, + 0x56, 0x22, 0x6e, 0x35, 0x7b, 0xfd, 0xe6, 0x74, 0x8c, 0x3c, 0x09, 0x98, 0xad, 0x6e, 0x4b, 0xf7, + 0x30, 0xf7, 0x47, 0xc3, 0x1e, 0xf6, 0x43, 0x50, 0xd2, 0xbb, 0x5d, 0xcd, 0xf5, 0x74, 0x0f, 0xf3, + 0xd8, 0x73, 0x82, 0xfa, 0xbc, 0x05, 0xbd, 0xdb, 0xa5, 0xef, 0x7c, 0xb1, 0xd8, 0xf3, 0x41, 0x28, + 0x12, 0x0d, 0x6f, 0xea, 0x6d, 0x11, 0xd8, 0xa4, 0x59, 0x88, 0xca, 0x4b, 0x79, 0x70, 0xd4, 0x82, + 0x7c, 0x58, 0xb9, 0xfb, 0xa9, 0x67, 0x29, 0x48, 0x3d, 0x93, 0x32, 0x7a, 0xf1, 0x84, 0x71, 0x48, + 0x5c, 0xd6, 0x49, 0x73, 0xb2, 0xcc, 0x29, 0xe6, 0x5f, 0xc4, 0xd1, 0xe9, 0x3a, 0xf6, 0x2d, 0x76, + 0x99, 0x2a, 0xa3, 0xb2, 0x0f, 0xe5, 0x65, 0x28, 0x46, 0xed, 0x00, 0x2a, 0x42, 0xc2, 0xbb, 0xc3, + 0x5b, 0x49, 0x78, 0x77, 0xd0, 0xc5, 0xd0, 0x0b, 0x69, 0xc5, 0x38, 0xeb, 0xc7, 0xf1, 0x83, 0xa7, + 0xbd, 0xae, 0xa7, 0x32, 0x09, 0x39, 0xa9, 0x94, 0xa0, 0x10, 0xb1, 0x12, 0xca, 0x31, 0x98, 0x89, + 0xd3, 0xf9, 0x8a, 0x09, 0x33, 0x71, 0xaa, 0x1b, 0x5d, 0x81, 0x8c, 0xaf, 0xf4, 0x85, 0x04, 0x0d, + 0xb4, 0xee, 0x23, 0xf9, 0xb0, 0x44, 0x76, 0xc8, 0x44, 0xd0, 0x1d, 0x8a, 0x04, 0x8f, 0x3a, 0xba, + 0xdd, 0x6b, 0xba, 0xbb, 0xa7, 0x7c, 0x33, 0xcc, 0x0e, 0xd3, 0xe7, 0x21, 0xc6, 0xb1, 0x54, 0x83, + 0x60, 0xdc, 0x31, 0x48, 0xf3, 0xd7, 0x16, 0x12, 0x34, 0x73, 0xca, 0xbf, 0x08, 0x43, 0x99, 0x6e, + 0x4f, 0xb2, 0x84, 0x2a, 0xfd, 0x50, 0x34, 0x38, 0x31, 0x54, 0xa5, 0x07, 0x5b, 0x2a, 0x3c, 0x07, + 0xcb, 0xb6, 0x54, 0x7c, 0x42, 0xac, 0xb3, 0xec, 0x83, 0xbe, 0xc2, 0x89, 0xad, 0x16, 0x0f, 0x6e, + 0xb2, 0x2a, 0xff, 0x52, 0x3e, 0x92, 0x84, 0x63, 0xf1, 0x7a, 0x1d, 0x2d, 0x40, 0xbe, 0xa3, 0xdf, + 0xd1, 0xbc, 0x68, 0xea, 0x03, 0x3a, 0xfa, 0x9d, 0x26, 0xcf, 0x7b, 0xc8, 0x90, 0xf4, 0xee, 0xb8, + 0xf4, 0x22, 0x57, 0x5e, 0x25, 0x7f, 0xa2, 0x1b, 0x30, 0xd5, 0xb6, 0x0d, 0xbd, 0xad, 0xb5, 0x75, + 0xd7, 0xd3, 0xb8, 0xd9, 0x67, 0xcb, 0xe9, 0x81, 0x61, 0x7a, 0x9a, 0x5d, 0xb7, 0x32, 0x3d, 0xa2, + 0x82, 0xf8, 0x42, 0x28, 0x51, 0x22, 0xab, 0xba, 0xeb, 0xf1, 0xf0, 0xa1, 0x06, 0xb9, 0x8e, 0xe9, + 0x6e, 0xe3, 0x3d, 0xfd, 0x96, 0x69, 0x3b, 0x7c, 0x5d, 0xc5, 0x48, 0xcf, 0x5a, 0x00, 0xc4, 0x49, + 0x85, 0xf1, 0x42, 0x93, 0x32, 0x11, 0x91, 0x66, 0xa1, 0x59, 0xd2, 0x87, 0xd6, 0x2c, 0x8f, 0xc3, + 0x8c, 0x85, 0xef, 0xd0, 0xbb, 0x82, 0x7c, 0xe5, 0x32, 0x49, 0x61, 0x57, 0xfd, 0x10, 0xa9, 0xf3, + 0xd7, 0xba, 0x4b, 0x77, 0xb5, 0x1e, 0x06, 0x3f, 0x60, 0xd4, 0x44, 0x34, 0x9b, 0xa1, 0xd0, 0x25, + 0x51, 0x5e, 0x61, 0xc5, 0xca, 0xeb, 0x74, 0x72, 0xe2, 0xac, 0xa3, 0x60, 0xbd, 0x14, 0xb0, 0xbe, + 0x09, 0x33, 0x1c, 0xbf, 0x15, 0xe1, 0xfe, 0x40, 0x78, 0x1e, 0x75, 0xba, 0x42, 0x5c, 0x47, 0x02, + 0x7f, 0x38, 0xe3, 0x93, 0xf7, 0xc8, 0x78, 0x04, 0x29, 0xca, 0x96, 0x14, 0x53, 0x37, 0xe4, 0xef, + 0xff, 0xd7, 0x26, 0xe3, 0xfd, 0x49, 0x98, 0x1a, 0x70, 0x2c, 0xfc, 0x81, 0x49, 0xb1, 0x03, 0x4b, + 0xc4, 0x0e, 0x2c, 0x79, 0xe8, 0x81, 0xf1, 0xd9, 0x4e, 0x8d, 0x9e, 0xed, 0x89, 0xb7, 0x73, 0xb6, + 0xd3, 0xf7, 0x38, 0xdb, 0xef, 0xe8, 0x3c, 0x7c, 0x4c, 0x82, 0xb9, 0xe1, 0xee, 0x58, 0xec, 0x84, + 0x3c, 0x02, 0x53, 0x7e, 0x57, 0x7c, 0xf2, 0x4c, 0x3d, 0xca, 0x7e, 0x05, 0xa7, 0x3f, 0xd4, 0xe2, + 0x3d, 0x08, 0xc5, 0x3e, 0x6f, 0x91, 0x09, 0x73, 0x21, 0x92, 0x41, 0x54, 0x3e, 0x90, 0x84, 0x99, + 0x38, 0x87, 0x2e, 0x66, 0xc5, 0xaa, 0x30, 0xdd, 0xc2, 0x86, 0xd9, 0xba, 0xe7, 0x05, 0x3b, 0xc5, + 0xd1, 0xff, 0xff, 0x7a, 0x8d, 0x91, 0x93, 0x1f, 0x03, 0xc8, 0xa8, 0xd8, 0xed, 0x12, 0x07, 0x8d, + 0xbd, 0xf6, 0x6c, 0xe0, 0xae, 0x17, 0x64, 0xda, 0x63, 0xe3, 0x06, 0x0e, 0x22, 0xf0, 0x48, 0xfc, + 0xec, 0xe3, 0xa1, 0x27, 0x79, 0x9a, 0x60, 0x68, 0xc0, 0xcf, 0xdc, 0x6f, 0x1f, 0x95, 0xe5, 0x09, + 0x9e, 0x12, 0x79, 0x82, 0xe4, 0xb0, 0xe8, 0x97, 0x3b, 0xe3, 0x3e, 0x1e, 0x4f, 0x14, 0x3c, 0xc9, + 0x13, 0x05, 0xa9, 0x61, 0xcd, 0x31, 0x9f, 0x3d, 0x68, 0xce, 0x64, 0x17, 0xb9, 0xc3, 0x99, 0x82, + 0xf4, 0xb0, 0xa1, 0x86, 0x9c, 0xeb, 0x60, 0xa8, 0x41, 0xaa, 0xe0, 0x29, 0x91, 0x2a, 0x98, 0x1c, + 0xd6, 0x69, 0xee, 0x4d, 0x06, 0x9d, 0x66, 0xb9, 0x82, 0xe7, 0x43, 0xb9, 0x82, 0x6c, 0xff, 0xce, + 0xe0, 0x40, 0xae, 0xc0, 0xc7, 0xf6, 0x93, 0x05, 0x65, 0x3f, 0x59, 0x90, 0x1f, 0x9a, 0x69, 0xe0, + 0x6e, 0xa0, 0x8f, 0x2c, 0xb2, 0x05, 0x9b, 0x03, 0xd9, 0x02, 0x16, 0xdc, 0x9f, 0x1d, 0x99, 0x2d, + 0xf0, 0x49, 0xf5, 0xa5, 0x0b, 0x36, 0x07, 0xd2, 0x05, 0xc5, 0x61, 0x14, 0xfb, 0x7c, 0xce, 0x80, + 0x62, 0x34, 0x5f, 0xf0, 0x8d, 0xf1, 0xf9, 0x82, 0xa1, 0x01, 0x7d, 0x8c, 0x7f, 0xe9, 0x93, 0x8e, + 0x49, 0x18, 0x7c, 0xf3, 0x90, 0x84, 0x81, 0x3c, 0x2c, 0xb0, 0x8d, 0xf3, 0x2e, 0xfd, 0x06, 0xe2, + 0x32, 0x06, 0x37, 0x62, 0x32, 0x06, 0x2c, 0xb4, 0x7f, 0x78, 0x8c, 0x8c, 0x81, 0x4f, 0x7a, 0x20, + 0x65, 0x70, 0x23, 0x26, 0x65, 0x80, 0x86, 0xd3, 0xed, 0x73, 0x8a, 0xc2, 0x74, 0xa3, 0x39, 0x83, + 0x95, 0x68, 0xce, 0x60, 0xfa, 0x60, 0x5f, 0x94, 0x99, 0x76, 0x9f, 0x5a, 0x38, 0x69, 0x60, 0x0c, + 0x4b, 0x1a, 0xb0, 0xb8, 0xfe, 0xb1, 0x31, 0x93, 0x06, 0x3e, 0xed, 0xd8, 0xac, 0xc1, 0xe6, 0x40, + 0xd6, 0xe0, 0xe8, 0x30, 0x81, 0xeb, 0x33, 0x32, 0x81, 0xc0, 0x0d, 0x4d, 0x1b, 0xb0, 0x47, 0xc6, + 0xd8, 0xf3, 0x62, 0x20, 0xe7, 0xae, 0xa7, 0x32, 0x39, 0x39, 0xaf, 0x3c, 0x4c, 0xdc, 0x9a, 0x3e, + 0xbd, 0x47, 0x82, 0x08, 0xec, 0x38, 0xb6, 0x23, 0x8e, 0x65, 0xd0, 0x0f, 0xe5, 0x1c, 0xe4, 0xc3, + 0x2a, 0xee, 0x80, 0x14, 0x43, 0x09, 0x0a, 0x11, 0xad, 0xa6, 0xfc, 0x82, 0x04, 0xf9, 0xb0, 0xbe, + 0x8a, 0x04, 0xa0, 0x59, 0x1e, 0x80, 0x86, 0x12, 0x0f, 0x89, 0x68, 0xe2, 0x61, 0x1e, 0x72, 0x24, + 0x08, 0xeb, 0xcb, 0x29, 0xe8, 0x5d, 0x3f, 0xa7, 0x70, 0x1e, 0xa6, 0xa8, 0x0d, 0x65, 0xe9, 0x09, + 0x6e, 0xa7, 0xd8, 0xfe, 0x4c, 0x89, 0x54, 0x50, 0x66, 0xf0, 0x9d, 0xc7, 0xc7, 0x60, 0x3a, 0x04, + 0xeb, 0x07, 0x77, 0x2c, 0xbc, 0x96, 0x7d, 0xe8, 0x0a, 0x8f, 0xf2, 0x7e, 0x59, 0x82, 0xa9, 0x01, + 0x75, 0x19, 0x9b, 0x37, 0x90, 0xde, 0xae, 0xbc, 0x41, 0xe2, 0xde, 0xf3, 0x06, 0xe1, 0x70, 0x35, + 0x19, 0x0d, 0x57, 0xff, 0x52, 0x82, 0x42, 0x44, 0x6d, 0x93, 0x49, 0x30, 0xec, 0x96, 0x38, 0xc4, + 0x43, 0xff, 0x26, 0x7e, 0x4a, 0xdb, 0xde, 0xe5, 0x61, 0x22, 0xf9, 0x93, 0x40, 0xf9, 0x86, 0x28, + 0xcb, 0xcd, 0x8c, 0x1f, 0x7b, 0x4e, 0x84, 0x8f, 0xf3, 0xf1, 0x23, 0x6e, 0xe9, 0xe0, 0x88, 0x9b, + 0x7f, 0x76, 0x67, 0x32, 0x74, 0x76, 0x07, 0x3d, 0x03, 0x59, 0xba, 0x0b, 0xa0, 0xd9, 0xdd, 0xe0, + 0x87, 0x29, 0x86, 0x1f, 0x6f, 0x73, 0xe9, 0xfe, 0x21, 0x3b, 0x13, 0x17, 0x78, 0x21, 0xd9, 0x88, + 0x17, 0x72, 0x1f, 0x64, 0x49, 0xf7, 0xd9, 0xe3, 0x8e, 0xc0, 0x0f, 0xd3, 0x8a, 0x02, 0xe5, 0x27, + 0x13, 0x50, 0xea, 0xb3, 0x3a, 0xb1, 0x83, 0x17, 0x52, 0x99, 0x08, 0xa5, 0x45, 0xc6, 0x63, 0xc8, + 0x29, 0x80, 0x5d, 0xdd, 0xd5, 0x6e, 0xeb, 0x96, 0xc7, 0xdf, 0x70, 0x4f, 0xaa, 0xa1, 0x12, 0x34, + 0x07, 0x19, 0xf2, 0xd5, 0x73, 0xf9, 0x2b, 0xee, 0x49, 0xd5, 0xff, 0x46, 0x75, 0x48, 0xe3, 0x5b, + 0xf4, 0x39, 0x12, 0xf6, 0xa8, 0xcf, 0xf1, 0x18, 0xf5, 0x44, 0xea, 0xab, 0xb3, 0x64, 0xba, 0xff, + 0xf0, 0xcd, 0x79, 0x99, 0x81, 0x3f, 0xea, 0x3f, 0xbf, 0xa0, 0x72, 0x02, 0x51, 0x36, 0x64, 0xfa, + 0xd8, 0x40, 0xd3, 0x85, 0x79, 0x11, 0xfb, 0x13, 0xa6, 0xb2, 0x0d, 0x4b, 0xb5, 0xd0, 0xc1, 0x9d, + 0xae, 0x6d, 0xb7, 0x35, 0xb6, 0xce, 0x2b, 0x50, 0x8c, 0x1a, 0x59, 0xf6, 0xf2, 0xb2, 0xa7, 0x9b, + 0x96, 0x16, 0xf1, 0x8d, 0xf3, 0xac, 0x90, 0xad, 0xab, 0xeb, 0xa9, 0x8c, 0x24, 0x27, 0x78, 0xba, + 0xe6, 0xdd, 0x70, 0x34, 0xd6, 0xc6, 0xa2, 0xa7, 0x21, 0x1b, 0xd8, 0x67, 0xb6, 0xed, 0x7c, 0x50, + 0x1e, 0x26, 0x00, 0x56, 0x6e, 0xc0, 0xd1, 0x58, 0x23, 0x8b, 0x9e, 0x83, 0xb4, 0x83, 0xdd, 0x5e, + 0xdb, 0xe3, 0xcf, 0x22, 0x3e, 0x38, 0xda, 0x3a, 0xf7, 0xda, 0x9e, 0xca, 0x91, 0x94, 0x8b, 0x70, + 0x62, 0xa8, 0x95, 0x0d, 0xb2, 0x29, 0x52, 0x28, 0x9b, 0xa2, 0xfc, 0xb4, 0x04, 0x73, 0xc3, 0x2d, + 0x27, 0xaa, 0xf6, 0x75, 0xe8, 0xfc, 0x98, 0x76, 0x37, 0xd4, 0x2b, 0x12, 0x6e, 0x38, 0x78, 0x07, + 0x7b, 0xc6, 0x1e, 0x33, 0xe1, 0x4c, 0x29, 0x14, 0xd4, 0x02, 0x2f, 0xa5, 0x38, 0x2e, 0x03, 0x7b, + 0x15, 0x1b, 0x9e, 0xc6, 0x26, 0xd5, 0xe5, 0x3f, 0xb5, 0x53, 0x60, 0xa5, 0x0d, 0x56, 0xa8, 0x3c, + 0x02, 0xc7, 0x87, 0xd8, 0xe2, 0xc1, 0xb8, 0x44, 0x79, 0x85, 0x00, 0xc7, 0x1a, 0x58, 0xf4, 0x02, + 0xa4, 0x5d, 0x4f, 0xf7, 0x7a, 0x2e, 0x1f, 0xd9, 0xd9, 0x91, 0xb6, 0xb9, 0x41, 0xc1, 0x55, 0x8e, + 0xa6, 0x3c, 0x0b, 0x68, 0xd0, 0xd2, 0xc6, 0xc4, 0x56, 0x52, 0x5c, 0x6c, 0xb5, 0x0d, 0x27, 0x0f, + 0xb0, 0xa9, 0x68, 0xa9, 0xaf, 0x73, 0x8f, 0x8c, 0x65, 0x92, 0xfb, 0x3a, 0xf8, 0xc7, 0x09, 0x38, + 0x1a, 0x6b, 0x5a, 0x43, 0xab, 0x54, 0x7a, 0xab, 0xab, 0xf4, 0x39, 0x00, 0xef, 0x8e, 0xc6, 0x66, + 0x5a, 0x68, 0xfb, 0xb8, 0x78, 0xe2, 0x0e, 0x36, 0xa8, 0xc2, 0x22, 0x82, 0x91, 0xf5, 0xf8, 0x5f, + 0x24, 0xf8, 0x0f, 0xc5, 0xb3, 0x3d, 0x6a, 0x09, 0x5c, 0x1e, 0xea, 0x8d, 0x6d, 0x33, 0x82, 0xc0, + 0x97, 0x15, 0xbb, 0xe8, 0x15, 0x38, 0xde, 0x67, 0xd1, 0x7c, 0xda, 0xa9, 0xb1, 0x0d, 0xdb, 0xd1, + 0xa8, 0x61, 0x13, 0xb4, 0xc3, 0x56, 0x69, 0x22, 0x6a, 0x95, 0x5e, 0x01, 0x08, 0x02, 0x5b, 0xb2, + 0xde, 0x1c, 0xbb, 0x67, 0xb5, 0xc4, 0xe1, 0x53, 0xfa, 0x81, 0xae, 0xc0, 0x04, 0x91, 0x04, 0xc1, + 0xaa, 0x18, 0x85, 0x41, 0xa6, 0x34, 0x14, 0x19, 0x33, 0x70, 0xe5, 0x55, 0x21, 0x6d, 0xe1, 0x1c, + 0xe3, 0x90, 0x36, 0x9e, 0x8f, 0xb6, 0xa1, 0x0c, 0x4f, 0x57, 0xc6, 0xb7, 0xf5, 0x77, 0x60, 0x82, + 0x4e, 0x7f, 0xec, 0xd9, 0xef, 0x6f, 0x02, 0xd0, 0x3d, 0xcf, 0x31, 0xb7, 0x7b, 0x41, 0x0b, 0x0b, + 0x43, 0xe4, 0xa7, 0x22, 0x00, 0xab, 0xf7, 0x71, 0x41, 0x9a, 0x09, 0x70, 0x43, 0xc2, 0x14, 0xa2, + 0xa8, 0xac, 0x43, 0x31, 0x8a, 0x1b, 0x7f, 0x98, 0x5d, 0xfc, 0x2a, 0x40, 0x70, 0xd4, 0x36, 0x30, + 0xe4, 0xfc, 0xb6, 0x10, 0xfd, 0x50, 0xbe, 0x25, 0x01, 0xf9, 0xb0, 0xf4, 0xfd, 0x2d, 0x34, 0x96, + 0xca, 0x07, 0x24, 0xc8, 0xf8, 0xe3, 0x8f, 0xa6, 0xf3, 0x23, 0xfb, 0x20, 0xc1, 0xb5, 0x06, 0x3f, + 0x07, 0xcf, 0x76, 0x3d, 0x92, 0xfe, 0xae, 0xc7, 0xbb, 0x7c, 0x83, 0x30, 0x34, 0x98, 0x0f, 0x73, + 0x5b, 0x1c, 0x4f, 0xe2, 0x06, 0xea, 0xd9, 0xf1, 0xce, 0x40, 0xcd, 0xc0, 0x44, 0xf8, 0xf8, 0x12, + 0xfb, 0x50, 0x70, 0xe8, 0x04, 0x25, 0x5b, 0x8d, 0xe1, 0xc3, 0x52, 0xd2, 0xe1, 0x0f, 0x4b, 0xf9, + 0xcd, 0x24, 0xc2, 0xcd, 0xfc, 0x23, 0x09, 0x32, 0x62, 0x5d, 0xa0, 0x17, 0xc2, 0xe7, 0x7b, 0xc5, + 0x61, 0xc1, 0xe1, 0x7a, 0x89, 0x37, 0x10, 0x3a, 0xde, 0x5b, 0x15, 0xfb, 0x8c, 0x66, 0x4b, 0xdb, + 0x69, 0xeb, 0xbb, 0x7c, 0xbb, 0x68, 0xe8, 0xe9, 0x64, 0x76, 0x78, 0x88, 0x1f, 0xb8, 0xac, 0xb7, + 0xc8, 0x07, 0xf7, 0x43, 0xfe, 0x5c, 0x02, 0xb9, 0x7f, 0xdd, 0xbe, 0xf5, 0xfe, 0x0d, 0xda, 0xab, + 0x64, 0x8c, 0xbd, 0x42, 0x17, 0x60, 0x3a, 0xf8, 0x61, 0x2e, 0xd7, 0xdc, 0xb5, 0xd8, 0xe1, 0x5f, + 0x96, 0x54, 0x43, 0x7e, 0x55, 0x43, 0xd4, 0x0c, 0x8e, 0x7b, 0xe2, 0x5e, 0xc7, 0xfd, 0xfe, 0x04, + 0xe4, 0x42, 0x39, 0x3e, 0x74, 0x39, 0xa4, 0x94, 0x8a, 0x71, 0x56, 0x22, 0x04, 0x1c, 0xfa, 0x59, + 0x9d, 0x08, 0xa7, 0x12, 0xf7, 0xc0, 0xa9, 0x61, 0xd9, 0x54, 0x91, 0x34, 0x4c, 0x1d, 0x3a, 0x69, + 0x18, 0x7f, 0x80, 0x70, 0x62, 0xc8, 0x01, 0xc2, 0xbf, 0x27, 0x41, 0xc6, 0x4f, 0xbe, 0x1c, 0x76, + 0x4f, 0xee, 0x18, 0xa4, 0xb9, 0xef, 0xc5, 0x36, 0xe5, 0xf8, 0x57, 0x6c, 0x76, 0x74, 0x0e, 0x32, + 0xe2, 0x95, 0x79, 0x6e, 0xe1, 0xfc, 0xef, 0xf3, 0xdb, 0x90, 0x0b, 0x6d, 0x6b, 0xa2, 0x13, 0x70, + 0x74, 0xe9, 0x5a, 0x6d, 0xe9, 0x45, 0xad, 0xf9, 0x52, 0xff, 0xdb, 0xc2, 0x03, 0x55, 0x6a, 0x8d, + 0x7e, 0xcb, 0x12, 0x3a, 0x0e, 0xd3, 0xd1, 0x2a, 0x56, 0x91, 0x98, 0x4b, 0x7d, 0xf0, 0x47, 0x4f, + 0x1d, 0x39, 0xff, 0xe7, 0x12, 0x4c, 0xc7, 0x78, 0xb9, 0xe8, 0x34, 0xdc, 0xbf, 0x71, 0xf5, 0x6a, + 0x4d, 0xd5, 0x1a, 0xeb, 0x95, 0xcd, 0xc6, 0xb5, 0x8d, 0xa6, 0xa6, 0xd6, 0x1a, 0x5b, 0xab, 0xcd, + 0x50, 0xa3, 0x0b, 0x70, 0x5f, 0x3c, 0x48, 0x65, 0x69, 0xa9, 0xb6, 0xd9, 0x64, 0x8f, 0x1b, 0x0f, + 0x81, 0xa8, 0x6e, 0xa8, 0x4d, 0x39, 0x31, 0x9c, 0x84, 0x5a, 0xbb, 0x5e, 0x5b, 0x6a, 0xca, 0x49, + 0x74, 0x16, 0xce, 0x1c, 0x04, 0xa1, 0x5d, 0xdd, 0x50, 0xd7, 0x2a, 0x4d, 0x39, 0x35, 0x12, 0xb0, + 0x51, 0x5b, 0x5f, 0xae, 0xa9, 0xf2, 0x04, 0x1f, 0xf7, 0x1b, 0x09, 0x98, 0x1d, 0xe6, 0x4c, 0x13, + 0x5a, 0x95, 0xcd, 0xcd, 0xd5, 0x97, 0x03, 0x5a, 0x4b, 0xd7, 0xb6, 0xd6, 0x5f, 0x1c, 0x64, 0xc1, + 0x43, 0xa0, 0x1c, 0x04, 0xe8, 0x33, 0xe2, 0x41, 0x38, 0x7d, 0x20, 0x1c, 0x67, 0xc7, 0x08, 0x30, + 0xb5, 0xd6, 0x54, 0x5f, 0x96, 0x93, 0x68, 0x11, 0xce, 0x8f, 0x04, 0xf3, 0xeb, 0xe4, 0x14, 0xba, + 0x00, 0x8f, 0x1c, 0x0c, 0xcf, 0x18, 0x24, 0x10, 0x04, 0x8b, 0x5e, 0x97, 0xe0, 0x68, 0xac, 0x57, + 0x8e, 0xce, 0xc0, 0xfc, 0xa6, 0xba, 0xb1, 0x54, 0x6b, 0x34, 0xb4, 0x4d, 0x75, 0x63, 0x73, 0xa3, + 0x51, 0x59, 0xd5, 0x1a, 0xcd, 0x4a, 0x73, 0xab, 0x11, 0xe2, 0x8d, 0x02, 0xa7, 0x86, 0x01, 0xf9, + 0x7c, 0x39, 0x00, 0x86, 0x4b, 0x80, 0x90, 0xd3, 0xbb, 0x12, 0x9c, 0x18, 0xea, 0x85, 0xa3, 0x73, + 0xf0, 0x00, 0xfd, 0x9d, 0xb2, 0x97, 0xb5, 0x1b, 0x1b, 0xcd, 0xf0, 0x2b, 0xda, 0x03, 0xbd, 0x3a, + 0x0b, 0x67, 0x0e, 0x84, 0xf4, 0xbb, 0x36, 0x0a, 0xb0, 0xaf, 0x7f, 0xdf, 0x26, 0x41, 0xa9, 0x4f, + 0x17, 0xa2, 0xfb, 0x60, 0x76, 0xad, 0xde, 0xa8, 0xd6, 0xae, 0x55, 0x6e, 0xd4, 0x37, 0xd4, 0xfe, + 0x35, 0x7b, 0x06, 0xe6, 0x07, 0x6a, 0x97, 0xb7, 0x36, 0x57, 0xeb, 0x4b, 0x95, 0x66, 0x8d, 0x36, + 0x2a, 0x4b, 0x64, 0x60, 0x03, 0x40, 0xab, 0xf5, 0x95, 0x6b, 0x4d, 0x6d, 0x69, 0xb5, 0x5e, 0x5b, + 0x6f, 0x6a, 0x95, 0x66, 0xb3, 0x12, 0x2c, 0xe7, 0xea, 0x8b, 0x43, 0x8f, 0xbe, 0x5e, 0x1c, 0xff, + 0xe8, 0x2b, 0x3f, 0xc2, 0x19, 0xdc, 0x56, 0x4b, 0xc0, 0xbc, 0x5f, 0xc9, 0x73, 0x69, 0xfd, 0x47, + 0x3c, 0xa7, 0x7d, 0xed, 0xce, 0x01, 0x86, 0xdf, 0xf8, 0x7c, 0x0e, 0x92, 0x95, 0x6e, 0x97, 0x68, + 0x3e, 0xfa, 0x6d, 0xd8, 0x6d, 0xae, 0x57, 0xfd, 0x6f, 0x52, 0xe7, 0xda, 0x3b, 0xde, 0x6d, 0xdd, + 0xf1, 0x7f, 0x79, 0x4d, 0x7c, 0x2b, 0xcf, 0x40, 0xd6, 0x8f, 0x1e, 0xe8, 0xdb, 0xa5, 0xfe, 0x3d, + 0xa4, 0x94, 0xb8, 0x67, 0xc4, 0x2f, 0x6b, 0x24, 0x82, 0xcb, 0x1a, 0xa9, 0x2f, 0xbe, 0x31, 0x2f, + 0x55, 0xd7, 0x87, 0x72, 0xe7, 0xc9, 0xf1, 0xb9, 0x13, 0x30, 0xc0, 0x67, 0xd0, 0xf7, 0xdd, 0x1f, + 0xba, 0x0d, 0xec, 0x9f, 0x38, 0x0d, 0xb3, 0x27, 0xe6, 0x3c, 0xfe, 0xa8, 0x33, 0xae, 0x63, 0x9c, + 0x61, 0x1d, 0x35, 0x2b, 0xf7, 0x7a, 0xc8, 0xf5, 0x19, 0x28, 0x6c, 0xea, 0x8e, 0xd7, 0xc0, 0xde, + 0x35, 0xac, 0xb7, 0xb0, 0x13, 0xbd, 0x9b, 0x5b, 0x10, 0x77, 0x73, 0x85, 0x3d, 0x4b, 0x04, 0xf6, + 0x4c, 0x31, 0x21, 0x45, 0x9f, 0x13, 0x1e, 0x7a, 0xc8, 0x84, 0x1d, 0x0a, 0xe1, 0x87, 0x4c, 0xe8, + 0x07, 0xba, 0x2c, 0x6e, 0xdf, 0x26, 0x47, 0xdc, 0xbe, 0x15, 0x91, 0x13, 0xbb, 0x83, 0xdb, 0x81, + 0x49, 0xee, 0xcd, 0xc4, 0xee, 0xde, 0xae, 0x43, 0xa9, 0xab, 0x3b, 0x1e, 0xfd, 0xb5, 0x92, 0x3d, + 0x3a, 0x0c, 0xee, 0x89, 0xc4, 0x5d, 0x9f, 0x8a, 0x0c, 0x97, 0x37, 0x53, 0xe8, 0x86, 0x0b, 0x95, + 0x2f, 0xa6, 0x20, 0xcd, 0xd9, 0xf1, 0x7c, 0xf4, 0xa4, 0x5b, 0xc4, 0x31, 0x0f, 0xc4, 0x3f, 0x08, + 0x72, 0x39, 0x41, 0x3f, 0x2d, 0xfd, 0x50, 0xff, 0xb9, 0xb2, 0x6a, 0xee, 0xf3, 0x6f, 0xce, 0x4f, + 0xd2, 0x4c, 0x71, 0x7d, 0x39, 0x38, 0x64, 0xf6, 0xf6, 0x7b, 0x41, 0xcb, 0x50, 0x08, 0xe5, 0xb0, + 0xcd, 0x16, 0xdf, 0xf8, 0x9f, 0x1b, 0xee, 0x29, 0x8a, 0x6d, 0x5e, 0x3f, 0xbf, 0x5d, 0x6f, 0xa1, + 0x73, 0x20, 0x87, 0x76, 0x9e, 0x59, 0x78, 0xce, 0x92, 0xb7, 0xc5, 0xb6, 0xbf, 0xa7, 0x4c, 0x37, + 0x5e, 0x4f, 0x42, 0x96, 0xfe, 0x80, 0x4e, 0x68, 0x7f, 0x36, 0x43, 0x0a, 0x68, 0xe5, 0x59, 0x28, + 0xf5, 0x6f, 0xe1, 0xb2, 0x4d, 0xd9, 0xe2, 0xad, 0xe8, 0xf6, 0xed, 0xb0, 0x0d, 0xdf, 0xec, 0xd0, + 0x0d, 0xdf, 0x07, 0xa1, 0x18, 0x24, 0x25, 0x28, 0x2c, 0x30, 0x4f, 0xdb, 0x2f, 0xa5, 0x60, 0xe1, + 0xfc, 0x42, 0x2e, 0x92, 0x5f, 0xf0, 0x77, 0x06, 0x78, 0xb6, 0x85, 0xc1, 0xe4, 0xd9, 0x9e, 0x31, + 0xa9, 0xe0, 0x49, 0x15, 0x0a, 0x7b, 0x06, 0x0a, 0xe2, 0x92, 0x22, 0x83, 0x2b, 0x50, 0xb8, 0xbc, + 0x28, 0x1c, 0xba, 0x07, 0x5d, 0x8c, 0xdf, 0x83, 0x9e, 0x85, 0xd4, 0x32, 0x8f, 0x8a, 0xfb, 0x72, + 0x6c, 0x9f, 0x4d, 0x42, 0x8a, 0x6e, 0x2b, 0x3d, 0x19, 0x71, 0xcc, 0xe3, 0x44, 0x9a, 0x84, 0x07, + 0xb8, 0xb5, 0xe6, 0xee, 0x86, 0xfc, 0xf2, 0x61, 0x47, 0x4c, 0xfc, 0xd4, 0x46, 0x32, 0x9c, 0xda, + 0xb8, 0x0a, 0x19, 0x5f, 0x4e, 0x52, 0x23, 0xe5, 0xa4, 0x44, 0xe4, 0x84, 0x88, 0x31, 0x2f, 0x50, + 0x27, 0x79, 0x78, 0x81, 0xaa, 0x90, 0xf5, 0x35, 0x8c, 0x2f, 0x70, 0xe3, 0xc8, 0x6c, 0x80, 0x16, + 0x7f, 0x16, 0x23, 0x3d, 0xe4, 0x2c, 0x46, 0x58, 0xb0, 0xf8, 0x6f, 0x6f, 0x4e, 0xd2, 0x81, 0x05, + 0x82, 0xc5, 0x7e, 0x7f, 0xf3, 0x3e, 0xc8, 0x06, 0xf1, 0x15, 0x93, 0xbd, 0xa0, 0x80, 0xd4, 0x06, + 0x91, 0x1a, 0x93, 0xb5, 0xd0, 0x8f, 0x38, 0x0f, 0x89, 0xd2, 0x60, 0x58, 0x94, 0xa6, 0xfc, 0x5b, + 0x09, 0xd2, 0xfc, 0xb8, 0xc5, 0x01, 0x69, 0x01, 0x36, 0x0f, 0x89, 0x61, 0xf3, 0x90, 0x7c, 0x4b, + 0xf3, 0x00, 0x7e, 0x3f, 0xc5, 0x21, 0xd3, 0xfb, 0x62, 0x93, 0x73, 0xa4, 0x93, 0x0d, 0x73, 0x57, + 0xec, 0x13, 0x05, 0x58, 0xca, 0x9b, 0x12, 0x31, 0xbf, 0xbc, 0x7e, 0x30, 0xf0, 0x94, 0x0e, 0x1d, + 0x78, 0x1e, 0xee, 0x94, 0x4d, 0x44, 0x94, 0x92, 0xf7, 0x26, 0x4a, 0x91, 0x49, 0x4f, 0xf5, 0x4d, + 0xba, 0xf2, 0x05, 0x89, 0xff, 0x7e, 0xb3, 0x9f, 0xfc, 0xfb, 0x2b, 0x9a, 0xad, 0xaf, 0xe7, 0xf2, + 0xd5, 0xc2, 0x2d, 0x6d, 0x60, 0xda, 0x1e, 0x88, 0xbb, 0x37, 0x1d, 0xe9, 0x75, 0x30, 0x7d, 0x48, + 0x90, 0x69, 0x04, 0xd3, 0xf8, 0x73, 0x09, 0x71, 0x2a, 0x2d, 0x04, 0xff, 0x37, 0x70, 0x3a, 0xa3, + 0x6b, 0x78, 0x62, 0xcc, 0x35, 0x9c, 0x1e, 0xba, 0x86, 0x7f, 0x2e, 0x41, 0xdf, 0xd9, 0x60, 0x67, + 0x04, 0xbe, 0x16, 0x3a, 0xf8, 0x24, 0x64, 0xbb, 0x76, 0x5b, 0x63, 0x35, 0xec, 0x31, 0xfe, 0x4c, + 0xd7, 0x6e, 0xab, 0x03, 0xa2, 0x36, 0xf1, 0x76, 0x29, 0xe8, 0xf4, 0xdb, 0x30, 0x0d, 0x93, 0xfd, + 0xab, 0xca, 0x83, 0x3c, 0xe3, 0x05, 0xf7, 0xa0, 0x2e, 0x12, 0x26, 0x50, 0x9f, 0x4c, 0xea, 0xf7, + 0xf9, 0xfc, 0x7e, 0x33, 0x50, 0x95, 0x03, 0x12, 0x94, 0xc8, 0x49, 0xb7, 0x13, 0x43, 0x35, 0x97, + 0x38, 0xd9, 0xa3, 0x7c, 0x58, 0x02, 0x58, 0x25, 0xcc, 0xa5, 0x23, 0x26, 0xce, 0x8f, 0x4b, 0x3b, + 0xa1, 0x45, 0xda, 0x9e, 0x1f, 0x3a, 0x71, 0xbc, 0x07, 0x79, 0x37, 0xdc, 0xf5, 0x65, 0x28, 0x04, + 0x02, 0xee, 0x62, 0xd1, 0x9d, 0xf9, 0x83, 0x2e, 0xb2, 0x36, 0xb0, 0xa7, 0xe6, 0x6f, 0x85, 0xbe, + 0x94, 0x7f, 0x27, 0x41, 0x96, 0xf6, 0x6a, 0x0d, 0x7b, 0x7a, 0x64, 0x22, 0xa5, 0xb7, 0x30, 0x91, + 0xf7, 0x03, 0x30, 0x3a, 0xae, 0xf9, 0x1a, 0xe6, 0xf2, 0x95, 0xa5, 0x25, 0x0d, 0xf3, 0x35, 0x8c, + 0x9e, 0xf2, 0xb9, 0x9e, 0x1c, 0xc1, 0x75, 0x91, 0xbc, 0xe5, 0xbc, 0x3f, 0x0e, 0x93, 0x56, 0xaf, + 0xa3, 0xb1, 0xc3, 0xa4, 0x54, 0x68, 0xad, 0x5e, 0xa7, 0x79, 0xc7, 0x55, 0x6e, 0xc2, 0x64, 0xf3, + 0x0e, 0x7b, 0xbf, 0xe7, 0x24, 0x64, 0x1d, 0xdb, 0xe6, 0xde, 0x20, 0x73, 0xc4, 0x33, 0xa4, 0x80, + 0x3a, 0x3f, 0x71, 0x39, 0xff, 0x0b, 0xe3, 0xba, 0xfd, 0xdc, 0xe1, 0x3f, 0xff, 0x9b, 0x12, 0x14, + 0x22, 0x2b, 0x0a, 0x3d, 0x0a, 0xc7, 0x1b, 0xf5, 0x95, 0xf5, 0xda, 0xb2, 0xb6, 0xd6, 0x58, 0xe9, + 0x0b, 0xb0, 0xe7, 0x4a, 0xaf, 0xdf, 0x5d, 0xc8, 0xf1, 0xab, 0xaa, 0xc3, 0xa0, 0x37, 0xd5, 0x1a, + 0x8b, 0xb4, 0x19, 0xf4, 0xa6, 0x83, 0x6f, 0xd9, 0x1e, 0xa6, 0xd0, 0x8f, 0xc3, 0x89, 0x18, 0x68, + 0xff, 0xc2, 0xea, 0xd4, 0xeb, 0x77, 0x17, 0x0a, 0x9b, 0x0e, 0x66, 0xa2, 0x46, 0x31, 0x16, 0x61, + 0x76, 0x10, 0x83, 0x65, 0x35, 0xe4, 0x85, 0x39, 0xf9, 0xf5, 0xbb, 0x0b, 0x79, 0xa1, 0x3b, 0x08, + 0xfc, 0x3b, 0x7e, 0x63, 0xf5, 0xa3, 0x59, 0x38, 0xc1, 0xde, 0xb0, 0xd2, 0x58, 0x0c, 0xc8, 0x3e, + 0x78, 0x48, 0x9a, 0x0f, 0x57, 0x8d, 0xfe, 0x71, 0x02, 0xe5, 0x45, 0x98, 0xae, 0x5b, 0x1e, 0x76, + 0x76, 0xf4, 0xf0, 0xcf, 0x0b, 0xc7, 0xfe, 0x60, 0xef, 0x42, 0xe4, 0x95, 0x4d, 0x1e, 0xc1, 0x87, + 0x8b, 0x94, 0x6f, 0x91, 0x40, 0x6e, 0x18, 0x7a, 0x5b, 0x77, 0xde, 0x2a, 0x29, 0xf4, 0x94, 0xf8, + 0x51, 0x0a, 0x7e, 0x41, 0x24, 0x79, 0xae, 0x78, 0x69, 0x76, 0x31, 0x3c, 0xb8, 0x45, 0xd6, 0x12, + 0xd5, 0xc1, 0xec, 0xc7, 0x28, 0xc8, 0x9f, 0xe7, 0x5f, 0x02, 0x08, 0x2a, 0xd0, 0x49, 0x38, 0xde, + 0x58, 0xaa, 0xac, 0x56, 0xfc, 0x3c, 0x4d, 0x63, 0xb3, 0xb6, 0xc4, 0x7e, 0xf9, 0xfe, 0x08, 0x3a, + 0x06, 0x28, 0x5c, 0xe9, 0xff, 0xce, 0xdc, 0x51, 0x98, 0x0a, 0x97, 0xb3, 0x9f, 0x21, 0x4f, 0x94, + 0xaf, 0x41, 0x89, 0xfd, 0x46, 0x32, 0x31, 0x80, 0xb8, 0xa5, 0x99, 0x16, 0x1a, 0xf1, 0x93, 0xc3, + 0xb3, 0xbf, 0xfa, 0x5f, 0xd9, 0x4f, 0x54, 0x14, 0x18, 0x62, 0x85, 0xe0, 0xd5, 0xad, 0x72, 0x13, + 0x66, 0xe8, 0x8d, 0x70, 0xfa, 0xb3, 0x32, 0x9a, 0x29, 0xf8, 0x3f, 0xfa, 0x0d, 0x41, 0x42, 0x2f, + 0x79, 0x2e, 0xab, 0x4e, 0x07, 0xe8, 0xfe, 0xec, 0x95, 0x5f, 0x0c, 0x7e, 0x54, 0xc4, 0xef, 0xe0, + 0x48, 0x8a, 0xbf, 0xc6, 0x7b, 0x28, 0x9e, 0x10, 0x16, 0x5d, 0x5c, 0x85, 0x29, 0xdd, 0x30, 0x70, + 0x37, 0xd2, 0xbf, 0x11, 0xcf, 0xb6, 0x89, 0xd1, 0xca, 0x1c, 0x33, 0xe8, 0xda, 0x53, 0x90, 0x76, + 0xe9, 0xa4, 0x8c, 0x22, 0x21, 0xba, 0xc3, 0xc1, 0xcb, 0x35, 0x28, 0x32, 0x31, 0xf0, 0x47, 0x34, + 0x82, 0xc0, 0x7f, 0xe4, 0x04, 0xf2, 0x14, 0x4d, 0x8c, 0xc6, 0x82, 0xa9, 0x16, 0x36, 0xda, 0xba, + 0x83, 0x43, 0xa3, 0x39, 0xf8, 0xe9, 0xe2, 0x7f, 0xf9, 0xe9, 0xc7, 0xfd, 0x3d, 0xf4, 0x90, 0xd0, + 0xc5, 0x2c, 0x16, 0x55, 0xe6, 0xb4, 0x83, 0xf1, 0x62, 0x28, 0x8a, 0xf6, 0xf8, 0xb8, 0x0f, 0x6e, + 0xec, 0x5f, 0xf1, 0xc6, 0x4e, 0xc5, 0x49, 0x78, 0xa8, 0xa5, 0x02, 0xa7, 0xca, 0x2a, 0xca, 0x55, + 0x28, 0xec, 0x98, 0xed, 0xd0, 0x74, 0x1f, 0xdc, 0xca, 0xbf, 0xfe, 0xf4, 0xe3, 0x6c, 0xa1, 0x11, + 0x24, 0xce, 0x9a, 0x7b, 0xfa, 0xc9, 0x14, 0x4a, 0xfd, 0xd9, 0x70, 0x57, 0x7d, 0xed, 0xf4, 0x89, + 0x24, 0x9c, 0xe2, 0xc0, 0xdb, 0xba, 0x8b, 0x89, 0xe2, 0xc2, 0x9e, 0x7e, 0xf1, 0x82, 0x61, 0x9b, + 0x56, 0x90, 0x54, 0xa4, 0x0a, 0x8b, 0xd4, 0x2f, 0xf2, 0xfa, 0x21, 0x39, 0xad, 0xe1, 0x8a, 0x6e, + 0x6e, 0xf0, 0x67, 0x7b, 0x94, 0x36, 0xa4, 0x96, 0x6c, 0xd3, 0x22, 0x3e, 0x57, 0x0b, 0x5b, 0x76, + 0x47, 0x9c, 0x57, 0xa4, 0x1f, 0xe8, 0x1a, 0xa4, 0xf5, 0x8e, 0xdd, 0xb3, 0xf8, 0xfb, 0x6d, 0xd5, + 0xc7, 0x89, 0x2d, 0xfc, 0xed, 0x37, 0xe7, 0x8f, 0x32, 0xb2, 0x6e, 0xeb, 0xe6, 0xa2, 0x69, 0x5f, + 0xe8, 0xe8, 0xde, 0x1e, 0x99, 0xe4, 0xdf, 0xf8, 0xcc, 0x63, 0xc0, 0xdb, 0xab, 0x5b, 0xde, 0x27, + 0xff, 0xe0, 0x67, 0xce, 0x4b, 0x2a, 0xc7, 0x67, 0x69, 0x47, 0xa5, 0x0b, 0x93, 0xcb, 0xd8, 0x38, + 0xa0, 0xc1, 0x7a, 0x5f, 0x83, 0x17, 0x79, 0x83, 0x27, 0x07, 0x1b, 0x64, 0xbf, 0x23, 0xb8, 0x8c, + 0x8d, 0x50, 0xb3, 0xcb, 0xd8, 0x88, 0xb6, 0x58, 0x5d, 0xfe, 0xad, 0xdf, 0x3b, 0x75, 0xe4, 0x7d, + 0x9f, 0x3f, 0x75, 0x64, 0xe8, 0x94, 0x29, 0xa3, 0x7f, 0xe5, 0xc6, 0x9f, 0xa9, 0xff, 0x2d, 0xc1, + 0x89, 0x7e, 0xf3, 0xa0, 0x5b, 0xfb, 0xc3, 0xde, 0x3c, 0xb8, 0x02, 0xc9, 0x8a, 0xb5, 0x8f, 0x4e, + 0xb0, 0xd7, 0x5c, 0xb5, 0x9e, 0xd3, 0x16, 0xc7, 0x3c, 0xc9, 0xf7, 0x96, 0xd3, 0x8e, 0x1e, 0x29, + 0xf0, 0x5f, 0xe6, 0xfa, 0xee, 0x43, 0x3e, 0x77, 0x90, 0xa9, 0x58, 0xfb, 0xe2, 0xa1, 0x83, 0x47, + 0xc7, 0x7c, 0xe8, 0x40, 0xb7, 0xf6, 0xbb, 0xdb, 0x87, 0x7d, 0xdf, 0xe0, 0x03, 0x97, 0xe1, 0x01, + 0xce, 0x23, 0xd7, 0xd3, 0x6f, 0x9a, 0xd6, 0xae, 0x2f, 0xac, 0xfc, 0x9b, 0xb3, 0xe2, 0x18, 0x9f, + 0x10, 0x51, 0x2a, 0x44, 0x76, 0x50, 0x02, 0xe7, 0x0e, 0x7c, 0x30, 0x61, 0xee, 0xe0, 0x6c, 0xf2, + 0xdc, 0x88, 0x75, 0x73, 0xd0, 0x62, 0x18, 0xb2, 0x7a, 0x86, 0x4e, 0xef, 0xc8, 0xd7, 0xc3, 0x46, + 0x26, 0x93, 0x3f, 0x2c, 0x41, 0xf1, 0x9a, 0xe9, 0x7a, 0xb6, 0x63, 0x1a, 0x7a, 0x9b, 0x6e, 0xa4, + 0xbf, 0x6b, 0x6c, 0xef, 0xbf, 0x9a, 0x25, 0x4b, 0x81, 0x2f, 0xaa, 0x3d, 0xe1, 0x80, 0xa7, 0x6f, + 0xe9, 0x6d, 0xe6, 0x79, 0x87, 0xf5, 0x6e, 0x3f, 0xdb, 0x43, 0xfb, 0xcb, 0x61, 0x2a, 0x0c, 0xb7, + 0x9c, 0x98, 0x95, 0x94, 0xef, 0x4f, 0x40, 0x89, 0x86, 0x0c, 0x2e, 0x3d, 0x10, 0x46, 0x8f, 0x1c, + 0x5d, 0x87, 0x94, 0xa3, 0x7b, 0xdc, 0x09, 0xa9, 0x5e, 0x39, 0xf4, 0x4a, 0x64, 0xad, 0x50, 0x1a, + 0xe8, 0xdd, 0x90, 0xe9, 0xe8, 0x77, 0x34, 0x4a, 0x2f, 0xf1, 0x96, 0xe8, 0x4d, 0x76, 0xf4, 0x3b, + 0xa4, 0x7f, 0xe8, 0x9b, 0xa0, 0x44, 0x48, 0x1a, 0x7b, 0xba, 0xb5, 0x8b, 0x19, 0xe5, 0xe4, 0x5b, + 0xa2, 0x5c, 0xe8, 0xe8, 0x77, 0x96, 0x28, 0x35, 0x42, 0x9f, 0x6b, 0xac, 0x5f, 0x92, 0xf8, 0xe9, + 0x2a, 0xca, 0x18, 0xa4, 0x83, 0x6c, 0xf8, 0x5f, 0xb4, 0x51, 0x71, 0x68, 0xf9, 0xec, 0x30, 0xde, + 0xf7, 0xb1, 0xb5, 0x5a, 0x20, 0xdd, 0xfb, 0xdc, 0x9b, 0xf3, 0x12, 0x6b, 0xb5, 0x64, 0x0c, 0xb0, + 0x3d, 0xc7, 0x4e, 0x8d, 0x69, 0x34, 0xb3, 0x9d, 0x18, 0x19, 0x84, 0x16, 0x44, 0x10, 0xca, 0x08, + 0x02, 0xc3, 0x26, 0xf5, 0x7c, 0x0c, 0x7f, 0x2a, 0x41, 0x6e, 0x39, 0xe4, 0x27, 0xce, 0xc2, 0x64, + 0xc7, 0xb6, 0xcc, 0x9b, 0xd8, 0xf1, 0x4f, 0x9d, 0xb3, 0x4f, 0x34, 0x07, 0x19, 0xf6, 0x0b, 0x90, + 0xde, 0xbe, 0xd8, 0x6d, 0x12, 0xdf, 0x04, 0xeb, 0x36, 0xde, 0x76, 0x4d, 0xc1, 0x67, 0x55, 0x7c, + 0xa2, 0x87, 0x41, 0x76, 0xb1, 0xd1, 0x73, 0x4c, 0x6f, 0x5f, 0x33, 0x6c, 0xcb, 0xd3, 0x0d, 0x8f, + 0x1f, 0x56, 0x2a, 0x89, 0xf2, 0x25, 0x56, 0x4c, 0x88, 0xb4, 0xb0, 0xa7, 0x9b, 0x6d, 0x76, 0x19, + 0x3b, 0xab, 0x8a, 0x4f, 0xb4, 0x12, 0xda, 0xfe, 0x4f, 0xfb, 0xbb, 0x13, 0xb1, 0x1c, 0x15, 0xbf, + 0x37, 0x1f, 0x16, 0x66, 0x1f, 0x99, 0x8f, 0x79, 0x07, 0x32, 0x02, 0x0c, 0x3d, 0x04, 0xa5, 0xae, + 0x63, 0x53, 0xab, 0xdf, 0x35, 0x0d, 0xad, 0xe7, 0x98, 0x7c, 0xdc, 0x05, 0x5e, 0xbc, 0x69, 0x1a, + 0x5b, 0x8e, 0x89, 0x1e, 0x05, 0xe4, 0xda, 0x06, 0xbd, 0x08, 0xae, 0x5b, 0xad, 0x36, 0x51, 0xd8, + 0x26, 0x3b, 0x6b, 0x96, 0x55, 0x65, 0x56, 0x73, 0x8d, 0x56, 0x6c, 0x39, 0xa6, 0xcb, 0xdb, 0xb9, + 0x3b, 0x19, 0x3e, 0x5b, 0xb4, 0x04, 0xb2, 0xdd, 0xc5, 0x4e, 0x24, 0xe3, 0xc3, 0x96, 0xcf, 0xec, + 0x6f, 0x7c, 0xe6, 0xb1, 0x19, 0x3e, 0x1e, 0x9e, 0xf3, 0x61, 0xaf, 0x38, 0xaa, 0x25, 0x81, 0x21, + 0x52, 0x41, 0x2f, 0x47, 0x0e, 0xc6, 0xf7, 0xb6, 0x83, 0x37, 0x99, 0x66, 0x06, 0xa4, 0xa0, 0x62, + 0xed, 0x57, 0x67, 0x7f, 0x2d, 0x20, 0xcd, 0xe3, 0xc5, 0x4d, 0x7a, 0xd2, 0x28, 0x7c, 0x48, 0x9e, + 0x92, 0x41, 0xc7, 0x20, 0xfd, 0xaa, 0x6e, 0xb6, 0xc5, 0xaf, 0xfb, 0xaa, 0xfc, 0x0b, 0x95, 0xfd, + 0x83, 0x9f, 0x29, 0x9a, 0xc1, 0x51, 0x86, 0xb1, 0xbe, 0x6a, 0x5b, 0xad, 0xe8, 0x79, 0x4f, 0xb4, + 0x04, 0x69, 0xcf, 0xbe, 0x89, 0x2d, 0x3e, 0xa3, 0xd5, 0x47, 0x0e, 0xe1, 0x23, 0xa8, 0x1c, 0x15, + 0x7d, 0x03, 0xc8, 0x2d, 0xdc, 0xc6, 0xbb, 0x2c, 0x95, 0xb0, 0xa7, 0x3b, 0x98, 0xe5, 0xb4, 0xef, + 0xc9, 0x03, 0x28, 0xf9, 0xa4, 0x1a, 0x94, 0x12, 0xda, 0x8c, 0x86, 0x4e, 0x93, 0xfe, 0x9d, 0xae, + 0xd8, 0x31, 0x86, 0x96, 0x4a, 0x58, 0xc2, 0x22, 0xa1, 0xd6, 0xc3, 0x20, 0xf7, 0xac, 0x6d, 0xdb, + 0xa2, 0x3f, 0x8a, 0xc9, 0x93, 0x58, 0x19, 0x76, 0x59, 0xc2, 0x2f, 0xe7, 0x97, 0x25, 0x36, 0xa1, + 0x18, 0x80, 0xd2, 0x25, 0x9d, 0x3d, 0xec, 0x92, 0x2e, 0xf8, 0x04, 0x08, 0x08, 0x5a, 0x03, 0x08, + 0x94, 0x06, 0x4d, 0xb3, 0xe7, 0x86, 0xcf, 0x58, 0xa0, 0x7e, 0xc2, 0x83, 0x09, 0x11, 0x40, 0x16, + 0x4c, 0x77, 0x4c, 0x4b, 0x73, 0x71, 0x7b, 0x47, 0xe3, 0x9c, 0x23, 0x74, 0x73, 0x94, 0xfd, 0xcf, + 0x1f, 0x62, 0x36, 0x7f, 0xfb, 0x33, 0x8f, 0x95, 0x02, 0xd7, 0x69, 0xe1, 0xf1, 0xc5, 0x27, 0x9f, + 0x52, 0xa7, 0x3a, 0xa6, 0xd5, 0xc0, 0xed, 0x9d, 0x65, 0x9f, 0x30, 0x7a, 0x17, 0x9c, 0x0c, 0x18, + 0x62, 0x5b, 0xda, 0x9e, 0xdd, 0x6e, 0x69, 0x0e, 0xde, 0xd1, 0x0c, 0xea, 0xf8, 0xe5, 0x29, 0x1b, + 0x8f, 0xfb, 0x20, 0x1b, 0xd6, 0x35, 0xbb, 0xdd, 0x52, 0xf1, 0xce, 0x12, 0xa9, 0x46, 0x67, 0x20, + 0xe0, 0x86, 0x66, 0xb6, 0xdc, 0xd9, 0xc2, 0x42, 0xf2, 0x5c, 0x4a, 0xcd, 0xfb, 0x85, 0xf5, 0x96, + 0x5b, 0xce, 0x7c, 0xf0, 0x8d, 0xf9, 0x23, 0x5f, 0x7c, 0x63, 0xfe, 0x88, 0x72, 0x95, 0xbe, 0xda, + 0xc6, 0x97, 0x16, 0x76, 0xd1, 0x15, 0xc8, 0xea, 0xe2, 0x83, 0x3d, 0x7c, 0x78, 0xc0, 0xd2, 0x0c, + 0x40, 0x95, 0x4f, 0x49, 0x90, 0x5e, 0xbe, 0xb1, 0xa9, 0x9b, 0x0e, 0xaa, 0x91, 0xc0, 0x48, 0xc8, + 0xea, 0xb8, 0xab, 0x3c, 0x10, 0x6f, 0xb1, 0xcc, 0xd7, 0x87, 0xa5, 0x87, 0xb3, 0xd5, 0xd3, 0xbf, + 0xf1, 0x99, 0xc7, 0xee, 0xe7, 0x64, 0x6e, 0xf4, 0x65, 0x8a, 0x05, 0xbd, 0xfe, 0x0c, 0x72, 0x68, + 0xcc, 0xd7, 0x61, 0x92, 0x75, 0xd5, 0x45, 0x2f, 0xc0, 0x44, 0x97, 0xfc, 0xc1, 0x4f, 0x5c, 0x9f, + 0x1a, 0x2a, 0xf3, 0x14, 0x3e, 0x2c, 0x21, 0x0c, 0x4f, 0xf9, 0x8e, 0x04, 0xc0, 0xf2, 0x8d, 0x1b, + 0x4d, 0xc7, 0xec, 0xb6, 0xb1, 0xf7, 0x76, 0x8d, 0x7d, 0x0b, 0x8e, 0x86, 0x32, 0x87, 0x8e, 0x71, + 0xf8, 0xf1, 0x4f, 0x07, 0x39, 0x44, 0xc7, 0x88, 0x25, 0xdb, 0x72, 0x3d, 0x9f, 0x6c, 0xf2, 0xf0, + 0x64, 0x97, 0x5d, 0x6f, 0x90, 0xb3, 0x2f, 0x41, 0x2e, 0x60, 0x86, 0x8b, 0xea, 0x90, 0xf1, 0xf8, + 0xdf, 0x9c, 0xc1, 0xca, 0x70, 0x06, 0x0b, 0xb4, 0x88, 0xd5, 0x12, 0xe8, 0xca, 0x5f, 0x4a, 0x00, + 0xa1, 0x35, 0xf2, 0xd7, 0x53, 0xc6, 0x48, 0x78, 0xc6, 0x95, 0x73, 0xf2, 0x9e, 0xc3, 0x33, 0x46, + 0x20, 0xc4, 0xd4, 0xef, 0x4a, 0xc0, 0xf4, 0x96, 0x58, 0xbd, 0x7f, 0xfd, 0x79, 0xb0, 0x05, 0x93, + 0xd8, 0xf2, 0x1c, 0xd3, 0xbf, 0x31, 0xf0, 0xf8, 0xb0, 0x39, 0x8f, 0x19, 0x54, 0xcd, 0xf2, 0x9c, + 0xfd, 0xb0, 0x04, 0x08, 0x5a, 0x21, 0x7e, 0x7c, 0x34, 0x09, 0xb3, 0xc3, 0x50, 0xd1, 0x59, 0x28, + 0x19, 0x0e, 0xa6, 0x05, 0xd1, 0x77, 0x38, 0x8b, 0xa2, 0x98, 0x9b, 0x1d, 0x15, 0x88, 0x67, 0x49, + 0x84, 0x8b, 0x80, 0xde, 0x9b, 0x2b, 0x59, 0x0c, 0x28, 0x50, 0xc3, 0xd3, 0x84, 0x92, 0x78, 0x2a, + 0x67, 0x5b, 0x6f, 0xeb, 0x96, 0x21, 0x5c, 0xee, 0x43, 0xd9, 0x7c, 0xf1, 0xdc, 0x4e, 0x95, 0x91, + 0x40, 0x35, 0x98, 0x14, 0xd4, 0x52, 0x87, 0xa7, 0x26, 0x70, 0xd1, 0x69, 0xc8, 0x87, 0x0d, 0x03, + 0xf5, 0x46, 0x52, 0x6a, 0x2e, 0x64, 0x17, 0x46, 0x59, 0x9e, 0xf4, 0x81, 0x96, 0x87, 0x3b, 0x7c, + 0x3f, 0x94, 0x84, 0x29, 0x15, 0xb7, 0xfe, 0xe6, 0x4f, 0xcb, 0x26, 0x00, 0x5b, 0xaa, 0x44, 0x93, + 0xf2, 0x99, 0xb9, 0x87, 0xf5, 0x9e, 0x65, 0x44, 0x96, 0x5d, 0xef, 0x6b, 0x35, 0x43, 0xbf, 0x93, + 0x80, 0x7c, 0x78, 0x86, 0xfe, 0x56, 0x1a, 0x2d, 0xb4, 0x1e, 0xa8, 0x29, 0xb6, 0x51, 0xfe, 0xf0, + 0x30, 0x35, 0x35, 0x20, 0xcd, 0x23, 0xf4, 0xd3, 0x97, 0x92, 0x90, 0xe6, 0x97, 0x6e, 0x37, 0x06, + 0x7c, 0xdb, 0x91, 0x8f, 0x30, 0x17, 0xc4, 0x3b, 0xd6, 0xb1, 0xae, 0xed, 0x83, 0x50, 0x24, 0x41, + 0x7d, 0xe4, 0x26, 0xaf, 0x74, 0xae, 0x40, 0x63, 0xf3, 0xe0, 0x60, 0x13, 0x9a, 0x87, 0x1c, 0x01, + 0x0b, 0xf4, 0x30, 0x81, 0x81, 0x8e, 0x7e, 0xa7, 0xc6, 0x4a, 0xd0, 0x45, 0x40, 0x7b, 0x7e, 0xa6, + 0x45, 0x0b, 0x18, 0x21, 0x9d, 0x2b, 0xd0, 0x17, 0xc9, 0xa7, 0x82, 0x5a, 0x81, 0x72, 0x3f, 0x00, + 0xe9, 0x89, 0xc6, 0xb2, 0x92, 0xfc, 0x67, 0xb2, 0x49, 0xc9, 0x32, 0xcd, 0x4c, 0x7e, 0x9b, 0xc4, + 0xdc, 0xe4, 0xbe, 0xf0, 0x9f, 0x47, 0x29, 0xcd, 0x31, 0x16, 0xc6, 0x9f, 0xbd, 0x39, 0x3f, 0xb7, + 0xaf, 0x77, 0xda, 0x65, 0x25, 0x86, 0x8e, 0x12, 0x97, 0x91, 0x20, 0xce, 0x73, 0x34, 0x7d, 0x80, + 0xea, 0x20, 0xdf, 0xc4, 0xfb, 0x9a, 0xc3, 0x7f, 0x49, 0x5e, 0xdb, 0xc1, 0xe2, 0x2d, 0xf4, 0x13, + 0x8b, 0x31, 0x39, 0xe2, 0xc5, 0x25, 0xdb, 0xb4, 0xf8, 0x16, 0x66, 0xf1, 0x26, 0xde, 0x57, 0x39, + 0xde, 0x55, 0x8c, 0xcb, 0x0f, 0x90, 0xd5, 0xf2, 0xfa, 0x1f, 0xfc, 0xcc, 0xf9, 0x93, 0xa1, 0x7c, + 0xe7, 0x1d, 0x3f, 0xb1, 0xc7, 0xa6, 0x98, 0x38, 0xbe, 0x28, 0x30, 0x42, 0xa1, 0xdb, 0xdb, 0x10, + 0x8a, 0x15, 0xa4, 0x83, 0x63, 0x90, 0x00, 0x3f, 0x12, 0x83, 0x84, 0x96, 0xe8, 0xf3, 0x81, 0x0d, + 0x48, 0x8c, 0x1a, 0x4d, 0x58, 0x3a, 0x39, 0x12, 0x5d, 0xf9, 0x47, 0x94, 0xff, 0x24, 0xc1, 0x89, + 0x01, 0x69, 0xf6, 0xbb, 0x6c, 0x00, 0x72, 0x42, 0x95, 0x54, 0x2a, 0xc4, 0x05, 0x9e, 0x7b, 0x5b, + 0x1c, 0x53, 0xce, 0x80, 0x21, 0x78, 0x7b, 0x8c, 0x19, 0xd7, 0x64, 0xbf, 0x2a, 0xc1, 0x4c, 0xb8, + 0x03, 0xfe, 0x50, 0x1a, 0x90, 0x0f, 0x37, 0xcd, 0x07, 0xf1, 0xc0, 0x38, 0x83, 0x08, 0xf7, 0x3f, + 0x42, 0x04, 0xdd, 0x08, 0x34, 0x06, 0x4b, 0x27, 0x5e, 0x1c, 0x9b, 0x29, 0xa2, 0x63, 0xb1, 0x9a, + 0x83, 0xcd, 0xcd, 0x97, 0x24, 0x48, 0x6d, 0xda, 0x76, 0x1b, 0xbd, 0x17, 0xa6, 0x2c, 0xdb, 0xd3, + 0xc8, 0xca, 0xc2, 0x2d, 0x8d, 0xa7, 0x0e, 0x98, 0x36, 0xae, 0x1d, 0xc8, 0xab, 0x3f, 0x7c, 0x73, + 0x7e, 0x10, 0x33, 0x6e, 0xcf, 0xa1, 0x64, 0xd9, 0x5e, 0x95, 0x02, 0x35, 0x59, 0x76, 0x61, 0x07, + 0x0a, 0xd1, 0xe6, 0x98, 0xc6, 0xae, 0x8c, 0x6a, 0xae, 0x30, 0xb2, 0xa9, 0xfc, 0x76, 0xa8, 0x1d, + 0xf6, 0xb3, 0x43, 0x7f, 0x42, 0x66, 0xee, 0x9b, 0x40, 0xbe, 0xd1, 0x7f, 0x3d, 0xf4, 0x2a, 0x4c, + 0x8a, 0xeb, 0xa0, 0xd2, 0xb8, 0x57, 0x4d, 0xc3, 0xfc, 0xe4, 0xc8, 0x34, 0x5f, 0xfb, 0xb9, 0x04, + 0x9c, 0x58, 0xb2, 0x2d, 0x97, 0x27, 0x7a, 0xf8, 0xaa, 0x66, 0xc9, 0xe5, 0x7d, 0xf4, 0xf0, 0x90, + 0x34, 0x54, 0x7e, 0x30, 0xd9, 0x74, 0x03, 0x4a, 0xc4, 0xc4, 0x1a, 0xb6, 0xf5, 0x16, 0x73, 0x4d, + 0x05, 0xbb, 0xdd, 0xe2, 0x3d, 0xba, 0x89, 0xf7, 0x09, 0x5d, 0x0b, 0xdf, 0x8e, 0xd0, 0x4d, 0xde, + 0x1b, 0x5d, 0x0b, 0xdf, 0x0e, 0xd1, 0x0d, 0xce, 0x0c, 0xa5, 0x22, 0x37, 0x90, 0xae, 0x40, 0x92, + 0xa8, 0xc2, 0x89, 0x43, 0x28, 0x0f, 0x82, 0x10, 0x32, 0x6b, 0x0d, 0x38, 0xc1, 0x33, 0x05, 0xee, + 0xc6, 0x0e, 0xe5, 0x28, 0xa6, 0x03, 0x7a, 0x11, 0xef, 0xc7, 0xa4, 0x0d, 0xf2, 0x63, 0xa5, 0x0d, + 0xce, 0xff, 0xbc, 0x04, 0x10, 0xe4, 0xcc, 0xd0, 0xa3, 0x70, 0xbc, 0xba, 0xb1, 0xbe, 0x1c, 0x5c, + 0xc6, 0x08, 0x6d, 0xad, 0x8b, 0x53, 0x1a, 0x6e, 0x17, 0x1b, 0xe6, 0x8e, 0x89, 0x5b, 0xe8, 0x21, + 0x98, 0x89, 0x42, 0x93, 0xaf, 0xda, 0xb2, 0x2c, 0xcd, 0xe5, 0x5f, 0xbf, 0xbb, 0x90, 0x61, 0x31, + 0x02, 0x6e, 0xa1, 0x73, 0x70, 0x74, 0x10, 0xae, 0xbe, 0xbe, 0x22, 0x27, 0xe6, 0x0a, 0xaf, 0xdf, + 0x5d, 0xc8, 0xfa, 0xc1, 0x04, 0x52, 0x00, 0x85, 0x21, 0x39, 0xbd, 0xe4, 0x1c, 0xbc, 0x7e, 0x77, + 0x21, 0xcd, 0x96, 0x0c, 0xbf, 0xc5, 0xf1, 0x8d, 0x00, 0x75, 0x6b, 0xc7, 0xd1, 0x0d, 0xaa, 0x1a, + 0xe6, 0xe0, 0x58, 0x7d, 0xfd, 0xaa, 0x5a, 0x59, 0x6a, 0xd6, 0x37, 0xd6, 0xfb, 0x4e, 0x04, 0x44, + 0xeb, 0x96, 0x37, 0xb6, 0xaa, 0xab, 0x35, 0xad, 0x51, 0x5f, 0x59, 0x67, 0x57, 0xae, 0x22, 0x75, + 0xef, 0x59, 0x6f, 0xd6, 0xd7, 0x6a, 0x72, 0xa2, 0x7a, 0x65, 0xe8, 0x76, 0xdc, 0x7d, 0x91, 0xc5, + 0x18, 0x98, 0xa3, 0xc8, 0x46, 0xdc, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xbf, 0x2e, 0x6f, 0x47, + 0xe8, 0xa7, 0x00, 0x00, } r := bytes.NewReader(gzipped) gzipr, err := compress_gzip.NewReader(r) @@ -2366,6 +2443,41 @@ func (this *Description) Equal(that interface{}) bool { if this.Details != that1.Details { return false } + if !this.Metadata.Equal(&that1.Metadata) { + return false + } + return true +} +func (this *Metadata) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Metadata) + if !ok { + that2, ok := that.(Metadata) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.ProfilePicUri != that1.ProfilePicUri { + return false + } + if len(this.SocialHandleUris) != len(that1.SocialHandleUris) { + return false + } + for i := range this.SocialHandleUris { + if this.SocialHandleUris[i] != that1.SocialHandleUris[i] { + return false + } + } return true } func (this *UnbondingDelegationEntry) Equal(that interface{}) bool { @@ -2703,6 +2815,16 @@ func (m *Description) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintStaking(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 if len(m.Details) > 0 { i -= len(m.Details) copy(dAtA[i:], m.Details) @@ -2741,6 +2863,45 @@ func (m *Description) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Metadata) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Metadata) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Metadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SocialHandleUris) > 0 { + for iNdEx := len(m.SocialHandleUris) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SocialHandleUris[iNdEx]) + copy(dAtA[i:], m.SocialHandleUris[iNdEx]) + i = encodeVarintStaking(dAtA, i, uint64(len(m.SocialHandleUris[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.ProfilePicUri) > 0 { + i -= len(m.ProfilePicUri) + copy(dAtA[i:], m.ProfilePicUri) + i = encodeVarintStaking(dAtA, i, uint64(len(m.ProfilePicUri))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Validator) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2762,20 +2923,20 @@ func (m *Validator) MarshalToSizedBuffer(dAtA []byte) (int, error) { var l int _ = l if len(m.UnbondingIds) > 0 { - dAtA5 := make([]byte, len(m.UnbondingIds)*10) - var j4 int + dAtA6 := make([]byte, len(m.UnbondingIds)*10) + var j5 int for _, num := range m.UnbondingIds { for num >= 1<<7 { - dAtA5[j4] = uint8(uint64(num)&0x7f | 0x80) + dAtA6[j5] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j4++ + j5++ } - dAtA5[j4] = uint8(num) - j4++ + dAtA6[j5] = uint8(num) + j5++ } - i -= j4 - copy(dAtA[i:], dAtA5[:j4]) - i = encodeVarintStaking(dAtA, i, uint64(j4)) + i -= j5 + copy(dAtA[i:], dAtA6[:j5]) + i = encodeVarintStaking(dAtA, i, uint64(j5)) i-- dAtA[i] = 0x6a } @@ -2804,12 +2965,12 @@ func (m *Validator) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x52 - n7, err7 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.UnbondingTime):]) - if err7 != nil { - return 0, err7 + n8, err8 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.UnbondingTime):]) + if err8 != nil { + return 0, err8 } - i -= n7 - i = encodeVarintStaking(dAtA, i, uint64(n7)) + i -= n8 + i = encodeVarintStaking(dAtA, i, uint64(n8)) i-- dAtA[i] = 0x4a if m.UnbondingHeight != 0 { @@ -3219,12 +3380,12 @@ func (m *UnbondingDelegationEntry) MarshalToSizedBuffer(dAtA []byte) (int, error } i-- dAtA[i] = 0x1a - n10, err10 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) - if err10 != nil { - return 0, err10 + n11, err11 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) + if err11 != nil { + return 0, err11 } - i -= n10 - i = encodeVarintStaking(dAtA, i, uint64(n10)) + i -= n11 + i = encodeVarintStaking(dAtA, i, uint64(n11)) i-- dAtA[i] = 0x12 if m.CreationHeight != 0 { @@ -3285,12 +3446,12 @@ func (m *RedelegationEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x1a - n11, err11 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) - if err11 != nil { - return 0, err11 + n12, err12 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) + if err12 != nil { + return 0, err12 } - i -= n11 - i = encodeVarintStaking(dAtA, i, uint64(n11)) + i -= n12 + i = encodeVarintStaking(dAtA, i, uint64(n12)) i-- dAtA[i] = 0x12 if m.CreationHeight != 0 { @@ -3421,12 +3582,12 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } - n13, err13 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingTime):]) - if err13 != nil { - return 0, err13 + n14, err14 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingTime):]) + if err14 != nil { + return 0, err14 } - i -= n13 - i = encodeVarintStaking(dAtA, i, uint64(n13)) + i -= n14 + i = encodeVarintStaking(dAtA, i, uint64(n14)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -3828,6 +3989,27 @@ func (m *Description) Size() (n int) { if l > 0 { n += 1 + l + sovStaking(uint64(l)) } + l = m.Metadata.Size() + n += 1 + l + sovStaking(uint64(l)) + return n +} + +func (m *Metadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProfilePicUri) + if l > 0 { + n += 1 + l + sovStaking(uint64(l)) + } + if len(m.SocialHandleUris) > 0 { + for _, s := range m.SocialHandleUris { + l = len(s) + n += 1 + l + sovStaking(uint64(l)) + } + } return n } @@ -4799,6 +4981,153 @@ func (m *Description) Unmarshal(dAtA []byte) error { } m.Details = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStaking + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthStaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipStaking(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthStaking + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Metadata) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Metadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProfilePicUri", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStaking + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthStaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProfilePicUri = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SocialHandleUris", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStaking + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthStaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SocialHandleUris = append(m.SocialHandleUris, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipStaking(dAtA[iNdEx:]) diff --git a/x/staking/types/validator.go b/x/staking/types/validator.go index c2e442d4c55a..6665c037b793 100644 --- a/x/staking/types/validator.go +++ b/x/staking/types/validator.go @@ -3,6 +3,7 @@ package types import ( "bytes" "fmt" + "net/url" "sort" "strings" "time" @@ -188,13 +189,14 @@ func (v Validator) IsUnbonding() bool { // constant used in flags to indicate that description field should not be updated const DoNotModifyDesc = "[do-not-modify]" -func NewDescription(moniker, identity, website, securityContact, details string) Description { +func NewDescription(moniker, identity, website, securityContact, details string, metadata Metadata) Description { return Description{ Moniker: moniker, Identity: identity, Website: website, SecurityContact: securityContact, Details: details, + Metadata: metadata, } } @@ -221,13 +223,18 @@ func (d Description) UpdateDescription(d2 Description) (Description, error) { d2.Details = d.Details } + if d2.Metadata.ProfilePicUri == DoNotModifyDesc { + d2.Metadata.ProfilePicUri = d.Metadata.ProfilePicUri + } + return NewDescription( d2.Moniker, d2.Identity, d2.Website, d2.SecurityContact, d2.Details, - ).EnsureLength() + d.Metadata, + ).Validate() } // EnsureLength ensures the length of a validator's description. @@ -255,6 +262,40 @@ func (d Description) EnsureLength() (Description, error) { return d, nil } +func (d Description) IsEmpty() bool { + return d.Moniker == "" && d.Details == "" && d.Identity == "" && d.Website == "" && d.SecurityContact == "" && + d.Metadata.ProfilePicUri == "" && len(d.Metadata.SocialHandleUris) == 0 +} + +// Validate calls metadata.Validate() description.EnsureLength() +func (d Description) Validate() (Description, error) { + if err := d.Metadata.Validate(); err != nil { + return d, err + } + + return d.EnsureLength() +} + +// Validate checks that the metadata fields are valid. For the ProfilePicUri, checks if a valid URI. +func (m Metadata) Validate() error { + if m.ProfilePicUri != "" { + _, err := url.ParseRequestURI(m.ProfilePicUri) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid profile_pic_uri format: %s, err: %s", m.ProfilePicUri, err) + } + } + + if m.SocialHandleUris != nil { + for _, socialHandleUri := range m.SocialHandleUris { + _, err := url.ParseRequestURI(socialHandleUri) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid social_handle_uri: %s, err: %s", socialHandleUri, err) + } + } + } + return nil +} + // ModuleValidatorUpdate returns a appmodule.ValidatorUpdate from a staking validator type // with the full validator power. // It replaces the previous ABCIValidatorUpdate function. diff --git a/x/tx/CHANGELOG.md b/x/tx/CHANGELOG.md index 9dac9e325c67..9fc07fac5acf 100644 --- a/x/tx/CHANGELOG.md +++ b/x/tx/CHANGELOG.md @@ -33,6 +33,9 @@ Since v0.13.0, x/tx follows Cosmos SDK semver: https://github.com/cosmos/cosmos- ## [Unreleased] +* [#21825](https://github.com/cosmos/cosmos-sdk/pull/21825) Fix decimal encoding and field ordering in Amino JSON encoder. +* [#21850](https://github.com/cosmos/cosmos-sdk/pull/21850) Support bytes field as signer. + ## [v0.13.5](https://github.com/cosmos/cosmos-sdk/releases/tag/x/tx/v0.13.5) - 2024-09-18 ### Improvements diff --git a/x/tx/go.mod b/x/tx/go.mod index 8f2bbf25e7dc..ed82d6892f5a 100644 --- a/x/tx/go.mod +++ b/x/tx/go.mod @@ -4,7 +4,7 @@ go 1.23 require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.3.0 github.com/cosmos/cosmos-proto v1.0.0-beta.5 @@ -29,8 +29,8 @@ require ( golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/grpc v1.67.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect + google.golang.org/grpc v1.67.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/x/tx/go.sum b/x/tx/go.sum index eda71a9bf9e6..d92c41b50631 100644 --- a/x/tx/go.sum +++ b/x/tx/go.sum @@ -1,7 +1,7 @@ cosmossdk.io/api v0.7.6 h1:PC20PcXy1xYKH2KU4RMurVoFjjKkCgYRbVAD4PdqUuY= cosmossdk.io/api v0.7.6/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= @@ -55,10 +55,10 @@ golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/x/tx/internal/testpb/signers.proto b/x/tx/internal/testpb/signers.proto index 63eb38cba43b..7244a3657400 100644 --- a/x/tx/internal/testpb/signers.proto +++ b/x/tx/internal/testpb/signers.proto @@ -92,7 +92,7 @@ message DeeplyNestedRepeatedSigner { message BadSigner { option (cosmos.msg.v1.signer) = "signer"; - bytes signer = 1; + int32 signer = 1; } message NoSignerOption { @@ -107,4 +107,4 @@ message ValidatorSigner { service TestSimpleSigner { option (cosmos.msg.v1.service) = true; rpc TestSimpleSigner(SimpleSigner) returns (SimpleSigner) {} -} \ No newline at end of file +} diff --git a/x/tx/internal/testpb/signers.pulsar.go b/x/tx/internal/testpb/signers.pulsar.go index f6e3a3d081c1..91de409223b3 100644 --- a/x/tx/internal/testpb/signers.pulsar.go +++ b/x/tx/internal/testpb/signers.pulsar.go @@ -7900,8 +7900,8 @@ func (x *fastReflection_BadSigner) Interface() protoreflect.ProtoMessage { // While iterating, mutating operations may only be performed // on the current field descriptor. func (x *fastReflection_BadSigner) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { - if len(x.Signer) != 0 { - value := protoreflect.ValueOfBytes(x.Signer) + if x.Signer != int32(0) { + value := protoreflect.ValueOfInt32(x.Signer) if !f(fd_BadSigner_signer, value) { return } @@ -7922,7 +7922,7 @@ func (x *fastReflection_BadSigner) Range(f func(protoreflect.FieldDescriptor, pr func (x *fastReflection_BadSigner) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { case "BadSigner.signer": - return len(x.Signer) != 0 + return x.Signer != int32(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: BadSigner")) @@ -7940,7 +7940,7 @@ func (x *fastReflection_BadSigner) Has(fd protoreflect.FieldDescriptor) bool { func (x *fastReflection_BadSigner) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { case "BadSigner.signer": - x.Signer = nil + x.Signer = int32(0) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: BadSigner")) @@ -7959,7 +7959,7 @@ func (x *fastReflection_BadSigner) Get(descriptor protoreflect.FieldDescriptor) switch descriptor.FullName() { case "BadSigner.signer": value := x.Signer - return protoreflect.ValueOfBytes(value) + return protoreflect.ValueOfInt32(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: BadSigner")) @@ -7981,7 +7981,7 @@ func (x *fastReflection_BadSigner) Get(descriptor protoreflect.FieldDescriptor) func (x *fastReflection_BadSigner) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { case "BadSigner.signer": - x.Signer = value.Bytes() + x.Signer = int32(value.Int()) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: BadSigner")) @@ -8018,7 +8018,7 @@ func (x *fastReflection_BadSigner) Mutable(fd protoreflect.FieldDescriptor) prot func (x *fastReflection_BadSigner) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { case "BadSigner.signer": - return protoreflect.ValueOfBytes(nil) + return protoreflect.ValueOfInt32(int32(0)) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: BadSigner")) @@ -8088,9 +8088,8 @@ func (x *fastReflection_BadSigner) ProtoMethods() *protoiface.Methods { var n int var l int _ = l - l = len(x.Signer) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) + if x.Signer != 0 { + n += 1 + runtime.Sov(uint64(x.Signer)) } if x.unknownFields != nil { n += len(x.unknownFields) @@ -8121,12 +8120,10 @@ func (x *fastReflection_BadSigner) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if len(x.Signer) > 0 { - i -= len(x.Signer) - copy(dAtA[i:], x.Signer) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Signer))) + if x.Signer != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Signer)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x8 } if input.Buf != nil { input.Buf = append(input.Buf, dAtA...) @@ -8178,10 +8175,10 @@ func (x *fastReflection_BadSigner) ProtoMethods() *protoiface.Methods { } switch fieldNum { case 1: - if wireType != 2 { + if wireType != 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } - var byteLen int + x.Signer = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow @@ -8191,26 +8188,11 @@ func (x *fastReflection_BadSigner) ProtoMethods() *protoiface.Methods { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + x.Signer |= int32(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Signer = append(x.Signer[:0], dAtA[iNdEx:postIndex]...) - if x.Signer == nil { - x.Signer = []byte{} - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -9386,7 +9368,7 @@ type BadSigner struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Signer []byte `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + Signer int32 `protobuf:"varint,1,opt,name=signer,proto3" json:"signer,omitempty"` } func (x *BadSigner) Reset() { @@ -9409,11 +9391,11 @@ func (*BadSigner) Descriptor() ([]byte, []int) { return file_signers_proto_rawDescGZIP(), []int{8} } -func (x *BadSigner) GetSigner() []byte { +func (x *BadSigner) GetSigner() int32 { if x != nil { return x.Signer } - return nil + return 0 } type NoSignerOption struct { @@ -9885,7 +9867,7 @@ var file_signers_proto_rawDesc = []byte{ 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x3a, 0x0a, 0x82, 0xe7, 0xb0, 0x2a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x22, 0x30, 0x0a, 0x09, 0x42, 0x61, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x69, 0x67, + 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x3a, 0x0b, 0x82, 0xe7, 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0x28, 0x0a, 0x0e, 0x4e, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, diff --git a/x/tx/signing/aminojson/encoder.go b/x/tx/signing/aminojson/encoder.go index 9fe589c0e544..d3e1e75c8bba 100644 --- a/x/tx/signing/aminojson/encoder.go +++ b/x/tx/signing/aminojson/encoder.go @@ -51,7 +51,12 @@ func cosmosDecEncoder(_ *Encoder, v protoreflect.Value, w io.Writer) error { if val == "" { return jsonMarshal(w, "0") } - return jsonMarshal(w, val) + var dec math.LegacyDec + err := dec.Unmarshal([]byte(val)) + if err != nil { + return err + } + return jsonMarshal(w, dec.String()) case []byte: if len(val) == 0 { return jsonMarshal(w, "0") @@ -125,27 +130,40 @@ func keyFieldEncoder(_ *Encoder, msg protoreflect.Message, w io.Writer) error { } type moduleAccountPretty struct { - Address string `json:"address"` - PubKey string `json:"public_key"` AccountNumber uint64 `json:"account_number"` - Sequence uint64 `json:"sequence"` + Address string `json:"address"` Name string `json:"name"` Permissions []string `json:"permissions"` + PubKey string `json:"public_key"` + Sequence uint64 `json:"sequence"` } // moduleAccountEncoder replicates the behavior in // https://github.com/cosmos/cosmos-sdk/blob/41a3dfeced2953beba3a7d11ec798d17ee19f506/x/auth/types/account.go#L230-L254 func moduleAccountEncoder(_ *Encoder, msg protoreflect.Message, w io.Writer) error { - ma := msg.Interface().(*authapi.ModuleAccount) + ma := &authapi.ModuleAccount{} + msgDesc := msg.Descriptor() + if msgDesc.FullName() != ma.ProtoReflect().Descriptor().FullName() { + return errors.New("moduleAccountEncoder: msg not a auth.ModuleAccount") + } + fields := msgDesc.Fields() + pretty := moduleAccountPretty{ - PubKey: "", - Name: ma.Name, - Permissions: ma.Permissions, - } - if ma.BaseAccount != nil { - pretty.Address = ma.BaseAccount.Address - pretty.AccountNumber = ma.BaseAccount.AccountNumber - pretty.Sequence = ma.BaseAccount.Sequence + PubKey: "", + Name: msg.Get(fields.ByName("name")).String(), + } + permissions := msg.Get(fields.ByName("permissions")).List() + for i := 0; i < permissions.Len(); i++ { + pretty.Permissions = append(pretty.Permissions, permissions.Get(i).String()) + } + + if msg.Has(fields.ByName("base_account")) { + baseAccount := msg.Get(fields.ByName("base_account")) + baMsg := baseAccount.Message() + bamdFields := baMsg.Descriptor().Fields() + pretty.Address = baMsg.Get(bamdFields.ByName("address")).String() + pretty.AccountNumber = baMsg.Get(bamdFields.ByName("account_number")).Uint() + pretty.Sequence = baMsg.Get(bamdFields.ByName("sequence")).Uint() } else { pretty.Address = "" pretty.AccountNumber = 0 @@ -166,29 +184,34 @@ func moduleAccountEncoder(_ *Encoder, msg protoreflect.Message, w io.Writer) err // also see: // https://github.com/cosmos/cosmos-sdk/blob/b49f948b36bc991db5be431607b475633aed697e/proto/cosmos/crypto/multisig/keys.proto#L15/ func thresholdStringEncoder(enc *Encoder, msg protoreflect.Message, w io.Writer) error { - pk, ok := msg.Interface().(*multisig.LegacyAminoPubKey) - if !ok { + pk := &multisig.LegacyAminoPubKey{} + msgDesc := msg.Descriptor() + fields := msgDesc.Fields() + if msgDesc.FullName() != pk.ProtoReflect().Descriptor().FullName() { return errors.New("thresholdStringEncoder: msg not a multisig.LegacyAminoPubKey") } - _, err := fmt.Fprintf(w, `{"threshold":"%d","pubkeys":`, pk.Threshold) - if err != nil { - return err - } - if len(pk.PublicKeys) == 0 { - _, err = io.WriteString(w, `[]}`) - return err - } - - fields := msg.Descriptor().Fields() pubkeysField := fields.ByName("public_keys") pubkeys := msg.Get(pubkeysField).List() - err = enc.marshalList(pubkeys, pubkeysField, w) + _, err := io.WriteString(w, `{"pubkeys":`) if err != nil { return err } - _, err = io.WriteString(w, `}`) + if pubkeys.Len() == 0 { + _, err := io.WriteString(w, `[]`) + if err != nil { + return err + } + } else { + err := enc.marshalList(pubkeys, pubkeysField, w) + if err != nil { + return err + } + } + + threshold := fields.ByName("threshold") + _, err = fmt.Fprintf(w, `,"threshold":"%d"}`, msg.Get(threshold).Uint()) return err } diff --git a/x/tx/signing/aminojson/internal/testpb/test.proto b/x/tx/signing/aminojson/internal/testpb/test.proto index 0bbb999426e6..421d1815d80e 100644 --- a/x/tx/signing/aminojson/internal/testpb/test.proto +++ b/x/tx/signing/aminojson/internal/testpb/test.proto @@ -32,19 +32,20 @@ message ABitOfEverything { repeated int32 repeated = 6; - string str = 7; - bool bool = 8; - bytes bytes = 9; - int32 i32 = 10; - fixed32 f32 = 11; - uint32 u32 = 12; - sint32 si32 = 13; - sfixed32 sf32 = 14; - int64 i64 = 15; - fixed64 f64 = 16; - uint64 u64 = 17; - sint64 si64 = 18; - sfixed64 sf64 = 19; + string str = 7; + bool bool = 8; + bytes bytes = 9; + int32 i32 = 10; + fixed32 f32 = 11; + uint32 u32 = 12; + sint32 si32 = 13; + sfixed32 sf32 = 14; + int64 i64 = 15; + fixed64 f64 = 16; + uint64 u64 = 17; + sint64 si64 = 18; + sfixed64 sf64 = 19; + bytes pretty_bytes = 20 [(amino.encoding) = "hex"]; // The following types are not tested here because they are treated fundamentally differently in // gogoproto. They are tested fully in /tests/integration/aminojson/aminojson_test.go diff --git a/x/tx/signing/aminojson/internal/testpb/test.pulsar.go b/x/tx/signing/aminojson/internal/testpb/test.pulsar.go index 0adf0b573d60..869176b6bb0e 100644 --- a/x/tx/signing/aminojson/internal/testpb/test.pulsar.go +++ b/x/tx/signing/aminojson/internal/testpb/test.pulsar.go @@ -1755,23 +1755,24 @@ func (x *_ABitOfEverything_6_list) IsValid() bool { } var ( - md_ABitOfEverything protoreflect.MessageDescriptor - fd_ABitOfEverything_message protoreflect.FieldDescriptor - fd_ABitOfEverything_enum protoreflect.FieldDescriptor - fd_ABitOfEverything_repeated protoreflect.FieldDescriptor - fd_ABitOfEverything_str protoreflect.FieldDescriptor - fd_ABitOfEverything_bool protoreflect.FieldDescriptor - fd_ABitOfEverything_bytes protoreflect.FieldDescriptor - fd_ABitOfEverything_i32 protoreflect.FieldDescriptor - fd_ABitOfEverything_f32 protoreflect.FieldDescriptor - fd_ABitOfEverything_u32 protoreflect.FieldDescriptor - fd_ABitOfEverything_si32 protoreflect.FieldDescriptor - fd_ABitOfEverything_sf32 protoreflect.FieldDescriptor - fd_ABitOfEverything_i64 protoreflect.FieldDescriptor - fd_ABitOfEverything_f64 protoreflect.FieldDescriptor - fd_ABitOfEverything_u64 protoreflect.FieldDescriptor - fd_ABitOfEverything_si64 protoreflect.FieldDescriptor - fd_ABitOfEverything_sf64 protoreflect.FieldDescriptor + md_ABitOfEverything protoreflect.MessageDescriptor + fd_ABitOfEverything_message protoreflect.FieldDescriptor + fd_ABitOfEverything_enum protoreflect.FieldDescriptor + fd_ABitOfEverything_repeated protoreflect.FieldDescriptor + fd_ABitOfEverything_str protoreflect.FieldDescriptor + fd_ABitOfEverything_bool protoreflect.FieldDescriptor + fd_ABitOfEverything_bytes protoreflect.FieldDescriptor + fd_ABitOfEverything_i32 protoreflect.FieldDescriptor + fd_ABitOfEverything_f32 protoreflect.FieldDescriptor + fd_ABitOfEverything_u32 protoreflect.FieldDescriptor + fd_ABitOfEverything_si32 protoreflect.FieldDescriptor + fd_ABitOfEverything_sf32 protoreflect.FieldDescriptor + fd_ABitOfEverything_i64 protoreflect.FieldDescriptor + fd_ABitOfEverything_f64 protoreflect.FieldDescriptor + fd_ABitOfEverything_u64 protoreflect.FieldDescriptor + fd_ABitOfEverything_si64 protoreflect.FieldDescriptor + fd_ABitOfEverything_sf64 protoreflect.FieldDescriptor + fd_ABitOfEverything_pretty_bytes protoreflect.FieldDescriptor ) func init() { @@ -1793,6 +1794,7 @@ func init() { fd_ABitOfEverything_u64 = md_ABitOfEverything.Fields().ByName("u64") fd_ABitOfEverything_si64 = md_ABitOfEverything.Fields().ByName("si64") fd_ABitOfEverything_sf64 = md_ABitOfEverything.Fields().ByName("sf64") + fd_ABitOfEverything_pretty_bytes = md_ABitOfEverything.Fields().ByName("pretty_bytes") } var _ protoreflect.Message = (*fastReflection_ABitOfEverything)(nil) @@ -1956,6 +1958,12 @@ func (x *fastReflection_ABitOfEverything) Range(f func(protoreflect.FieldDescrip return } } + if len(x.PrettyBytes) != 0 { + value := protoreflect.ValueOfBytes(x.PrettyBytes) + if !f(fd_ABitOfEverything_pretty_bytes, value) { + return + } + } } // Has reports whether a field is populated. @@ -2003,6 +2011,8 @@ func (x *fastReflection_ABitOfEverything) Has(fd protoreflect.FieldDescriptor) b return x.Si64 != int64(0) case "testpb.ABitOfEverything.sf64": return x.Sf64 != int64(0) + case "testpb.ABitOfEverything.pretty_bytes": + return len(x.PrettyBytes) != 0 default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.ABitOfEverything")) @@ -2051,6 +2061,8 @@ func (x *fastReflection_ABitOfEverything) Clear(fd protoreflect.FieldDescriptor) x.Si64 = int64(0) case "testpb.ABitOfEverything.sf64": x.Sf64 = int64(0) + case "testpb.ABitOfEverything.pretty_bytes": + x.PrettyBytes = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.ABitOfEverything")) @@ -2118,6 +2130,9 @@ func (x *fastReflection_ABitOfEverything) Get(descriptor protoreflect.FieldDescr case "testpb.ABitOfEverything.sf64": value := x.Sf64 return protoreflect.ValueOfInt64(value) + case "testpb.ABitOfEverything.pretty_bytes": + value := x.PrettyBytes + return protoreflect.ValueOfBytes(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.ABitOfEverything")) @@ -2172,6 +2187,8 @@ func (x *fastReflection_ABitOfEverything) Set(fd protoreflect.FieldDescriptor, v x.Si64 = value.Int() case "testpb.ABitOfEverything.sf64": x.Sf64 = value.Int() + case "testpb.ABitOfEverything.pretty_bytes": + x.PrettyBytes = value.Bytes() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.ABitOfEverything")) @@ -2231,6 +2248,8 @@ func (x *fastReflection_ABitOfEverything) Mutable(fd protoreflect.FieldDescripto panic(fmt.Errorf("field si64 of message testpb.ABitOfEverything is not mutable")) case "testpb.ABitOfEverything.sf64": panic(fmt.Errorf("field sf64 of message testpb.ABitOfEverything is not mutable")) + case "testpb.ABitOfEverything.pretty_bytes": + panic(fmt.Errorf("field pretty_bytes of message testpb.ABitOfEverything is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.ABitOfEverything")) @@ -2278,6 +2297,8 @@ func (x *fastReflection_ABitOfEverything) NewField(fd protoreflect.FieldDescript return protoreflect.ValueOfInt64(int64(0)) case "testpb.ABitOfEverything.sf64": return protoreflect.ValueOfInt64(int64(0)) + case "testpb.ABitOfEverything.pretty_bytes": + return protoreflect.ValueOfBytes(nil) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: testpb.ABitOfEverything")) @@ -2402,6 +2423,10 @@ func (x *fastReflection_ABitOfEverything) ProtoMethods() *protoiface.Methods { if x.Sf64 != 0 { n += 10 } + l = len(x.PrettyBytes) + if l > 0 { + n += 2 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -2431,6 +2456,15 @@ func (x *fastReflection_ABitOfEverything) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.PrettyBytes) > 0 { + i -= len(x.PrettyBytes) + copy(dAtA[i:], x.PrettyBytes) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PrettyBytes))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa2 + } if x.Sf64 != 0 { i -= 8 binary.LittleEndian.PutUint64(dAtA[i:], uint64(x.Sf64)) @@ -2981,6 +3015,40 @@ func (x *fastReflection_ABitOfEverything) ProtoMethods() *protoiface.Methods { } x.Sf64 = int64(binary.LittleEndian.Uint64(dAtA[iNdEx:])) iNdEx += 8 + case 20: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PrettyBytes", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.PrettyBytes = append(x.PrettyBytes[:0], dAtA[iNdEx:postIndex]...) + if x.PrettyBytes == nil { + x.PrettyBytes = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -4178,22 +4246,23 @@ type ABitOfEverything struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Message *NestedMessage `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - Enum AnEnum `protobuf:"varint,2,opt,name=enum,proto3,enum=testpb.AnEnum" json:"enum,omitempty"` - Repeated []int32 `protobuf:"varint,6,rep,packed,name=repeated,proto3" json:"repeated,omitempty"` - Str string `protobuf:"bytes,7,opt,name=str,proto3" json:"str,omitempty"` - Bool bool `protobuf:"varint,8,opt,name=bool,proto3" json:"bool,omitempty"` - Bytes []byte `protobuf:"bytes,9,opt,name=bytes,proto3" json:"bytes,omitempty"` - I32 int32 `protobuf:"varint,10,opt,name=i32,proto3" json:"i32,omitempty"` - F32 uint32 `protobuf:"fixed32,11,opt,name=f32,proto3" json:"f32,omitempty"` - U32 uint32 `protobuf:"varint,12,opt,name=u32,proto3" json:"u32,omitempty"` - Si32 int32 `protobuf:"zigzag32,13,opt,name=si32,proto3" json:"si32,omitempty"` - Sf32 int32 `protobuf:"fixed32,14,opt,name=sf32,proto3" json:"sf32,omitempty"` - I64 int64 `protobuf:"varint,15,opt,name=i64,proto3" json:"i64,omitempty"` - F64 uint64 `protobuf:"fixed64,16,opt,name=f64,proto3" json:"f64,omitempty"` - U64 uint64 `protobuf:"varint,17,opt,name=u64,proto3" json:"u64,omitempty"` - Si64 int64 `protobuf:"zigzag64,18,opt,name=si64,proto3" json:"si64,omitempty"` - Sf64 int64 `protobuf:"fixed64,19,opt,name=sf64,proto3" json:"sf64,omitempty"` + Message *NestedMessage `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Enum AnEnum `protobuf:"varint,2,opt,name=enum,proto3,enum=testpb.AnEnum" json:"enum,omitempty"` + Repeated []int32 `protobuf:"varint,6,rep,packed,name=repeated,proto3" json:"repeated,omitempty"` + Str string `protobuf:"bytes,7,opt,name=str,proto3" json:"str,omitempty"` + Bool bool `protobuf:"varint,8,opt,name=bool,proto3" json:"bool,omitempty"` + Bytes []byte `protobuf:"bytes,9,opt,name=bytes,proto3" json:"bytes,omitempty"` + I32 int32 `protobuf:"varint,10,opt,name=i32,proto3" json:"i32,omitempty"` + F32 uint32 `protobuf:"fixed32,11,opt,name=f32,proto3" json:"f32,omitempty"` + U32 uint32 `protobuf:"varint,12,opt,name=u32,proto3" json:"u32,omitempty"` + Si32 int32 `protobuf:"zigzag32,13,opt,name=si32,proto3" json:"si32,omitempty"` + Sf32 int32 `protobuf:"fixed32,14,opt,name=sf32,proto3" json:"sf32,omitempty"` + I64 int64 `protobuf:"varint,15,opt,name=i64,proto3" json:"i64,omitempty"` + F64 uint64 `protobuf:"fixed64,16,opt,name=f64,proto3" json:"f64,omitempty"` + U64 uint64 `protobuf:"varint,17,opt,name=u64,proto3" json:"u64,omitempty"` + Si64 int64 `protobuf:"zigzag64,18,opt,name=si64,proto3" json:"si64,omitempty"` + Sf64 int64 `protobuf:"fixed64,19,opt,name=sf64,proto3" json:"sf64,omitempty"` + PrettyBytes []byte `protobuf:"bytes,20,opt,name=pretty_bytes,json=prettyBytes,proto3" json:"pretty_bytes,omitempty"` } func (x *ABitOfEverything) Reset() { @@ -4328,6 +4397,13 @@ func (x *ABitOfEverything) GetSf64() int64 { return 0 } +func (x *ABitOfEverything) GetPrettyBytes() []byte { + if x != nil { + return x.PrettyBytes + } + return nil +} + type Duration struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4450,7 +4526,7 @@ var file_testpb_test_proto_rawDesc = []byte{ 0x09, 0x57, 0x69, 0x74, 0x68, 0x41, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x10, 0x9a, 0xe7, 0xb0, 0x2a, 0x0b, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x52, 0x06, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x31, 0x22, 0x92, 0x03, 0x0a, 0x10, 0x41, 0x42, 0x69, 0x74, 0x4f, 0x66, 0x45, + 0x65, 0x6c, 0x64, 0x31, 0x22, 0xbf, 0x03, 0x0a, 0x10, 0x41, 0x42, 0x69, 0x74, 0x4f, 0x66, 0x45, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, @@ -4474,32 +4550,35 @@ var file_testpb_test_proto_rawDesc = []byte{ 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x75, 0x36, 0x34, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x36, 0x34, 0x18, 0x12, 0x20, 0x01, 0x28, 0x12, 0x52, 0x04, 0x73, 0x69, 0x36, 0x34, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x66, 0x36, 0x34, 0x18, 0x13, 0x20, 0x01, 0x28, 0x10, 0x52, 0x04, 0x73, 0x66, - 0x36, 0x34, 0x3a, 0x15, 0x8a, 0xe7, 0xb0, 0x2a, 0x10, 0x41, 0x42, 0x69, 0x74, 0x4f, 0x66, 0x45, - 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x22, 0x7b, 0x0a, 0x08, 0x44, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x47, 0x0a, 0x0d, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x6f, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x62, 0x61, 0x72, 0x3a, 0x12, 0x8a, 0xe7, 0xb0, - 0x2a, 0x0d, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, - 0x29, 0x0a, 0x06, 0x41, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x44, - 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x4e, 0x45, 0x10, - 0x01, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x57, 0x4f, 0x10, 0x02, 0x42, 0x83, 0x01, 0x0a, 0x0a, 0x63, - 0x6f, 0x6d, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x42, 0x09, 0x54, 0x65, 0x73, 0x74, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x32, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, - 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x78, 0x2f, 0x74, 0x78, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x6a, - 0x73, 0x6f, 0x6e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, - 0x74, 0x70, 0x62, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x54, 0x58, 0x58, - 0xaa, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xca, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, - 0x70, 0x62, 0xe2, 0x02, 0x12, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x36, 0x34, 0x12, 0x2b, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0x9a, 0xe7, 0xb0, 0x2a, 0x03, 0x68, + 0x65, 0x78, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x3a, + 0x15, 0x8a, 0xe7, 0xb0, 0x2a, 0x10, 0x41, 0x42, 0x69, 0x74, 0x4f, 0x66, 0x45, 0x76, 0x65, 0x72, + 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x22, 0x7b, 0x0a, 0x08, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x22, 0x47, 0x0a, 0x0d, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x66, 0x6f, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x03, 0x62, 0x61, 0x72, 0x3a, 0x12, 0x8a, 0xe7, 0xb0, 0x2a, 0x0d, 0x4e, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, 0x29, 0x0a, 0x06, + 0x41, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, + 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x07, + 0x0a, 0x03, 0x54, 0x57, 0x4f, 0x10, 0x02, 0x42, 0x83, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x42, 0x09, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x32, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, + 0x6f, 0x2f, 0x78, 0x2f, 0x74, 0x78, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x6a, 0x73, 0x6f, 0x6e, + 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, + 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0xa2, 0x02, 0x03, 0x54, 0x58, 0x58, 0xaa, 0x02, 0x06, + 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xca, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0xe2, + 0x02, 0x12, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x54, 0x65, 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/x/tx/signing/aminojson/json_marshal_test.go b/x/tx/signing/aminojson/json_marshal_test.go index 29d2f8cf8f59..b2a4ddd77e42 100644 --- a/x/tx/signing/aminojson/json_marshal_test.go +++ b/x/tx/signing/aminojson/json_marshal_test.go @@ -1,6 +1,7 @@ package aminojson_test import ( + "crypto/sha256" "encoding/json" "errors" "fmt" @@ -414,3 +415,33 @@ func TestAminoNameAsTypeURL(t *testing.T) { } }`, string(bz)) } + +func TestCustomBytesEncoder(t *testing.T) { + cdc := amino.NewCodec() + cdc.RegisterConcrete(&testpb.ABitOfEverything{}, "ABitOfEverything", nil) + encoder := aminojson.NewEncoder(aminojson.EncoderOptions{}) + + bz := sha256.Sum256([]byte("test")) + + msg := &testpb.ABitOfEverything{ + Bytes: bz[:], + PrettyBytes: bz[:], + } + + legacyJSON, err := cdc.MarshalJSON(msg) + require.NoError(t, err) + aminoJSON, err := encoder.Marshal(msg) + require.NoError(t, err) + require.Equal(t, string(legacyJSON), string(aminoJSON)) + + encoder.DefineFieldEncoding( + "hex", + func(enc *aminojson.Encoder, v protoreflect.Value, w io.Writer) error { + _, err := fmt.Fprintf(w, "\"%x\"", v.Bytes()) + return err + }) + aminoJSON, err = encoder.Marshal(msg) + require.NoError(t, err) + require.NotEqual(t, string(legacyJSON), string(aminoJSON)) + t.Logf("hex encoded bytes: %s", string(aminoJSON)) +} diff --git a/x/tx/signing/context.go b/x/tx/signing/context.go index f44be0118cca..d02be6d12523 100644 --- a/x/tx/signing/context.go +++ b/x/tx/signing/context.go @@ -301,6 +301,11 @@ func (c *Context) makeGetSignersFunc(descriptor protoreflect.MessageDescriptor) } return arr, nil } + case protoreflect.BytesKind: + fieldGetters[i] = func(msg proto.Message, arr [][]byte) ([][]byte, error) { + addrBz := msg.ProtoReflect().Get(field).Bytes() + return append(arr, addrBz), nil + } default: return nil, fmt.Errorf("unexpected field type %s for field %s in message %s", field.Kind(), fieldName, descriptor.FullName()) } diff --git a/x/upgrade/client/cli/tx.go b/x/upgrade/client/cli/tx.go index c817fcba9020..7f95184f3751 100644 --- a/x/upgrade/client/cli/tx.go +++ b/x/upgrade/client/cli/tx.go @@ -50,7 +50,7 @@ func NewCmdSubmitUpgradeProposal() *cobra.Command { Short: "Submit a software upgrade proposal", Long: "Submit a software upgrade along with an initial deposit.\n" + "Please specify a unique name and height for the upgrade to take effect.\n" + - "You may include info to reference a binary download link, in a format compatible with: https://docs.cosmos.network/main/tooling/cosmovisor", + "You may include info to reference a binary download link, in a format compatible with: https://docs.cosmos.network/main/build/tooling/cosmovisor", RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientTxContext(cmd) if err != nil { diff --git a/x/upgrade/go.mod b/x/upgrade/go.mod index 166a0b5be293..6505f6b4b02a 100644 --- a/x/upgrade/go.mod +++ b/x/upgrade/go.mod @@ -4,7 +4,7 @@ go 1.23.1 require ( cosmossdk.io/api v0.7.6 - cosmossdk.io/core v1.0.0-alpha.3 + cosmossdk.io/core v1.0.0-alpha.4 cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 cosmossdk.io/depinject v1.0.0 cosmossdk.io/errors v1.0.1 @@ -27,7 +27,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.67.0 + google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.34.2 ) @@ -42,7 +42,7 @@ require ( cloud.google.com/go/storage v1.43.0 // indirect cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/math v1.3.0 // indirect - cosmossdk.io/schema v0.3.0 // indirect + cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 // indirect cosmossdk.io/x/bank v0.0.0-20240226161501-23359a0b6d91 // indirect cosmossdk.io/x/staking v0.0.0-00010101000000-000000000000 // indirect cosmossdk.io/x/tx v0.13.3 // indirect @@ -147,7 +147,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.4 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.59.1 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect @@ -181,7 +181,7 @@ require ( golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect @@ -190,7 +190,7 @@ require ( golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/api v0.192.0 // indirect google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect diff --git a/x/upgrade/go.sum b/x/upgrade/go.sum index 93311a69c2a9..257f52f8aca0 100644 --- a/x/upgrade/go.sum +++ b/x/upgrade/go.sum @@ -194,8 +194,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA= -cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= +cosmossdk.io/core v1.0.0-alpha.4 h1:9iuroT9ejDYETCsGkzkvs/wAY/5UFl7nCIINFRxyMJY= +cosmossdk.io/core v1.0.0-alpha.4/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29 h1:NxxUo0GMJUbIuVg0R70e3cbn9eFTEuMr7ev1AFvypdY= cosmossdk.io/core/testing v0.0.0-20240923163230-04da382a9f29/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs= cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= @@ -206,8 +206,8 @@ cosmossdk.io/log v1.4.1 h1:wKdjfDRbDyZRuWa8M+9nuvpVYxrEOwbD/CA8hvhU8QM= cosmossdk.io/log v1.4.1/go.mod h1:k08v0Pyq+gCP6phvdI6RCGhLf/r425UT6Rk/m+o74rU= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c= -cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9 h1:DmOoS/1PeY6Ih0hAVlJ69kLMUrLV+TCbfICrZtB1vdU= +cosmossdk.io/schema v0.3.1-0.20240930054013-7c6e0388a3f9/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ= cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190 h1:XQJj9Dv9Gtze0l2TF79BU5lkP6MkUveTUuKICmxoz+o= cosmossdk.io/x/protocolpool v0.0.0-20230925135524-a1bc045b3190/go.mod h1:7WUGupOvmlHJoIMBz1JbObQxeo6/TDiuDBxmtod8HRg= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -722,8 +722,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0= -github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= @@ -972,8 +972,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1327,8 +1327,8 @@ google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142 h1:oLiyxGgE+rt22du google.golang.org/genproto v0.0.0-20240814211410-ddb44dafa142/go.mod h1:G11eXq53iI5Q+kyNOmCvnzBaxEA2Q/Ik5Tj7nqBE8j4= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1364,8 +1364,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw= -google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/x/upgrade/keeper/abci.go b/x/upgrade/keeper/abci.go index afaad8cf849b..efb06bf3ccbc 100644 --- a/x/upgrade/keeper/abci.go +++ b/x/upgrade/keeper/abci.go @@ -19,7 +19,8 @@ import ( // a migration to be executed if needed upon this switch (migration defined in the new binary) // skipUpgradeHeightArray is a set of block heights for which the upgrade must be skipped func (k Keeper) PreBlocker(ctx context.Context) error { - defer telemetry.ModuleMeasureSince(types.ModuleName, telemetry.Now(), telemetry.MetricKeyBeginBlocker) + start := telemetry.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyBeginBlocker) blockHeight := k.HeaderService.HeaderInfo(ctx).Height plan, err := k.GetUpgradePlan(ctx)