Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(types): abci valset update abci does not need a public key on replay #786

Merged
merged 4 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions internal/consensus/replayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ func (r *BlockReplayer) execInitChain(ctx context.Context, rs *replayState, stat
return nil
}
stateBlockHeight := state.LastBlockHeight
nextVals, err := validatorSetUpdateFromGenesis(r.genDoc, r.nodeProTxHash)
nextVals, err := validatorSetUpdateFromGenesis(r.genDoc)
if err != nil {
return err
}
Expand Down Expand Up @@ -382,7 +382,7 @@ func (r *BlockReplayer) publishEvents(
return nil
}

func validatorSetUpdateFromGenesis(genDoc *types.GenesisDoc, nodeProTxHash types.ProTxHash) (*abci.ValidatorSetUpdate, error) {
func validatorSetUpdateFromGenesis(genDoc *types.GenesisDoc) (*abci.ValidatorSetUpdate, error) {
if len(genDoc.QuorumHash) != crypto.DefaultHashSize {
return nil, nil
}
Expand All @@ -394,12 +394,11 @@ func validatorSetUpdateFromGenesis(genDoc *types.GenesisDoc, nodeProTxHash types
return nil, fmt.Errorf("blockReplayer blocks error when validating validator: %s", err)
}
}
validatorSet := types.NewValidatorSetWithLocalNodeProTxHash(
validatorSet := types.NewValidatorSetCheckPublicKeys(
validators,
genDoc.ThresholdPublicKey,
genDoc.QuorumType,
genDoc.QuorumHash,
nodeProTxHash,
)
err := validatorSet.ValidateBasic()
if err != nil {
Expand Down
7 changes: 3 additions & 4 deletions internal/state/current_round_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func (candidate *CurrentRoundState) populateValsetUpdates() error {

base := candidate.Base

newValSet, err := valsetUpdate(candidate.ProTxHash, update, base.Validators, candidate.NextConsensusParams.Validator)
newValSet, err := valsetUpdate(update, base.Validators, candidate.NextConsensusParams.Validator)
if err != nil {
return fmt.Errorf("validator set updates: %w", err)
}
Expand Down Expand Up @@ -313,7 +313,6 @@ func RoundParamsFromInitChain(resp *abci.ResponseInitChain) (RoundParams, error)

// valsetUpdate processes validator set updates received from ABCI app.
func valsetUpdate(
nodeProTxHash types.ProTxHash,
vu *abci.ValidatorSetUpdate,
currentVals *types.ValidatorSet,
params types.ValidatorParams,
Expand All @@ -339,8 +338,8 @@ func valsetUpdate(
}
} else {
// if we don't have proTxHash, NewValidatorSetWithLocalNodeProTxHash behaves like NewValidatorSet
nValSet = types.NewValidatorSetWithLocalNodeProTxHash(validatorUpdates, thresholdPubKey,
currentVals.QuorumType, quorumHash, nodeProTxHash)
nValSet = types.NewValidatorSetCheckPublicKeys(validatorUpdates, thresholdPubKey,
currentVals.QuorumType, quorumHash)
}
} else {
// validators not changed, but we might have a new quorum hash or threshold public key
Expand Down
11 changes: 10 additions & 1 deletion types/protobuf.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,21 @@ func (pb2tm) ValidatorSetFromProtoUpdate(
valSetUpdate *abci.ValidatorSetUpdate,
) (*ValidatorSet, error) {
hasPublicKeys := true
for _, v := range valSetUpdate.ValidatorUpdates {
for i, v := range valSetUpdate.ValidatorUpdates {
if v.PubKey == nil {
hasPublicKeys = false
break
}

pubkey, err := cryptoenc.PubKeyFromProto(*v.PubKey)
if err != nil {
return nil, fmt.Errorf("invalid pubkey of validator %d (%x) in valset update: %w", i, v.ProTxHash, err)
}
if len(pubkey.Bytes()) == 0 {
return nil, fmt.Errorf("pubkey of validator %d (%x) in valset update has zero length", i, v.ProTxHash)
}
}

tmVals, pub, quorumHash, err := PB2TM.ValidatorUpdatesFromValidatorSet(valSetUpdate)
if err != nil {
return nil, err
Expand Down
21 changes: 12 additions & 9 deletions types/validator_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,21 @@ func NewValidatorSet(valz []*Validator, newThresholdPublicKey crypto.PubKey, quo
return vals
}

// NewValidatorSetWithLocalNodeProTxHash initializes a ValidatorSet the same way as NewValidatorSet does,
// however it does allows to set the localNodeProTxHash to more easily identify if the validator set should have public
// keys. If the local node is part of the validator set the public keys must be present
func NewValidatorSetWithLocalNodeProTxHash(
// NewValidatorSetCheckPublicKeys initializes a ValidatorSet the same way as NewValidatorSet does,
// but determines if the public keys are present.
func NewValidatorSetCheckPublicKeys(
valz []*Validator,
newThresholdPublicKey crypto.PubKey,
quorumType btcjson.LLMQType,
quorumHash crypto.QuorumHash,
localNodeProTxHash crypto.ProTxHash,
) *ValidatorSet {
vals := NewValidatorSet(valz, newThresholdPublicKey, quorumType, quorumHash, false)
if vals.HasProTxHash(localNodeProTxHash) {
vals.HasPublicKeys = true
hasPublicKeys := true
for _, val := range valz {
if val.PubKey == nil || len(val.PubKey.Bytes()) == 0 {
hasPublicKeys = false
}
}
return vals
return NewValidatorSet(valz, newThresholdPublicKey, quorumType, quorumHash, hasPublicKeys)
}

// NewEmptyValidatorSet initializes a ValidatorSet with no validators
Expand Down Expand Up @@ -199,6 +199,9 @@ func (vals *ValidatorSet) ThresholdPublicKeyValid() error {
return errors.New("threshold public key is wrong size")
}
if len(vals.Validators) == 1 && vals.HasPublicKeys {
if vals.Validators[0].PubKey == nil {
shumkov marked this conversation as resolved.
Show resolved Hide resolved
return errors.New("validator public key is not set")
}
if !vals.Validators[0].PubKey.Equals(vals.ThresholdPublicKey) {
return errors.New("incorrect threshold public key")
}
Expand Down
6 changes: 6 additions & 0 deletions types/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var (
ErrVoteExtensionTypeWrongForRequestID = errors.New("provided vote extension type does not support sign request ID")
ErrVoteInvalidValidatorProTxHash = errors.New("invalid validator pro_tx_hash")
ErrVoteInvalidValidatorPubKeySize = errors.New("invalid validator public key size")
ErrVoteMissingValidatorPubKey = errors.New("missing validator public key")
ErrVoteInvalidBlockSignature = errors.New("invalid block signature")
ErrVoteInvalidStateSignature = errors.New("invalid state signature")
ErrVoteStateSignatureShouldBeNil = errors.New("state signature when voting for nil block")
Expand Down Expand Up @@ -197,6 +198,11 @@ func (vote *Vote) verifyBasic(proTxHash ProTxHash, pubKey crypto.PubKey) error {
if !bytes.Equal(proTxHash, vote.ValidatorProTxHash) {
return ErrVoteInvalidValidatorProTxHash
}

if pubKey == nil {
return ErrVoteMissingValidatorPubKey
}

if len(pubKey.Bytes()) != bls12381.PubKeySize {
return ErrVoteInvalidValidatorPubKeySize
}
Expand Down
Loading