Commit e059219f authored by caopingcp's avatar caopingcp Committed by vipwzw

Query function avoid deadlock

parent aa3cc58a
......@@ -9,7 +9,6 @@ import (
"errors"
"fmt"
"runtime/debug"
"sync"
"sync/atomic"
"time"
......@@ -17,6 +16,7 @@ import (
"github.com/33cn/chain33/types"
ttypes "github.com/33cn/plugin/plugin/consensus/qbft/types"
tmtypes "github.com/33cn/plugin/plugin/dapp/qbftNode/types"
siasync "github.com/NebulousLabs/Sia/sync"
)
//-----------------------------------------------------------------------------
......@@ -67,7 +67,7 @@ type ConsensusState struct {
blockExec *BlockExecutor
// internal state
mtx sync.Mutex
mtx siasync.TryMutex
ttypes.RoundState
state State // QbftState until height-1.
......@@ -145,6 +145,34 @@ func (cs *ConsensusState) IsRunning() bool {
//----------------------------------------
// QueryState returns a copy of the chain state.
func (cs *ConsensusState) QueryState() *State {
if cs == nil {
return nil
}
if !cs.mtx.TryLockTimed(time.Millisecond * 500) {
return nil
}
defer cs.mtx.Unlock()
state := cs.state.Copy()
return &state
}
// QueryRoundState returns a copy of the internal consensus state.
func (cs *ConsensusState) QueryRoundState() *ttypes.RoundState {
if cs == nil {
return nil
}
if !cs.mtx.TryLockTimed(time.Millisecond * 500) {
return nil
}
defer cs.mtx.Unlock()
rs := cs.RoundState
return &rs
}
// GetState returns a copy of the chain state.
func (cs *ConsensusState) GetState() State {
cs.mtx.Lock()
......
......@@ -18,7 +18,6 @@ import (
"time"
"github.com/33cn/chain33/types"
ttypes "github.com/33cn/plugin/plugin/consensus/qbft/types"
tmtypes "github.com/33cn/plugin/plugin/dapp/qbftNode/types"
"github.com/golang/protobuf/proto"
......
......@@ -26,7 +26,7 @@ import (
)
const (
qbftVersion = "0.1.0"
qbftVersion = "0.2.0"
// DefaultQbftPort 默认端口
DefaultQbftPort = 33001
......@@ -665,26 +665,31 @@ func (client *Client) LoadProposalBlock(height int64) *tmtypes.QbftBlock {
// Query_IsHealthy query whether consensus is sync
func (client *Client) Query_IsHealthy(req *types.ReqNil) (types.Message, error) {
isHealthy := false
if client.IsCaughtUp() && client.GetCurrentHeight() <= client.csState.GetRoundState().Height+1 {
isHealthy = true
if client.IsCaughtUp() {
rs := client.csState.QueryRoundState()
if rs != nil && client.GetCurrentHeight() <= rs.Height+1 {
isHealthy = true
}
}
return &tmtypes.QbftIsHealthy{IsHealthy: isHealthy}, nil
}
// Query_CurrentState query current consensus state
func (client *Client) Query_CurrentState(req *types.ReqNil) (types.Message, error) {
if client.csState == nil {
return nil, ttypes.ErrConsensusState
state := client.csState.QueryState()
if state == nil {
return nil, ttypes.ErrConsensusQuery
}
return SaveState(client.csState.GetState()), nil
return SaveState(*state), nil
}
// Query_NodeInfo query validator node info
func (client *Client) Query_NodeInfo(req *types.ReqNil) (types.Message, error) {
if client.csState == nil {
return nil, ttypes.ErrConsensusState
rs := client.csState.QueryRoundState()
if rs == nil {
return nil, ttypes.ErrConsensusQuery
}
vals := client.csState.GetRoundState().Validators.Validators
vals := rs.Validators.Validators
nodes := make([]*tmtypes.QbftNodeInfo, 0)
for _, val := range vals {
if val == nil {
......
......@@ -29,7 +29,7 @@ var (
// ErrLastBlockID error type
ErrLastBlockID = errors.New("ErrLastBlockID")
// ErrConsensusState error type
ErrConsensusState = errors.New("ErrConsensusState")
ErrConsensusQuery = errors.New("Consensus is busy, please try again!")
)
var (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment