Skip to content

Commit

Permalink
Merge branch 'release/v0.52.x' into chore/remove-integ-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
aljo242 committed Jan 17, 2025
2 parents 7511103 + f42fc60 commit ce209a7
Show file tree
Hide file tree
Showing 30 changed files with 654 additions and 198 deletions.
15 changes: 10 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,28 @@ Ref: https://keepachangelog.com/en/1.0.0/

Every module contains its own CHANGELOG.md. Please refer to the module you are interested in.

## [v0.52.0-rc.2](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.52.0-rc.2) - 2025-01-17

Every module contains its own CHANGELOG.md. Please refer to the module you are interested in.

### Features

* (sims) [#23013](https://github.com/cosmos/cosmos-sdk/pull/23013) Integration with app v2
* (x/auth/ante) [#23128](https://github.com/cosmos/cosmos-sdk/pull/23128) Allow custom verifyIsOnCurve when validate tx for public key like ethsecp256k1.
* (server) [#23128](https://github.com/cosmos/cosmos-sdk/pull/23128) Add custom rollback command option. In order to use it, you need to implement the Rollback interface and remove the default rollback command with `cmd.RemoveCommand(cmd.RollbackCmd)` and then add it back with `cmd.AddCommand(cmd.NewCustomRollbackCmd(appCreator, rollbackable))`.
* (server) [#23321](https://github.com/cosmos/cosmos-sdk/pull/23321) Add custom rollback command option. In order to use it, you need to implement the Rollback interface and remove the default rollback command with `cmd.RemoveCommand(cmd.RollbackCmd)` and then add it back with `cmd.AddCommand(cmd.NewCustomRollbackCmd(appCreator, rollbackable))`.

### Improvements

* (codec) [#22988](https://github.com/cosmos/cosmos-sdk/pull/22988) Improve edge case handling for recursion limits.

### Bug Fixes

* (query) [23002](https://github.com/cosmos/cosmos-sdk/pull/23002) Fix collection filtered pagination.
* (x/auth/tx) [#23170](https://github.com/cosmos/cosmos-sdk/pull/23170) Avoid panic from newWrapperFromDecodedTx when AuthInfo.Fee is optional in decodedTx.
* (x/auth/tx) [23144](https://github.com/cosmos/cosmos-sdk/pull/23144) Add missing CacheWithValue for ExtensionOptions.
* (x/auth/tx) [#23148](https://github.com/cosmos/cosmos-sdk/pull/23148) Avoid panic from intoAnyV2 when v1.PublicKey is optional.
* (query) [#23002](https://github.com/cosmos/cosmos-sdk/pull/23002) Fix collection filtered pagination.
* (x/auth/tx) [#23170](https://github.com/cosmos/cosmos-sdk/pull/23170) Avoid panic from `newWrapperFromDecodedTx` when `AuthInfo.Fee` is optional in decodedTx.
* (x/auth/tx) [#23144](https://github.com/cosmos/cosmos-sdk/pull/23144) Add missing `CacheWithValue` for `ExtensionOptions`.
* (x/auth/tx) [#23148](https://github.com/cosmos/cosmos-sdk/pull/23148) Avoid panic from `intoAnyV2` when v1.PublicKey is optional.
* (server) [#23244](https://github.com/cosmos/cosmos-sdk/pull/23244) Allow align block header with skip check header in grpc server.
* (x/auth) [#23357](https://github.com/cosmos/cosmos-sdk/pull/23357) Fixes accessibility of the AddressStringToBytes HTTP binding and adds another binding to AddressBytesToString.

### Deprecated

Expand Down
19 changes: 14 additions & 5 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
# Cosmos SDK v0.52.0-rc.1 Release Notes
# Cosmos SDK v0.52.0-rc.2 Release Notes

We've just released a release candidate for the Cosmos SDK v0.52.0.
APIs should now be stable, and we encourage everyone to start integrating with this release candidate.
This second release canditate include bug fixes found during integration.
Additionally, it bumps the SDK dependencies to their final release:

This release is the first totally modular release of the Cosmos SDK. Many components have been extracted in their own modules. Refer to the [version matrix](https://github.com/cosmos/cosmos-sdk?tab=readme-ov-file#version-matrix) to understand what it means.
* cosmossdk.io/core v1.0.0
* cosmossdk.io/collection v1.0.0
* cosmossdk.io/schema v1.0.0
* cosmossdk.io/x/tx v1.0.0

Modules remained stable and nothing has changed since their first release candidate.
We encourage chains to already start integrating with this release candidate as APIs are stable.

Cosmos SDK Olympus is the first totally modular (as in package) release of the Cosmos SDK. Many components have been extracted in their own modules. Refer to the [version matrix](https://github.com/cosmos/cosmos-sdk?tab=readme-ov-file#version-matrix) to understand what it means.

A final release is expected in the coming **days**.

Please see the [CHANGELOG](https://github.com/cosmos/cosmos-sdk/blob/release/v0.52.x/CHANGELOG.md) for an exhaustive list of changes.
Refer to the [UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/release/v0.52.x/UPGRADING.md) for upgrading your application.

Full Commit History: https://github.com/cosmos/cosmos-sdk/compare/release/v0.50.x...release/v0.52.x
Full Commit History: https://github.com/cosmos/cosmos-sdk/compare/v0.52.0-rc.1...v0.52.0-rc.
`v0.50..v0.52`: https://github.com/cosmos/cosmos-sdk/compare/release/v0.50.x...release/v0.52.x
2 changes: 1 addition & 1 deletion client/v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ It is possible to use `AutoCLI` for non module commands. The trick is still to i
For example, here is how the SDK does it for `cometbft` gRPC commands:

```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/client/grpc/cmtservice/autocli.go#L52-L71
https://github.com/cosmos/cosmos-sdk/blob/release/v0.52.x/client/grpc/cmtservice/autocli.go#L52-L71
```

#### Conventions for the `Use` field in Cobra
Expand Down
5 changes: 5 additions & 0 deletions crypto/keys/multisig/multisig.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ func (m *LegacyAminoPubKey) VerifyMultisignature(getSignBytes multisigtypes.GetS
sigs := sig.Signatures
size := bitarray.Count()
pubKeys := m.GetPubKeys()

// N-M rule verification
if int(m.Threshold) <= 0 {
return fmt.Errorf("invalid threshold: must be > 0, got %d", m.Threshold)
}
// ensure bit array is the correct size
if len(pubKeys) != size {
return fmt.Errorf("bit array size is incorrect, expecting: %d", len(pubKeys))
Expand Down
116 changes: 112 additions & 4 deletions crypto/keys/multisig/multisig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ func TestAddSignatureFromPubKeyNilCheck(t *testing.T) {

func TestMultiSigMigration(t *testing.T) {
msg := []byte{1, 2, 3, 4}
pkSet, sigs := generatePubKeysAndSignatures(2, msg)
multisignature := multisig.NewMultisig(2)
pkSet, sigs := generatePubKeysAndSignatures(3, msg)
multisignature := multisig.NewMultisig(3)

multisigKey := kmultisig.NewLegacyAminoPubKey(2, pkSet)
signBytesFn := func(mode signing.SignMode) ([]byte, error) { return msg, nil }
Expand Down Expand Up @@ -318,6 +318,22 @@ func generatePubKeysAndSignatures(n int, msg []byte) (pubKeys []cryptotypes.PubK
return
}

// generateNestedMultiSignature creates a nested multisig structure for testing purposes.
// It generates a top-level multisig with 'n' sub-multisigs, where each sub-multisig contains
// 5 individual signatures.
//
// Parameters:
// - n: number of nested multisigs to generate (determines the size of the top-level multisig)
// - msg: the message to be signed
//
// Returns:
// - multisig.PubKey: the top-level multisig public key containing n sub-multisig public keys
// - *signing.MultiSignatureData: the corresponding signature data structure containing n sub-multisig signatures
//
// Each sub-multisig is configured with:
// - threshold of 5 (requires all 4 signatures)
// - 5 individual secp256k1 public keys and their corresponding signatures
// All signature bits are set to true to simulate a fully signed multisig.
func generateNestedMultiSignature(n int, msg []byte) (multisig.PubKey, *signing.MultiSignatureData) {
pubKeys := make([]cryptotypes.PubKey, n)
signatures := make([]signing.SignatureData, n)
Expand All @@ -333,10 +349,10 @@ func generateNestedMultiSignature(n int, msg []byte) (multisig.PubKey, *signing.
Signatures: nestedSigs,
}
signatures[i] = nestedSig
pubKeys[i] = kmultisig.NewLegacyAminoPubKey(5, nestedPks)
pubKeys[i] = kmultisig.NewLegacyAminoPubKey(4, nestedPks)
bitArray.SetIndex(i, true)
}
return kmultisig.NewLegacyAminoPubKey(n, pubKeys), &signing.MultiSignatureData{
return kmultisig.NewLegacyAminoPubKey(n-1, pubKeys), &signing.MultiSignatureData{
BitArray: bitArray,
Signatures: signatures,
}
Expand Down Expand Up @@ -453,3 +469,95 @@ func TestAminoUnmarshalJSON(t *testing.T) {
require.NoError(t, err)
}
}

func TestVerifyMultisignatureNMRule(t *testing.T) {
makeTestKeysAndSignatures := func(n int, msg []byte) ([]cryptotypes.PubKey, []signing.SignatureData) {
pubKeys := make([]cryptotypes.PubKey, n)
sigs := make([]signing.SignatureData, n)

for i := 0; i < n; i++ {
// Generate private key and get its public key
privKey := secp256k1.GenPrivKey()
pubKeys[i] = privKey.PubKey()

// Create real signature
sig, err := privKey.Sign(msg)
require.NoError(t, err)
sigs[i] = &signing.SingleSignatureData{
Signature: sig,
}
}
return pubKeys, sigs
}

tests := []struct {
name string
n int // number of keys
m uint32 // threshold
expectErr string
}{
{
name: "valid case: N=3 M=2",
n: 3,
m: 2,
expectErr: "",
},
{
name: "invalid: M=0",
n: 3,
m: 0,
expectErr: "invalid threshold: must be > 0, got 0",
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
msg := []byte("test message")
pubKeys, sigs := makeTestKeysAndSignatures(tc.n, msg)

// Create the key directly instead of using NewLegacyAminoPubKey
pubKeysAny := make([]*types.Any, len(pubKeys))
for i, key := range pubKeys {
anyKey, err := types.NewAnyWithValue(key)
require.NoError(t, err)
pubKeysAny[i] = anyKey
}

multisigKey := &kmultisig.LegacyAminoPubKey{
Threshold: tc.m,
PubKeys: pubKeysAny,
}

// Create a dummy signature with a proper bit array
bitArray := cryptotypes.NewCompactBitArray(tc.n)
// Set the first M bits to simulate M signatures
for i := 0; i < int(tc.m) && i < tc.n; i++ {
bitArray.SetIndex(i, true)
}

multiSig := &signing.MultiSignatureData{
BitArray: bitArray,
Signatures: make([]signing.SignatureData, 0, tc.m),
}

// Fill in dummy signatures
for i := 0; i < int(tc.m) && i < tc.n; i++ {
multiSig.Signatures = append(multiSig.Signatures, sigs[i])
}

// Create getSignBytes function that returns our test message
getSignBytes := func(mode signing.SignMode) ([]byte, error) {
return msg, nil
}

err := multisigKey.VerifyMultisignature(getSignBytes, multiSig)

if tc.expectErr == "" {
require.NoError(t, err)
} else {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expectErr)
}
})
}
}
2 changes: 1 addition & 1 deletion docs/build/building-apps/upgrades/0.52.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ plugins:

### Refactor Module Imports to cosmossdk.io/x/

All modules except auth have been split into their own go.mod and are imported via cosmossdk.io/x/<mod>.
All modules except auth have been split into their own go.mod and are imported via `cosmossdk.io/x/<mod>`.


* Replace import paths from github.com/cosmos/cosmos-sdk/x/{moduleName} to cosmossdk.io/x/{moduleName}.
Expand Down
4 changes: 2 additions & 2 deletions docs/build/building-modules/02-messages-and-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ https://github.com/cosmos/cosmos-sdk/blob/28fa3b8/x/bank/proto/cosmos/bank/v1bet

### `transaction.Msg` Interface

`transaction.Msg` is an alias of `proto.Message`.
`transaction.Msg` uses structural types to define the interface for a message.

```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/core/transaction/transaction.go#L8
https://github.com/cosmos/cosmos-sdk/blob/main/core/transaction/transaction.go#L4-L9
```

Signers from the `GetSigners()` call is automated via a protobuf annotation.
Expand Down
30 changes: 17 additions & 13 deletions proto/cosmos/auth/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,25 @@ service Query {
// AddressBytesToString converts Account Address bytes to string
rpc AddressBytesToString(AddressBytesToStringRequest) returns (AddressBytesToStringResponse) {
option (cosmos_proto.method_added_in) = "cosmos-sdk 0.46";
option (google.api.http).get = "/cosmos/auth/v1beta1/bech32/{address_bytes}";
}
option (google.api.http) = {
get: "/cosmos/auth/v1beta1/bech32/{address_bytes}";
additional_bindings:
[{get: "/cosmos/auth/v1beta1/bech32/decode/{address_bytes}"}]
};
}

// AddressStringToBytes converts Address string to bytes
rpc AddressStringToBytes(AddressStringToBytesRequest) returns (AddressStringToBytesResponse) {
option (cosmos_proto.method_added_in) = "cosmos-sdk 0.46";
option (google.api.http).get = "/cosmos/auth/v1beta1/bech32/{address_string}";
}
// AddressStringToBytes converts Address string to bytes
rpc AddressStringToBytes(AddressStringToBytesRequest) returns (AddressStringToBytesResponse) {
option (cosmos_proto.method_added_in) = "cosmos-sdk 0.46";
option (google.api.http).get = "/cosmos/auth/v1beta1/bech32/encode/{address_string}";
}

// AccountInfo queries account info which is common to all account types.
rpc AccountInfo(QueryAccountInfoRequest) returns (QueryAccountInfoResponse) {
option (cosmos_proto.method_added_in) = "cosmos-sdk 0.47";
option (cosmos.query.v1.module_query_safe) = true;
option (google.api.http).get = "/cosmos/auth/v1beta1/account_info/{address}";
}
// AccountInfo queries account info which is common to all account types.
rpc AccountInfo(QueryAccountInfoRequest) returns (QueryAccountInfoResponse) {
option (cosmos_proto.method_added_in) = "cosmos-sdk 0.47";
option (cosmos.query.v1.module_query_safe) = true;
option (google.api.http).get = "/cosmos/auth/v1beta1/account_info/{address}";
}
}

// QueryAccountsRequest is the request type for the Query/Accounts RPC method.
Expand Down
25 changes: 17 additions & 8 deletions scripts/build/simulations.mk
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,6 @@ test-v2-sim:
@cd ${CURRENT_DIR}/simapp/v2 && go test -failfast -mod=readonly -timeout 30m -tags='sims' -run TestSimsAppV2
.PHONY: test-v2-sim


test-sim-benchmark-invariants:
@echo "Running simulation invariant benchmarks..."
cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -benchmem -bench=BenchmarkInvariants -tags='sims' -run=^$ \
-Enabled=true -NumBlocks=1000 -BlockSize=200 -Commit=true -Seed=57 -v -timeout 24h

.PHONY: \
test-sim-nondeterminism \
test-sim-nondeterminism-streaming \
Expand All @@ -88,7 +82,6 @@ test-sim-after-import \
test-sim-custom-genesis-multi-seed \
test-sim-multi-seed-short \
test-sim-multi-seed-long \
test-sim-benchmark-invariants

SIM_NUM_BLOCKS ?= 500
SIM_BLOCK_SIZE ?= 200
Expand All @@ -99,20 +92,36 @@ test-sim-fuzz:
@echo "Running application fuzz for numBlocks=2, blockSize=20. This may take awhile!"
#ld flags are a quick fix to make it work on current osx
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -json -tags='sims' -ldflags="-extldflags=-Wl,-ld_classic" -timeout=60m -fuzztime=60m -run=^$$ -fuzz=FuzzFullAppSimulation -GenesisTime=1714720615 -NumBlocks=2 -BlockSize=20

#? test-sim-fuzz-v2: Run fuzz test for simapp/v2
test-sim-fuzz-v2:
@echo "Running application fuzz for numBlocks=2, blockSize=20. This may take awhile!"
#ld flags are a quick fix to make it work on current osx
@cd ${CURRENT_DIR}/simapp/v2 && go test -failfast -mod=readonly -json -tags='sims' -timeout=60m -fuzztime=60m -run=^$$ -fuzz=FuzzFullAppSimulation -GenesisTime=1714720615 -NumBlocks=2 -BlockSize=20

#? test-sim-benchmark: Run benchmark test for simapp
test-sim-benchmark:
@echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -tags='sims' -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
-Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -timeout 24h

#? test-sim-benchmark-v2: Run benchmark test for simapp/v2
test-sim-benchmark-v2:
@echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
@cd ${CURRENT_DIR}/simapp/v2 && go test -failfast -mod=readonly -tags='sims' -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
-NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE)

test-sim-profile:
@echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
@cd ${CURRENT_DIR}/simapp && go test -failfast -mod=readonly -tags='sims' -benchmem -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
-Enabled=true -NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -Commit=$(SIM_COMMIT) -timeout 24h -cpuprofile cpu.out -memprofile mem.out

.PHONY: test-sim-profile test-sim-benchmark test-sim-fuzz
test-sim-profile-v2:
@echo "Running application benchmark for numBlocks=$(SIM_NUM_BLOCKS), blockSize=$(SIM_BLOCK_SIZE). This may take awhile!"
@cd ${CURRENT_DIR}/simapp/v2 && go test -failfast -mod=readonly -tags='sims' -benchmem -run=^$$ $(.) -bench ^BenchmarkFullAppSimulation$$ \
-NumBlocks=$(SIM_NUM_BLOCKS) -BlockSize=$(SIM_BLOCK_SIZE) -cpuprofile cpu.out -memprofile mem.out

.PHONY: test-sim-profile test-sim-benchmark test-sim-fuzz test-sim-profile-v2 test-sim-benchmark-v2 test-sim-fuzz-v2

#? benchmark: Run benchmark tests
benchmark:
Expand Down
8 changes: 6 additions & 2 deletions server/grpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"net"

gogogrpc "github.com/cosmos/gogoproto/grpc"
"google.golang.org/grpc"

"cosmossdk.io/log"
Expand All @@ -14,13 +15,16 @@ import (
"github.com/cosmos/cosmos-sdk/server/config"
"github.com/cosmos/cosmos-sdk/server/grpc/gogoreflection"
reflection "github.com/cosmos/cosmos-sdk/server/grpc/reflection/v2alpha1"
"github.com/cosmos/cosmos-sdk/server/types"
_ "github.com/cosmos/cosmos-sdk/types/tx/amino" // Import amino.proto file for reflection
)

type grpcApp interface {
RegisterGRPCServerWithSkipCheckHeader(gogogrpc.Server, bool)
}

// NewGRPCServer returns a correctly configured and initialized gRPC server.
// Note, the caller is responsible for starting the server. See StartGRPCServer.
func NewGRPCServer(clientCtx client.Context, app types.Application, cfg config.GRPCConfig) (*grpc.Server, error) {
func NewGRPCServer(clientCtx client.Context, app grpcApp, cfg config.GRPCConfig) (*grpc.Server, error) {
maxSendMsgSize := cfg.MaxSendMsgSize
if maxSendMsgSize == 0 {
maxSendMsgSize = config.DefaultGRPCMaxSendMsgSize
Expand Down
Loading

0 comments on commit ce209a7

Please sign in to comment.