mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-20 23:14:37 +00:00
state/privval: no GetPubKey retry beyond the proposal/voting window (#6578)
Closes #5142
This commit is contained in:
@@ -129,6 +129,7 @@ Friendly reminder: We have a [bug bounty program](https://hackerone.com/tendermi
|
|||||||
- [p2p/pex] \#6509 Improve addrBook.hash performance (@cuonglm)
|
- [p2p/pex] \#6509 Improve addrBook.hash performance (@cuonglm)
|
||||||
- [consensus/metrics] \#6549 Change block_size gauge to a histogram for better observability over time (@marbar3778)
|
- [consensus/metrics] \#6549 Change block_size gauge to a histogram for better observability over time (@marbar3778)
|
||||||
- [statesync] \#6587 Increase chunk priority and re-request chunks that don't arrive (@cmwaters)
|
- [statesync] \#6587 Increase chunk priority and re-request chunks that don't arrive (@cmwaters)
|
||||||
|
- [state/privval] \#6578 No GetPubKey retry beyond the proposal/voting window (@JayT106)
|
||||||
- [rpc] \#6615 Add TotalGasUsed to block_results response (@crypto-facs)
|
- [rpc] \#6615 Add TotalGasUsed to block_results response (@crypto-facs)
|
||||||
|
|
||||||
### BUG FIXES
|
### BUG FIXES
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
tmos "github.com/tendermint/tendermint/libs/os"
|
tmos "github.com/tendermint/tendermint/libs/os"
|
||||||
"github.com/tendermint/tendermint/libs/service"
|
"github.com/tendermint/tendermint/libs/service"
|
||||||
tmtime "github.com/tendermint/tendermint/libs/time"
|
tmtime "github.com/tendermint/tendermint/libs/time"
|
||||||
|
"github.com/tendermint/tendermint/privval"
|
||||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||||
sm "github.com/tendermint/tendermint/state"
|
sm "github.com/tendermint/tendermint/state"
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
@@ -78,8 +79,9 @@ type State struct {
|
|||||||
service.BaseService
|
service.BaseService
|
||||||
|
|
||||||
// config details
|
// config details
|
||||||
config *cfg.ConsensusConfig
|
config *cfg.ConsensusConfig
|
||||||
privValidator types.PrivValidator // for signing votes
|
privValidator types.PrivValidator // for signing votes
|
||||||
|
privValidatorType types.PrivValidatorType
|
||||||
|
|
||||||
// store blocks and commits
|
// store blocks and commits
|
||||||
blockStore sm.BlockStore
|
blockStore sm.BlockStore
|
||||||
@@ -272,6 +274,24 @@ func (cs *State) SetPrivValidator(priv types.PrivValidator) {
|
|||||||
|
|
||||||
cs.privValidator = priv
|
cs.privValidator = priv
|
||||||
|
|
||||||
|
if priv != nil {
|
||||||
|
switch t := priv.(type) {
|
||||||
|
case *privval.RetrySignerClient:
|
||||||
|
cs.privValidatorType = types.RetrySignerClient
|
||||||
|
case *privval.FilePV:
|
||||||
|
cs.privValidatorType = types.FileSignerClient
|
||||||
|
case *privval.SignerClient:
|
||||||
|
cs.privValidatorType = types.SignerClient
|
||||||
|
case types.MockPV:
|
||||||
|
cs.privValidatorType = types.MockSignerClient
|
||||||
|
case *types.ErroringMockPV:
|
||||||
|
cs.privValidatorType = types.ErrorMockSignerClient
|
||||||
|
default:
|
||||||
|
cs.Logger.Error("unsupported priv validator type", "err",
|
||||||
|
fmt.Errorf("error privValidatorType %s", t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := cs.updatePrivValidatorPubKey(); err != nil {
|
if err := cs.updatePrivValidatorPubKey(); err != nil {
|
||||||
cs.Logger.Error("failed to get private validator pubkey", "err", err)
|
cs.Logger.Error("failed to get private validator pubkey", "err", err)
|
||||||
}
|
}
|
||||||
@@ -2267,7 +2287,13 @@ func (cs *State) updatePrivValidatorPubKey() error {
|
|||||||
timeout = cs.config.TimeoutPrevote
|
timeout = cs.config.TimeoutPrevote
|
||||||
}
|
}
|
||||||
|
|
||||||
// set a hard timeout for 2 seconds. This helps in avoiding blocking of the remote signer connection
|
// no GetPubKey retry beyond the proposal/voting in RetrySignerClient
|
||||||
|
if cs.Step >= cstypes.RoundStepPrecommit && cs.privValidatorType == types.RetrySignerClient {
|
||||||
|
timeout = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// set context timeout depending on the configuration and the State step,
|
||||||
|
// this helps in avoiding blocking of the remote signer connection.
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
|
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
pubKey, err := cs.privValidator.GetPubKey(ctx)
|
pubKey, err := cs.privValidator.GetPubKey(ctx)
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ func (sc *RetrySignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, erro
|
|||||||
pk crypto.PubKey
|
pk crypto.PubKey
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
t := time.NewTimer(sc.timeout)
|
||||||
for i := 0; i < sc.retries || sc.retries == 0; i++ {
|
for i := 0; i < sc.retries || sc.retries == 0; i++ {
|
||||||
pk, err = sc.next.GetPubKey(ctx)
|
pk, err = sc.next.GetPubKey(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -59,7 +61,12 @@ func (sc *RetrySignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, erro
|
|||||||
if _, ok := err.(*RemoteSignerError); ok {
|
if _, ok := err.(*RemoteSignerError); ok {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
time.Sleep(sc.timeout)
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
case <-t.C:
|
||||||
|
t.Reset(sc.timeout)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("exhausted all attempts to get pubkey: %w", err)
|
return nil, fmt.Errorf("exhausted all attempts to get pubkey: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,17 @@ import (
|
|||||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PrivValidatorType defines the implemtation types.
|
||||||
|
type PrivValidatorType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
MockSignerClient = PrivValidatorType(0x00) // mock singer
|
||||||
|
FileSignerClient = PrivValidatorType(0x01) // singer client via file
|
||||||
|
RetrySignerClient = PrivValidatorType(0x02) // singer client via socket
|
||||||
|
SignerClient = PrivValidatorType(0x03) // singer client via gRPC
|
||||||
|
ErrorMockSignerClient = PrivValidatorType(0x04) // error mock singer
|
||||||
|
)
|
||||||
|
|
||||||
// PrivValidator defines the functionality of a local Tendermint validator
|
// PrivValidator defines the functionality of a local Tendermint validator
|
||||||
// that signs votes and proposals, and never double signs.
|
// that signs votes and proposals, and never double signs.
|
||||||
type PrivValidator interface {
|
type PrivValidator interface {
|
||||||
|
|||||||
Reference in New Issue
Block a user