Skip to content

Commit 30e3aaa

Browse files
facundomedicamergify[bot]
authored andcommitted
fix(x/tx): concurrent map writes when calling GetSigners (#21073)
(cherry picked from commit de0708b) # Conflicts: # x/tx/CHANGELOG.md # x/tx/signing/context_test.go
1 parent 91d412c commit 30e3aaa

4 files changed

Lines changed: 151 additions & 4 deletions

File tree

simapp/app.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ func NewSimApp(
209209
legacyAmino := codec.NewLegacyAmino()
210210
txConfig := tx.NewTxConfig(appCodec, tx.DefaultSignModes)
211211

212+
if err := signingCtx.Validate(); err != nil {
213+
panic(err)
214+
}
215+
212216
std.RegisterLegacyAminoCodec(legacyAmino)
213217
std.RegisterInterfaces(interfaceRegistry)
214218

x/tx/CHANGELOG.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,90 @@ Ref: https://keepachangelog.com/en/1.0.0/
3131

3232
## [Unreleased]
3333

34+
<<<<<<< HEAD
35+
=======
36+
### Improvements
37+
38+
* [#21073](https://github.com/cosmos/cosmos-sdk/pull/21073) In Context use sync.Map `getSignersFuncs` map from concurrent writes, we also call Validate when creating the Context.
39+
40+
## [v0.13.3](https://github.com/cosmos/cosmos-sdk/releases/tag/x/tx/v0.13.3) - 2024-04-22
41+
42+
### Improvements
43+
44+
* [#20049](https://github.com/cosmos/cosmos-sdk/pull/20049) Sort JSON attributes for `inline_json` encoder.
45+
46+
## [v0.13.2](https://github.com/cosmos/cosmos-sdk/releases/tag/x/tx/v0.13.2) - 2024-04-12
47+
48+
### Features
49+
50+
* [#19786](https://github.com/cosmos/cosmos-sdk/pull/19786)/[#19919](https://github.com/cosmos/cosmos-sdk/pull/19919) Add "inline_json" option to Amino JSON encoder.
51+
52+
### Improvements
53+
54+
* [#19845](https://github.com/cosmos/cosmos-sdk/pull/19845) Use hybrid resolver instead of only protov2 registry
55+
56+
### Bug Fixes
57+
58+
* [#19955](https://github.com/cosmos/cosmos-sdk/pull/19955) Don't shadow Amino marshalling error messages
59+
60+
## [v0.13.1](https://github.com/cosmos/cosmos-sdk/releases/tag/x/tx/v0.13.1) - 2024-03-05
61+
62+
### Features
63+
64+
* [#19618](https://github.com/cosmos/cosmos-sdk/pull/19618) Add enum as string option to encoder.
65+
66+
### Improvements
67+
68+
* [#18857](https://github.com/cosmos/cosmos-sdk/pull/18857) Moved `FormatCoins` from `core/coins` to this package under `signing/textual`.
69+
70+
### Bug Fixes
71+
72+
* [#19265](https://github.com/cosmos/cosmos-sdk/pull/19265) Reject denoms that contain a comma.
73+
74+
## [v0.13.0](https://github.com/cosmos/cosmos-sdk/releases/tag/x/tx/v0.13.0) - 2023-12-19
75+
76+
### Improvements
77+
78+
* [#18740](https://github.com/cosmos/cosmos-sdk/pull/18740) Support nested messages when fetching signers up to a default depth of 32.
79+
80+
## v0.12.0
81+
82+
### Improvements
83+
84+
* [#18309](https://github.com/cosmos/cosmos-sdk/pull/18309) Update encoder so that amino types default to msg type url.
85+
86+
## v0.11.0
87+
88+
### Improvements
89+
90+
* [#17787](https://github.com/cosmos/cosmos-sdk/pull/17787) Drop tip support.
91+
92+
## v0.10.0
93+
94+
### Features
95+
96+
* [#17681](https://github.com/cosmos/cosmos-sdk/pull/17681) Add encoder `DefineTypeEncoding` method for defining custom type encodings.
97+
* [#17600](https://github.com/cosmos/cosmos-sdk/pull/17600) Add encoder `DefineScalarEncoding` method for defining custom scalar encodings.
98+
* [#17600](https://github.com/cosmos/cosmos-sdk/pull/17600) Add indent option to encoder.
99+
100+
## v0.9.1
101+
102+
### Improvements
103+
104+
* [#16936](https://github.com/cosmos/cosmos-sdk/pull/16936) Remove extra whitespace when marshalling module accounts.
105+
106+
## v0.9.0
107+
108+
### Bug Fixes
109+
110+
* [#16681](https://github.com/cosmos/cosmos-sdk/pull/16681): Catch and fix `(*Decoder).Decode` crash from invalid length prefix in Tx bytes.
111+
112+
### Improvements
113+
114+
* [#16846](https://github.com/cosmos/cosmos-sdk/pull/16846): Harmonize interface `signing.TypeResolver` with the rest of the codebase (orm and client/v2).
115+
* [#16684](https://github.com/cosmos/cosmos-sdk/pull/16684): Use `io.WriteString`+`fmt.Fprintf` to remove unnecessary `string`->`[]byte` roundtrip.
116+
117+
>>>>>>> de0708b40 (fix(x/tx): concurrent map writes when calling GetSigners (#21073))
34118
## v0.8.0
35119

36120
### Improvements

x/tx/signing/context.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package signing
33
import (
44
"errors"
55
"fmt"
6+
"sync"
67

78
cosmos_proto "github.com/cosmos/cosmos-proto"
89
"google.golang.org/protobuf/proto"
@@ -23,7 +24,7 @@ type Context struct {
2324
typeResolver protoregistry.MessageTypeResolver
2425
addressCodec address.Codec
2526
validatorAddressCodec address.Codec
26-
getSignersFuncs map[protoreflect.FullName]GetSignersFunc
27+
getSignersFuncs sync.Map
2728
customGetSignerFuncs map[protoreflect.FullName]GetSignersFunc
2829
}
2930

@@ -95,7 +96,7 @@ func NewContext(options Options) (*Context, error) {
9596
typeResolver: protoTypes,
9697
addressCodec: options.AddressCodec,
9798
validatorAddressCodec: options.ValidatorAddressCodec,
98-
getSignersFuncs: map[protoreflect.FullName]GetSignersFunc{},
99+
getSignersFuncs: sync.Map{},
99100
customGetSignerFuncs: customGetSignerFuncs,
100101
}
101102

@@ -323,14 +324,17 @@ func (c *Context) getGetSignersFn(messageDescriptor protoreflect.MessageDescript
323324
if ok {
324325
return f, nil
325326
}
326-
f, ok = c.getSignersFuncs[messageDescriptor.FullName()]
327+
328+
loadedFn, ok := c.getSignersFuncs.Load(messageDescriptor.FullName())
327329
if !ok {
328330
var err error
329331
f, err = c.makeGetSignersFunc(messageDescriptor)
330332
if err != nil {
331333
return nil, err
332334
}
333-
c.getSignersFuncs[messageDescriptor.FullName()] = f
335+
c.getSignersFuncs.Store(messageDescriptor.FullName(), f)
336+
} else {
337+
f = loadedFn.(GetSignersFunc)
334338
}
335339

336340
return f, nil

x/tx/signing/context_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,61 @@ import (
1414
"cosmossdk.io/x/tx/internal/testpb"
1515
)
1616

17+
<<<<<<< HEAD
18+
=======
19+
var deeplyNestedRepeatedSigner = &testpb.DeeplyNestedRepeatedSigner{
20+
Inner: []*testpb.DeeplyNestedRepeatedSigner_Inner{
21+
{
22+
Inner: []*testpb.DeeplyNestedRepeatedSigner_Inner_Inner{
23+
{
24+
Inner: []*testpb.DeeplyNestedRepeatedSigner_Inner_Inner_Bottom{
25+
{
26+
Signer: []string{hex.EncodeToString([]byte("foo")), hex.EncodeToString([]byte("bar"))},
27+
},
28+
},
29+
},
30+
},
31+
},
32+
{
33+
Inner: []*testpb.DeeplyNestedRepeatedSigner_Inner_Inner{
34+
{
35+
Inner: []*testpb.DeeplyNestedRepeatedSigner_Inner_Inner_Bottom{
36+
{
37+
Signer: []string{hex.EncodeToString([]byte("baz"))},
38+
},
39+
},
40+
},
41+
{
42+
Inner: []*testpb.DeeplyNestedRepeatedSigner_Inner_Inner_Bottom{
43+
{
44+
Signer: []string{hex.EncodeToString([]byte("qux")), hex.EncodeToString([]byte("fuz"))},
45+
},
46+
{
47+
Signer: []string{hex.EncodeToString([]byte("bing")), hex.EncodeToString([]byte("bap"))},
48+
},
49+
},
50+
},
51+
},
52+
},
53+
},
54+
}
55+
56+
func TestGetGetSignersFnConcurrent(t *testing.T) {
57+
ctx, err := NewContext(Options{
58+
AddressCodec: dummyAddressCodec{},
59+
ValidatorAddressCodec: dummyValidatorAddressCodec{},
60+
})
61+
require.NoError(t, err)
62+
63+
desc := (&testpb.RepeatedSigner{}).ProtoReflect().Descriptor()
64+
for i := 0; i < 50; i++ {
65+
go func() {
66+
_, _ = ctx.getGetSignersFn(desc)
67+
}()
68+
}
69+
}
70+
71+
>>>>>>> de0708b40 (fix(x/tx): concurrent map writes when calling GetSigners (#21073))
1772
func TestGetSigners(t *testing.T) {
1873
ctx, err := NewContext(Options{
1974
AddressCodec: dummyAddressCodec{},

0 commit comments

Comments
 (0)