fix(x/auth): allow multiple = signs in GetTxsEvent (#12474)
This commit is contained in:
parent
b75c2ebcfa
commit
18da0e9c15
@ -88,6 +88,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* (x/staking) [#12303](https://github.com/cosmos/cosmos-sdk/pull/12303) Use bytes instead of string comparison in delete validator queue
|
||||
* (testutil/sims) [#12374](https://github.com/cosmos/cosmos-sdk/pull/12374) fix the non-determinstic behavior in simulations caused by `GenSignedMockTx` and check
|
||||
empty coins slice before it is used to create `banktype.MsgSend`.
|
||||
* (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).
|
||||
|
||||
## [v0.46.0-rc1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.0-rc1) - 2022-05-23
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package tx
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
gogogrpc "github.com/gogo/protobuf/grpc"
|
||||
@ -39,13 +40,18 @@ func NewTxServer(clientCtx client.Context, simulate baseAppSimulateFn, interface
|
||||
}
|
||||
}
|
||||
|
||||
var _ txtypes.ServiceServer = txServer{}
|
||||
var (
|
||||
_ txtypes.ServiceServer = txServer{}
|
||||
|
||||
// EventRegex checks that an event string is formatted with {alphabetic}.{alphabetic}={value}
|
||||
EventRegex = regexp.MustCompile(`^[a-zA-Z]+\.[a-zA-Z]+=\S+$`)
|
||||
)
|
||||
|
||||
const (
|
||||
eventFormat = "{eventType}.{eventAttribute}={value}"
|
||||
)
|
||||
|
||||
// TxsByEvents implements the ServiceServer.TxsByEvents RPC method.
|
||||
// GetTxsEvent implements the ServiceServer.TxsByEvents RPC method.
|
||||
func (s txServer) GetTxsEvent(ctx context.Context, req *txtypes.GetTxsEventRequest) (*txtypes.GetTxsEventResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "request cannot be nil")
|
||||
@ -69,7 +75,7 @@ func (s txServer) GetTxsEvent(ctx context.Context, req *txtypes.GetTxsEventReque
|
||||
}
|
||||
|
||||
for _, event := range req.Events {
|
||||
if !strings.Contains(event, "=") || strings.Count(event, "=") > 1 {
|
||||
if !EventRegex.Match([]byte(event)) {
|
||||
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid event; event %s should be of the format: %s", event, eventFormat))
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,10 +4,12 @@ package tx_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
@ -28,6 +30,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
||||
authtest "github.com/cosmos/cosmos-sdk/x/auth/client/testutil"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
@ -111,6 +114,78 @@ func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestQueryBySig() {
|
||||
// broadcast tx
|
||||
txb := s.mkTxBuilder()
|
||||
txbz, err := s.cfg.TxConfig.TxEncoder()(txb.GetTx())
|
||||
s.Require().NoError(err)
|
||||
_, err = s.queryClient.BroadcastTx(context.Background(), &tx.BroadcastTxRequest{TxBytes: txbz, Mode: tx.BroadcastMode_BROADCAST_MODE_BLOCK})
|
||||
s.Require().NoError(err)
|
||||
|
||||
// get the signature out of the builder
|
||||
sigs, err := txb.GetTx().GetSignaturesV2()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(sigs, 1)
|
||||
sig, ok := sigs[0].Data.(*signing.SingleSignatureData)
|
||||
s.Require().True(ok)
|
||||
|
||||
// encode, format, query
|
||||
b64Sig := base64.StdEncoding.EncodeToString(sig.Signature)
|
||||
sigFormatted := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, b64Sig)
|
||||
res, err := s.queryClient.GetTxsEvent(context.Background(), &tx.GetTxsEventRequest{
|
||||
Events: []string{sigFormatted},
|
||||
OrderBy: 0,
|
||||
Page: 0,
|
||||
Limit: 10,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(res.Txs, 1)
|
||||
s.Require().Len(res.Txs[0].Signatures, 1)
|
||||
s.Require().Equal(res.Txs[0].Signatures[0], sig.Signature)
|
||||
|
||||
// bad format should error
|
||||
_, err = s.queryClient.GetTxsEvent(context.Background(), &tx.GetTxsEventRequest{Events: []string{"tx.foo.bar='baz'"}})
|
||||
s.Require().ErrorContains(err, "invalid event;")
|
||||
}
|
||||
|
||||
func TestEventRegex(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
event string
|
||||
match bool
|
||||
}{
|
||||
{
|
||||
name: "valid: with quotes",
|
||||
event: "tx.message='something'",
|
||||
match: true,
|
||||
},
|
||||
{
|
||||
name: "valid: no quotes",
|
||||
event: "tx.message=something",
|
||||
match: true,
|
||||
},
|
||||
{
|
||||
name: "invalid: too many separators",
|
||||
event: "tx.message.foo='bar'",
|
||||
match: false,
|
||||
},
|
||||
{
|
||||
name: "valid: symbols ok",
|
||||
event: "tx.signature='foobar/baz123=='",
|
||||
match: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
match := authtx.EventRegex.Match([]byte(tc.event))
|
||||
require.Equal(t, tc.match, match)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s IntegrationTestSuite) TestSimulateTx_GRPC() {
|
||||
val := s.network.Validators[0]
|
||||
txBuilder := s.mkTxBuilder()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user