consensus: rename (*PeerState).ToJSON to MarshalJSON (backport #524)#533
Merged
thanethomson merged 2 commits intov0.34.xfrom Mar 16, 2023
Merged
consensus: rename (*PeerState).ToJSON to MarshalJSON (backport #524)#533thanethomson merged 2 commits intov0.34.xfrom
thanethomson merged 2 commits intov0.34.xfrom
Conversation
In (*PeerState).PickSendVote, there is a Debug-level log that includes the PeerState value as a logging field. By default, zerolog json-encodes a struct passed as a log field (when the struct doesn't implement zerolog.LogObjectMarshaler).
Because PeerState didn't have a MarshalJSON method, the JSON encoder fell back to reflection to encode the PeerState value. Reflection did not acquire the lock, and there were data races resulting from an unsynchronized read while logging the PeerState, and concurrent (locked) writes at least during (*PeerState).SetHasProposal and (*PeerState).SetHasVote.
Given that there was only one call to (*PeerState).ToJSON in the cometbft repo, it seemed appropriate to just rename ToJSON to MarshalJSON, as opposed to leaving ToJSON for backwards compatibility. Any third party calls to ToJSON should be able to easily change the method being called.
Example data race (which is no longer reproducible with this change):
```
==================
WARNING: DATA RACE
Read at 0x00c0004a4870 by goroutine 131:
reflect.Value.Bool()
/opt/homebrew/Cellar/go/1.20.1/libexec/src/reflect/value.go:288 +0x7c
encoding/json.boolEncoder()
/opt/homebrew/Cellar/go/1.20.1/libexec/src/encoding/json/encode.go:539 +0x88
encoding/json.structEncoder.encode()
/opt/homebrew/Cellar/go/1.20.1/libexec/src/encoding/json/encode.go:759 +0x1bc
encoding/json.structEncoder.encode-fm()
<autogenerated>:1 +0x94
encoding/json.structEncoder.encode()
/opt/homebrew/Cellar/go/1.20.1/libexec/src/encoding/json/encode.go:759 +0x1bc
encoding/json.structEncoder.encode-fm()
<autogenerated>:1 +0x94
encoding/json.ptrEncoder.encode()
/opt/homebrew/Cellar/go/1.20.1/libexec/src/encoding/json/encode.go:943 +0x2a4
encoding/json.ptrEncoder.encode-fm()
<autogenerated>:1 +0x6c
encoding/json.(*encodeState).reflectValue()
/opt/homebrew/Cellar/go/1.20.1/libexec/src/encoding/json/encode.go:358 +0x74
encoding/json.(*encodeState).marshal()
/opt/homebrew/Cellar/go/1.20.1/libexec/src/encoding/json/encode.go:330 +0x1a0
encoding/json.Marshal()
/opt/homebrew/Cellar/go/1.20.1/libexec/src/encoding/json/encode.go:161 +0xa0
github.com/rs/zerolog.init.1.func1()
/Users/hh/go/pkg/mod/github.com/rs/zerolog@v1.29.0/encoder_json.go:21 +0x4c
github.com/rs/zerolog/internal/json.Encoder.AppendInterface()
/Users/hh/go/pkg/mod/github.com/rs/zerolog@v1.29.0/internal/json/types.go:366 +0x5c
github.com/rs/zerolog.appendFieldList()
/Users/hh/go/pkg/mod/github.com/rs/zerolog@v1.29.0/fields.go:273 +0x2b8c
github.com/rs/zerolog.appendFields()
/Users/hh/go/pkg/mod/github.com/rs/zerolog@v1.29.0/fields.go:21 +0x160
github.com/rs/zerolog.(*Event).Fields()
/Users/hh/go/pkg/mod/github.com/rs/zerolog@v1.29.0/event.go:165 +0x90
cosmossdk.io/log.zeroLogWrapper.Debug()
/Users/hh/go/pkg/mod/cosmossdk.io/log@v0.0.0-20230313123454-0fe816b71a62/logger.go:89 +0x18
github.com/cosmos/cosmos-sdk/server/log.(*CometZeroLogWrapper).Debug()
<autogenerated>:1 +0x74
github.com/cometbft/cometbft/consensus.(*PeerState).PickSendVote()
/Users/hh/go/src/github.com/cometbft/cometbft/consensus/reactor.go:1138 +0x1bc
github.com/cometbft/cometbft/consensus.(*Reactor).gossipVotesForHeight()
/Users/hh/go/src/github.com/cometbft/cometbft/consensus/reactor.go:794 +0x260
github.com/cometbft/cometbft/consensus.(*Reactor).gossipVotesRoutine()
/Users/hh/go/src/github.com/cometbft/cometbft/consensus/reactor.go:724 +0x2cc
github.com/cometbft/cometbft/consensus.(*Reactor).AddPeer.func2()
/Users/hh/go/src/github.com/cometbft/cometbft/consensus/reactor.go:199 +0x58
Previous write at 0x00c0004a4870 by goroutine 130:
github.com/cometbft/cometbft/consensus.(*PeerState).SetHasProposal()
/Users/hh/go/src/github.com/cometbft/cometbft/consensus/reactor.go:1096 +0x118
github.com/cometbft/cometbft/consensus.(*Reactor).gossipDataRoutine()
/Users/hh/go/src/github.com/cometbft/cometbft/consensus/reactor.go:617 +0xab8
github.com/cometbft/cometbft/consensus.(*Reactor).AddPeer.func1()
/Users/hh/go/src/github.com/cometbft/cometbft/consensus/reactor.go:198 +0x58
Goroutine 131 (running) created at:
github.com/cometbft/cometbft/consensus.(*Reactor).AddPeer()
/Users/hh/go/src/github.com/cometbft/cometbft/consensus/reactor.go:199 +0x240
github.com/cometbft/cometbft/p2p.(*Switch).addPeer()
/Users/hh/go/src/github.com/cometbft/cometbft/p2p/switch.go:855 +0x7b4
github.com/cometbft/cometbft/p2p.(*Switch).acceptRoutine()
/Users/hh/go/src/github.com/cometbft/cometbft/p2p/switch.go:707 +0x704
github.com/cometbft/cometbft/p2p.(*Switch).OnStart.func1()
/Users/hh/go/src/github.com/cometbft/cometbft/p2p/switch.go:241 +0x34
Goroutine 130 (running) created at:
github.com/cometbft/cometbft/consensus.(*Reactor).AddPeer()
/Users/hh/go/src/github.com/cometbft/cometbft/consensus/reactor.go:198 +0x164
github.com/cometbft/cometbft/p2p.(*Switch).addPeer()
/Users/hh/go/src/github.com/cometbft/cometbft/p2p/switch.go:855 +0x7b4
github.com/cometbft/cometbft/p2p.(*Switch).acceptRoutine()
/Users/hh/go/src/github.com/cometbft/cometbft/p2p/switch.go:707 +0x704
github.com/cometbft/cometbft/p2p.(*Switch).OnStart.func1()
/Users/hh/go/src/github.com/cometbft/cometbft/p2p/switch.go:241 +0x34
==================
```
---
#### PR checklist
- [ ] Tests written/updated
- [x] Changelog entry added in `.changelog` (we use [unclog](https://github.com/informalsystems/unclog) to manage our changelog)
- [ ] Updated relevant documentation (`docs/` or `spec/`) and code comments
(cherry picked from commit 587bc0b)
thanethomson
approved these changes
Mar 15, 2023
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is an automatic backport of pull request #524 done by Mergify.
Mergify commands and options
More conditions and actions can be found in the documentation.
You can also trigger Mergify actions by commenting on this pull request:
@Mergifyio refreshwill re-evaluate the rules@Mergifyio rebasewill rebase this PR on its base branch@Mergifyio updatewill merge the base branch into this PR@Mergifyio backport <destination>will backport this PR on<destination>branchAdditionally, on Mergify dashboard you can:
Finally, you can contact us on https://mergify.com