Skip to content

Commit 1132e3c

Browse files
sergio-menamergify[bot]thanethomson
authored
Merge pull request from GHSA-cpqw-5g6w-h8rr
* Revert "Fixed ordering of match.events in light client RPC (tendermint#9877)" * Revert "state/kvindexer: associate event attributes with events (tendermint#9759)" * Revert "consensus: correctly save reference to previous height precommits (backport tendermint#9760) (tendermint#9776)" * add peer gossip sleep (tendermint#241) (tendermint#245) * add peer gossip sleep * add changelog * Update .changelog/unreleased/bug-fixes/4-busy-loop-send-block-part.md Co-authored-by: Jasmina Malicevic <[email protected]> * Update .changelog/unreleased/bug-fixes/4-busy-loop-send-block-part.md --------- Co-authored-by: jhernandezb <[email protected]> Co-authored-by: Jasmina Malicevic <[email protected]> (cherry picked from commit 5954e75) Co-authored-by: Sergio Mena <[email protected]> * Build changelog for v0.34.25 release Signed-off-by: Thane Thomson <[email protected]> * Bump version --------- Signed-off-by: Thane Thomson <[email protected]> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Thane Thomson <[email protected]>
1 parent 936221e commit 1132e3c

File tree

22 files changed

+121
-897
lines changed

22 files changed

+121
-897
lines changed

CHANGELOG.md

+26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,32 @@
22

33
Friendly reminder, we have a [bug bounty program](https://hackerone.com/cosmos).
44

5+
## v0.34.25
6+
7+
*Feb 3, 2023*
8+
9+
This is primarily a security patch from the Informal Systems team's public fork
10+
of Tendermint Core, but additionally includes some minor improvements that were
11+
not yet released on the `v0.34.x` branch.
12+
13+
Special thanks to @jhernandezb and the Notional team for picking up on this
14+
issue!
15+
16+
### SECURITY
17+
18+
- `[consensus]`
19+
[informalsystems/tendermint\#4](https://github.com/informalsystems/tendermint/issues/4)
20+
Fixed a busy loop that happened when sending of a block part failed by
21+
sleeping in case of error (@jhernandezb and @sergio-mena)
22+
23+
### IMPROVEMENTS
24+
25+
- `[crypto]` [\#9250](https://github.com/tendermint/tendermint/issues/9250)
26+
Update to use btcec v2 and the latest btcutil. (@wcsiu)
27+
- `[metrics]` [\#9733](https://github.com/tendermint/tendermint/issues/9733) Add
28+
metrics for timing the consensus steps and for the progress of block gossip.
29+
(@williambanfield)
30+
531
## v0.34.24
632

733
*Nov 21, 2022*

CHANGELOG_PENDING.md

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Unreleased Changes
22

3-
## v0.34.25
3+
## v0.34.26
44

55
### BREAKING CHANGES
66

@@ -16,14 +16,7 @@
1616

1717
### FEATURES
1818

19-
- `[rpc]` [\#9759] Added `match_event` query parameter to indicate to Tendermint that the query should match event attributes within events, not only within a height.
20-
2119
### IMPROVEMENTS
2220

23-
- `[state/kvindexer]` [\#9759] Added `match.event` keyword to support condition evalution based on the event attributes belong to. (@jmalicevic)
24-
- [crypto] \#9250 Update to use btcec v2 and the latest btcutil. (@wcsiu)
25-
- [consensus] \#9760 Save peer LastCommit correctly to achieve 50% reduction in gossiped precommits. (@williambanfield)
26-
- [metrics] \#9733 Add metrics for timing the consensus steps and for the progress of block gossip. (@williambanfield)
27-
2821
### BUG FIXES
2922

abci/example/kvstore/kvstore.go

-84
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,13 @@ type Application struct {
6868

6969
state State
7070
RetainBlocks int64 // blocks to retain after commit (via ResponseCommit.RetainHeight)
71-
// If true, the app will generate block events in BeginBlock. Used to test the event indexer
72-
// Should be false by default to avoid generating too much data.
73-
genBlockEvents bool
7471
}
7572

7673
func NewApplication() *Application {
7774
state := loadState(dbm.NewMemDB())
7875
return &Application{state: state}
7976
}
8077

81-
func (app *Application) SetGenBlockEvents() {
82-
app.genBlockEvents = true
83-
}
84-
8578
func (app *Application) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
8679
return types.ResponseInfo{
8780
Data: fmt.Sprintf("{\"size\":%v}", app.state.Size),
@@ -118,15 +111,6 @@ func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeli
118111
{Key: []byte("noindex_key"), Value: []byte("index is working"), Index: false},
119112
},
120113
},
121-
{
122-
Type: "app",
123-
Attributes: []types.EventAttribute{
124-
{Key: []byte("creator"), Value: []byte("Cosmoshi"), Index: true},
125-
{Key: []byte("key"), Value: value, Index: true},
126-
{Key: []byte("index_key"), Value: []byte("index is working"), Index: true},
127-
{Key: []byte("noindex_key"), Value: []byte("index is working"), Index: false},
128-
},
129-
},
130114
}
131115

132116
return types.ResponseDeliverTx{Code: code.CodeTypeOK, Events: events}
@@ -186,71 +170,3 @@ func (app *Application) Query(reqQuery types.RequestQuery) (resQuery types.Respo
186170

187171
return resQuery
188172
}
189-
190-
func (app *Application) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
191-
192-
response := types.ResponseBeginBlock{}
193-
194-
if !app.genBlockEvents {
195-
return response
196-
}
197-
198-
if app.state.Height%2 == 0 {
199-
response = types.ResponseBeginBlock{
200-
Events: []types.Event{
201-
{
202-
Type: "begin_event",
203-
Attributes: []types.EventAttribute{
204-
{
205-
Key: []byte("foo"),
206-
Value: []byte("100"),
207-
Index: true,
208-
},
209-
{
210-
Key: []byte("bar"),
211-
Value: []byte("200"),
212-
Index: true,
213-
},
214-
},
215-
},
216-
{
217-
Type: "begin_event",
218-
Attributes: []types.EventAttribute{
219-
{
220-
Key: []byte("foo"),
221-
Value: []byte("200"),
222-
Index: true,
223-
},
224-
{
225-
Key: []byte("bar"),
226-
Value: []byte("300"),
227-
Index: true,
228-
},
229-
},
230-
},
231-
},
232-
}
233-
} else {
234-
response = types.ResponseBeginBlock{
235-
Events: []types.Event{
236-
{
237-
Type: "begin_event",
238-
Attributes: []types.EventAttribute{
239-
{
240-
Key: []byte("foo"),
241-
Value: []byte("400"),
242-
Index: true,
243-
},
244-
{
245-
Key: []byte("bar"),
246-
Value: []byte("300"),
247-
Index: true,
248-
},
249-
},
250-
},
251-
},
252-
}
253-
}
254-
255-
return response
256-
}

abci/example/kvstore/persistent_kvstore.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ func NewPersistentKVStoreApplication(dbDir string) *PersistentKVStoreApplication
5151
}
5252
}
5353

54-
func (app *PersistentKVStoreApplication) SetGenBlockEvents() {
55-
app.app.genBlockEvents = true
56-
}
5754
func (app *PersistentKVStoreApplication) SetLogger(l log.Logger) {
5855
app.logger = l
5956
}
@@ -145,7 +142,7 @@ func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock)
145142
}
146143
}
147144

