mirror of
https://github.com/tendermint/tendermint.git
synced 2026-07-20 06:52:30 +00:00
Merge pull request #1446 from tendermint/1442-data-race-fix-attempt
fix data race
This commit is contained in:
+15
-5
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/tendermint/go-amino"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
|
||||
@@ -838,8 +838,8 @@ var (
|
||||
ErrPeerStateInvalidStartTime = errors.New("Error peer state invalid startTime")
|
||||
)
|
||||
|
||||
// PeerState contains the known state of a peer, including its connection
|
||||
// and threadsafe access to its PeerRoundState.
|
||||
// PeerState contains the known state of a peer, including its connection and
|
||||
// threadsafe access to its PeerRoundState.
|
||||
type PeerState struct {
|
||||
Peer p2p.Peer
|
||||
logger log.Logger
|
||||
@@ -878,12 +878,14 @@ func NewPeerState(peer p2p.Peer) *PeerState {
|
||||
}
|
||||
}
|
||||
|
||||
// SetLogger allows to set a logger on the peer state. Returns the peer state
|
||||
// itself.
|
||||
func (ps *PeerState) SetLogger(logger log.Logger) *PeerState {
|
||||
ps.logger = logger
|
||||
return ps
|
||||
}
|
||||
|
||||
// GetRoundState returns an atomic snapshot of the PeerRoundState.
|
||||
// GetRoundState returns an shallow copy of the PeerRoundState.
|
||||
// There's no point in mutating it since it won't change PeerState.
|
||||
func (ps *PeerState) GetRoundState() *cstypes.PeerRoundState {
|
||||
ps.mtx.Lock()
|
||||
@@ -893,6 +895,14 @@ func (ps *PeerState) GetRoundState() *cstypes.PeerRoundState {
|
||||
return &prs
|
||||
}
|
||||
|
||||
// GetRoundStateJSON returns a json of PeerRoundState, marshalled using go-amino.
|
||||
func (ps *PeerState) GetRoundStateJSON() ([]byte, error) {
|
||||
ps.mtx.Lock()
|
||||
defer ps.mtx.Unlock()
|
||||
|
||||
return cdc.MarshalJSON(ps.PeerRoundState)
|
||||
}
|
||||
|
||||
// GetHeight returns an atomic snapshot of the PeerRoundState's height
|
||||
// used by the mempool to ensure peers are caught up before broadcasting new txs
|
||||
func (ps *PeerState) GetHeight() int64 {
|
||||
@@ -1055,7 +1065,7 @@ func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numValida
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureVoteVitArrays ensures the bit-arrays have been allocated for tracking
|
||||
// EnsureVoteBitArrays ensures the bit-arrays have been allocated for tracking
|
||||
// what votes this peer has received.
|
||||
// NOTE: It's important to make sure that numValidators actually matches
|
||||
// what the node sees as the number of validators for height.
|
||||
|
||||
+9
-4
@@ -168,18 +168,23 @@ func (cs *ConsensusState) GetState() sm.State {
|
||||
return cs.state.Copy()
|
||||
}
|
||||
|
||||
// GetRoundState returns a copy of the internal consensus state.
|
||||
// GetRoundState returns a shallow copy of the internal consensus state.
|
||||
func (cs *ConsensusState) GetRoundState() *cstypes.RoundState {
|
||||
cs.mtx.Lock()
|
||||
defer cs.mtx.Unlock()
|
||||
return cs.getRoundState()
|
||||
}
|
||||
|
||||
func (cs *ConsensusState) getRoundState() *cstypes.RoundState {
|
||||
rs := cs.RoundState // copy
|
||||
return &rs
|
||||
}
|
||||
|
||||
// GetRoundStateJSON returns a json of RoundState, marshalled using go-amino.
|
||||
func (cs *ConsensusState) GetRoundStateJSON() ([]byte, error) {
|
||||
cs.mtx.Lock()
|
||||
defer cs.mtx.Unlock()
|
||||
|
||||
return cdc.MarshalJSON(cs.RoundState)
|
||||
}
|
||||
|
||||
// GetValidators returns a copy of the current validators.
|
||||
func (cs *ConsensusState) GetValidators() (int64, []*types.Validator) {
|
||||
cs.mtx.Lock()
|
||||
|
||||
@@ -52,9 +52,6 @@ func (rs RoundStepType) String() string {
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// RoundState defines the internal consensus state.
|
||||
// It is Immutable when returned from ConsensusState.GetRoundState()
|
||||
// TODO: Actually, only the top pointer is copied,
|
||||
// so access to field pointers is still racey
|
||||
// NOTE: Not thread safe. Should only be manipulated by functions downstream
|
||||
// of the cs.receiveRoutine
|
||||
type RoundState struct {
|
||||
|
||||
+13
-5
@@ -1,8 +1,9 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
cm "github.com/tendermint/tendermint/consensus"
|
||||
cstypes "github.com/tendermint/tendermint/consensus/types"
|
||||
p2p "github.com/tendermint/tendermint/p2p"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
@@ -58,7 +59,7 @@ func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
|
||||
return &ctypes.ResultValidators{height, validators.Validators}, nil
|
||||
}
|
||||
|
||||
// Dump consensus state.
|
||||
// DumpConsensusState dumps consensus state.
|
||||
//
|
||||
// ```shell
|
||||
// curl 'localhost:46657/dump_consensus_state'
|
||||
@@ -83,11 +84,18 @@ func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
|
||||
// }
|
||||
// ```
|
||||
func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
|
||||
peerRoundStates := make(map[p2p.ID]*cstypes.PeerRoundState)
|
||||
peerRoundStates := make(map[p2p.ID]json.RawMessage)
|
||||
for _, peer := range p2pSwitch.Peers().List() {
|
||||
peerState := peer.Get(types.PeerStateKey).(*cm.PeerState)
|
||||
peerRoundState := peerState.GetRoundState()
|
||||
peerRoundState, err := peerState.GetRoundStateJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
peerRoundStates[peer.ID()] = peerRoundState
|
||||
}
|
||||
return &ctypes.ResultDumpConsensusState{consensusState.GetRoundState(), peerRoundStates}, nil
|
||||
roundState, err := consensusState.GetRoundStateJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ctypes.ResultDumpConsensusState{roundState, peerRoundStates}, nil
|
||||
}
|
||||
|
||||
+2
-3
@@ -3,9 +3,8 @@ package core
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/go-crypto"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/tendermint/consensus"
|
||||
cstypes "github.com/tendermint/tendermint/consensus/types"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
@@ -23,7 +22,7 @@ var subscribeTimeout = 5 * time.Second
|
||||
type Consensus interface {
|
||||
GetState() sm.State
|
||||
GetValidators() (int64, []*types.Validator)
|
||||
GetRoundState() *cstypes.RoundState
|
||||
GetRoundStateJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
type P2P interface {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package core_types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -8,7 +9,6 @@ import (
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
|
||||
cstypes "github.com/tendermint/tendermint/consensus/types"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -109,8 +109,8 @@ type ResultValidators struct {
|
||||
}
|
||||
|
||||
type ResultDumpConsensusState struct {
|
||||
RoundState *cstypes.RoundState `json:"round_state"`
|
||||
PeerRoundStates map[p2p.ID]*cstypes.PeerRoundState `json:"peer_round_states"`
|
||||
RoundState json.RawMessage `json:"round_state"`
|
||||
PeerRoundStates map[p2p.ID]json.RawMessage `json:"peer_round_states"`
|
||||
}
|
||||
|
||||
type ResultBroadcastTx struct {
|
||||
|
||||
Reference in New Issue
Block a user