Skip to content

Commit afdf06a

Browse files
mergify[bot]technicallytyjulienrbrt
authored
fix(x/auth): allow multiple = signs in GetTxsEvent (backport #12474) (#13598)
* fix(x/auth): allow multiple = signs in `GetTxsEvent` (#12474) (cherry picked from commit 18da0e9) # Conflicts: # CHANGELOG.md * fix changelog * changelog * fix: flakey test Co-authored-by: Tyler <48813565+technicallyty@users.noreply.github.com> Co-authored-by: Julien Robert <julien@rbrt.fr>
1 parent f538e09 commit afdf06a

File tree

3 files changed

+92
-4
lines changed

3 files changed

+92
-4
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
4141

4242
* (x/auth) [#13612](https://github.com/cosmos/cosmos-sdk/pull/13612) Add `Query/ModuleAccountByName` endpoint for accessing the module account info by module name.
4343

44+
## Bug Fixes
45+
46+
* (x/auth/tx) [#12474](https://github.com/cosmos/cosmos-sdk/pull/12474) Remove condition in GetTxsEvent that disallowed multiple equal signs, which would break event queries with base64 strings (i.e. query by signature).
47+
4448
## [v0.46.3](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.3) - 2022-10-20
4549

4650
ATTENTION:
@@ -52,7 +56,7 @@ All users should upgrade immediately.
5256
Users *must* add a replace directive in their go.mod for the new `ics23` package in the SDK:
5357

5458
```go
55-
replace github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v8.0.0
59+
replace github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0
5660
```
5761

5862
### Features

x/auth/tx/service.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package tx
33
import (
44
"context"
55
"fmt"
6+
"regexp"
67
"strings"
78

89
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
@@ -40,13 +41,18 @@ func NewTxServer(clientCtx client.Context, simulate baseAppSimulateFn, interface
4041
}
4142
}
4243

43-
var _ txtypes.ServiceServer = txServer{}
44+
var (
45+
_ txtypes.ServiceServer = txServer{}
46+
47+
// EventRegex checks that an event string is formatted with {alphabetic}.{alphabetic}={value}
48+
EventRegex = regexp.MustCompile(`^[a-zA-Z]+\.[a-zA-Z]+=\S+$`)
49+
)
4450

4551
const (
4652
eventFormat = "{eventType}.{eventAttribute}={value}"
4753
)
4854

49-
// TxsByEvents implements the ServiceServer.TxsByEvents RPC method.
55+
// GetTxsEvent implements the ServiceServer.TxsByEvents RPC method.
5056
func (s txServer) GetTxsEvent(ctx context.Context, req *txtypes.GetTxsEventRequest) (*txtypes.GetTxsEventResponse, error) {
5157
if req == nil {
5258
return nil, status.Error(codes.InvalidArgument, "request cannot be nil")
@@ -70,7 +76,7 @@ func (s txServer) GetTxsEvent(ctx context.Context, req *txtypes.GetTxsEventReque
7076
}
7177

7278
for _, event := range req.Events {
73-
if !strings.Contains(event, "=") || strings.Count(event, "=") > 1 {
79+
if !EventRegex.Match([]byte(event)) {
7480
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid event; event %s should be of the format: %s", event, eventFormat))
7581
}
7682
}

x/auth/tx/service_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ package tx_test
44

55
import (
66
"context"
7+
"encoding/base64"
78
"fmt"
89
"strings"
910
"testing"
1011

12+
"github.com/stretchr/testify/require"
1113
"github.com/stretchr/testify/suite"
1214

1315
"github.com/cosmos/cosmos-sdk/client"
@@ -28,6 +30,7 @@ import (
2830
"github.com/cosmos/cosmos-sdk/types/tx/signing"
2931
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
3032
authtest "github.com/cosmos/cosmos-sdk/x/auth/client/testutil"
33+
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
3134
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
3235
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
3336
)
@@ -111,6 +114,81 @@ func (s *IntegrationTestSuite) TearDownSuite() {
111114
s.network.Cleanup()
112115
}
113116

117+
func (s *IntegrationTestSuite) TestQueryBySig() {
118+
// broadcast tx
119+
txb := s.mkTxBuilder()
120+
txbz, err := s.cfg.TxConfig.TxEncoder()(txb.GetTx())
121+
s.Require().NoError(err)
122+
resp, err := s.queryClient.BroadcastTx(context.Background(), &tx.BroadcastTxRequest{TxBytes: txbz, Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC})
123+
s.Require().NoError(err)
124+
s.Require().NotEmpty(resp.TxResponse.TxHash)
125+
126+
s.Require().NoError(s.network.WaitForNextBlock())
127+
128+
// get the signature out of the builder
129+
sigs, err := txb.GetTx().GetSignaturesV2()
130+
s.Require().NoError(err)
131+
s.Require().Len(sigs, 1)
132+
sig, ok := sigs[0].Data.(*signing.SingleSignatureData)
133+
s.Require().True(ok)
134+
135+
// encode, format, query
136+
b64Sig := base64.StdEncoding.EncodeToString(sig.Signature)
137+
sigFormatted := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, b64Sig)
138+
res, err := s.queryClient.GetTxsEvent(context.Background(), &tx.GetTxsEventRequest{
139+
Events: []string{sigFormatted},
140+
OrderBy: 0,
141+
Page: 0,
142+
Limit: 10,
143+
})
144+
s.Require().NoError(err)
145+
s.Require().Len(res.Txs, 1)
146+
s.Require().Len(res.Txs[0].Signatures, 1)
147+
s.Require().Equal(res.Txs[0].Signatures[0], sig.Signature)
148+
149+
// bad format should error
150+
_, err = s.queryClient.GetTxsEvent(context.Background(), &tx.GetTxsEventRequest{Events: []string{"tx.foo.bar='baz'"}})
151+
s.Require().ErrorContains(err, "invalid event;")
152+
}
153+
154+
func TestEventRegex(t *testing.T) {
155+
t.Parallel()
156+
157+
testCases := []struct {
158+
name string
159+
event string
160+
match bool
161+
}{
162+
{
163+
name: "valid: with quotes",
164+
event: "tx.message='something'",
165+
match: true,
166+
},
167+
{
168+
name: "valid: no quotes",
169+
event: "tx.message=something",
170+
match: true,
171+
},
172+
{
173+
name: "invalid: too many separators",
174+
event: "tx.message.foo='bar'",
175+
match: false,
176+
},
177+
{
178+
name: "valid: symbols ok",
179+
event: "tx.signature='foobar/baz123=='",
180+
match: true,
181+
},
182+
}
183+
184+
for _, tc := range testCases {
185+
t.Run(tc.name, func(t *testing.T) {
186+
match := authtx.EventRegex.Match([]byte(tc.event))
187+
require.Equal(t, tc.match, match)
188+
})
189+
}
190+
}
191+
114192
func (s IntegrationTestSuite) TestSimulateTx_GRPC() {
115193
val := s.network.Validators[0]
116194
txBuilder := s.mkTxBuilder()

0 commit comments

Comments
 (0)