148-
return app.app.BeginBlock(req)
145+
return types.ResponseBeginBlock{}
149146
}
150147

151148
// Update the validator set

consensus/reactor.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,8 @@ func (conR *Reactor) gossipDataForCatchup(logger log.Logger, rs *cstypes.RoundSt
706706
ps.SetHasProposalBlockPart(prs.Height, prs.Round, index)
707707
} else {
708708
logger.Debug("Sending block part for catchup failed")
709+
// sleep to avoid retrying too fast
710+
time.Sleep(conR.conS.config.PeerGossipSleepDuration)
709711
}
710712
return
711713
}
@@ -1375,7 +1377,6 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) {
13751377
psRound := ps.PRS.Round
13761378
psCatchupCommitRound := ps.PRS.CatchupCommitRound
13771379
psCatchupCommit := ps.PRS.CatchupCommit
1378-
lastPrecommits := ps.PRS.Precommits
13791380

13801381
startTime := tmtime.Now().Add(-1 * time.Duration(msg.SecondsSinceStartTime) * time.Second)
13811382
ps.PRS.Height = msg.Height
@@ -1403,7 +1404,7 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) {
14031404
// Shift Precommits to LastCommit.
14041405
if psHeight+1 == msg.Height && psRound == msg.LastCommitRound {
14051406
ps.PRS.LastCommitRound = msg.LastCommitRound
1406-
ps.PRS.LastCommit = lastPrecommits
1407+
ps.PRS.LastCommit = ps.PRS.Precommits
14071408
} else {
14081409
ps.PRS.LastCommitRound = msg.LastCommitRound
14091410
ps.PRS.LastCommit = nil

docs/app-dev/indexing-transactions.md

+1-82
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ would be equal to the composite key of `jack.account.number`.
3434
By default, Tendermint will index all transactions by their respective hashes
3535
and height and blocks by their height.
3636

37-
Tendermint allows for different events within the same height to have
38-
equal attributes.
39-
4037
## Configuration
4138

4239
Operators can configure indexing via the `[tx_index]` section. The `indexer`
@@ -70,56 +67,6 @@ for block and transaction events directly against Tendermint's RPC. However, the
7067
query syntax is limited and so this indexer type might be deprecated or removed
7168
entirely in the future.
7269

73-
**Implementation and data layout**
74-
75-
The kv indexer stores each attribute of an event individually, by creating a composite key
76-
of the *event type*, *attribute key*, *attribute value*, *height* and *event sequence*.
77-
78-
For example the following events:
79-
80-
```
81-
Type: "transfer",
82-
Attributes: []abci.EventAttribute{
83-
{Key: []byte("sender"), Value: []byte("Bob"), Index: true},
84-
{Key: []byte("recipient"), Value: []byte("Alice"), Index: true},
85-
{Key: []byte("balance"), Value: []byte("100"), Index: true},
86-
{Key: []byte("note"), Value: []byte("nothing"), Index: true},
87-
},
88-
89-
```
90-
91-
```
92-
Type: "transfer",
93-
Attributes: []abci.EventAttribute{
94-
{Key: []byte("sender"), Value: []byte("Tom"), Index: true},
95-
{Key: []byte("recipient"), Value: []byte("Alice"), Index: true},
96-
{Key: []byte("balance"), Value: []byte("200"), Index: true},
97-
{Key: []byte("note"), Value: []byte("nothing"), Index: true},
98-
},
99-
```
100-
101-
will be represented as follows in the store:
102-
103-
```
104-
Key value
105-
transferSenderBobEndBlock1 1
106-
transferRecepientAliceEndBlock11 1
107-
transferBalance100EndBlock11 1
108-
transferNodeNothingEndblock11 1
109-
---- event2 ------
110-
transferSenderTomEndBlock12 1
111-
transferRecepientAliceEndBlock12 1
112-
transferBalance200EndBlock12 1
113-
transferNodeNothingEndblock12 1
114-
115-
```
116-
The key is thus formed of the event type, the attribute key and value, the event the attribute belongs to (`EndBlock` or `BeginBlock`),
117-
the height and the event number. The event number is a local variable kept by the indexer and incremented when a new event is processed.
118-
119-
It is an `int64` variable and has no other semantics besides being used to associate attributes belonging to the same events within a height.
120-
This variable is not atomically incremented as event indexing is deterministic. **Should this ever change**, the event id generation
121-
will be broken.
122-
12370
#### PostgreSQL
12471

12572
The `psql` indexer type allows an operator to enable block and transaction event
@@ -198,9 +145,6 @@ You can query for a paginated set of transaction by their events by calling the
198145
```bash
199146
curl "localhost:26657/tx_search?query=\"message.sender='cosmos1...'\"&prove=true"
200147
```
201-
If the conditions are related to transaction events and the user wants to make sure the
202-
conditions are true within the same events, the `match.event` keyword should be used,
203-
as described [below](#querying_block_events)
204148

205149
Check out [API docs](https://docs.tendermint.com/v0.34/rpc/#/Info/tx_search)
206150
for more information on query syntax and other options.
@@ -224,7 +168,7 @@ a query to `/subscribe` RPC endpoint.
224168
Check out [API docs](https://docs.tendermint.com/v0.34/rpc/#subscribe) for more information
225169
on query syntax and other options.
226170

227-
## Querying Block Events
171+
## Querying Blocks Events
228172

229173
You can query for a paginated set of blocks by their events by calling the
230174
`/block_search` RPC endpoint:
@@ -233,30 +177,5 @@ You can query for a paginated set of blocks by their events by calling the
233177
curl "localhost:26657/block_search?query=\"block.height > 10 AND val_set.num_changed > 0\""
234178
```
235179

236-
## `match_events` keyword
237-
238-
The query results in the height number(s) (or transaction hashes when querying transactions) which contain events whose attributes match the query conditions.
239-
However, there are two options to query the indexers. To demonstrate the two modes, we reuse the two events
240-
where Bob and Tom send money to Alice and query the block indexer. We issue the following query:
241-
242-
```bash
243-
curl "localhost:26657/block_search?query=\"sender=Bob AND balance = 200\""
244-
```
245-
246-
The result will return height 1 even though the attributes matching the conditions in the query
247-
occurred in different events.
248-
249-
If we wish to retrieve only heights where the attributes occurred within the same event,
250-
the query syntax is as follows:
251-
252-
```bash
253-
curl "localhost:26657/block_search?query=\"sender=Bob AND balance = 200\"&match_events=true"
254-
```
255-
Currently the default behaviour is if `match_events` is set to false.
256-
257180
Check out [API docs](https://docs.tendermint.com/v0.34/rpc/#/Info/block_search)
258181
for more information on query syntax and other options.
259-
260-
**Backwards compatibility**
261-
262-
Up until Tendermint 0.34.25, the event sequence was not stored in the kvstore and the `match_events` keyword in the RPC query is not ignored by older versions. Thus, in a network running mixed Tendermint versions, nodes running older versions will still return blocks (or transactions) whose attributes match within different events on the same height.

light/proxy/routes.go

+6-16
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ func RPCRoutes(c *lrpc.Client) map[string]*rpcserver.RPCFunc {
2929
"block_results": rpcserver.NewRPCFunc(makeBlockResultsFunc(c), "height", rpcserver.Cacheable("height")),
3030
"commit": rpcserver.NewRPCFunc(makeCommitFunc(c), "height", rpcserver.Cacheable("height")),
3131
"tx": rpcserver.NewRPCFunc(makeTxFunc(c), "hash,prove", rpcserver.Cacheable()),
32-
"tx_search": rpcserver.NewRPCFunc(makeTxSearchFuncMatchEvents(c), "query,prove,page,per_page,order_by,match_events"),
33-
"block_search": rpcserver.NewRPCFunc(makeBlockSearchFuncMatchEvents(c), "query,page,per_page,order_by,match_events"),
32+
"tx_search": rpcserver.NewRPCFunc(makeTxSearchFunc(c), "query,prove,page,per_page,order_by"),
33+
"block_search": rpcserver.NewRPCFunc(makeBlockSearchFunc(c), "query,page,per_page,order_by"),
3434
"validators": rpcserver.NewRPCFunc(makeValidatorsFunc(c), "height,page,per_page", rpcserver.Cacheable("height")),
3535
"dump_consensus_state": rpcserver.NewRPCFunc(makeDumpConsensusStateFunc(c), ""),
3636
"consensus_state": rpcserver.NewRPCFunc(makeConsensusStateFunc(c), ""),
@@ -141,52 +141,42 @@ func makeTxFunc(c *lrpc.Client) rpcTxFunc {
141141
}
142142
}
143143

144-
type rpcTxSearchFuncMatchEvents func(
144+
type rpcTxSearchFunc func(
145145
ctx *rpctypes.Context,
146146
query string,
147147
prove bool,
148148
page, perPage *int,
149149
orderBy string,
150-
matchEvents bool,
151150
) (*ctypes.ResultTxSearch, error)
152151

153-
func makeTxSearchFuncMatchEvents(c *lrpc.Client) rpcTxSearchFuncMatchEvents {
152+
func makeTxSearchFunc(c *lrpc.Client) rpcTxSearchFunc {
154153
return func(
155154
ctx *rpctypes.Context,
156155
query string,
157156
prove bool,
158157
page, perPage *int,
159158
orderBy string,
160-
matchEvents bool,
161159
) (*ctypes.ResultTxSearch, error) {
162-
if matchEvents {
163-
query = "match.events = 1 AND " + query
164-
}
165160
return c.TxSearch(ctx.Context(), query, prove, page, perPage, orderBy)
166161
}
167162
}
168163

169-
type rpcBlockSearchFuncMatchEvents func(
164+
type rpcBlockSearchFunc func(
170165
ctx *rpctypes.Context,
171166
query string,
172167
prove bool,
173168
page, perPage *int,
174169
orderBy string,
175-
matchEvents bool,
176170
) (*ctypes.ResultBlockSearch, error)
177171

178-
func makeBlockSearchFuncMatchEvents(c *lrpc.Client) rpcBlockSearchFuncMatchEvents {
172+
func makeBlockSearchFunc(c *lrpc.Client) rpcBlockSearchFunc {
179173
return func(
180174
ctx *rpctypes.Context,
181175
query string,
182176
prove bool,
183177
page, perPage *int,
184178
orderBy string,
185-
matchEvents bool,
186179
) (*ctypes.ResultBlockSearch, error) {
187-
if matchEvents {
188-
query = "match.events = 1 AND " + query
189-
}
190180
return c.BlockSearch(ctx.Context(), query, page, perPage, orderBy)
191181
}
192182
}

0 commit comments

Comments
 (0)