Skip to content

Commit

Permalink
check verifying pubkey against validator address
Browse files Browse the repository at this point in the history
  • Loading branch information
sainoe committed Oct 13, 2023
1 parent 28e0c14 commit 9f23165
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 9 deletions.
36 changes: 36 additions & 0 deletions testutil/crypto/evidence.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,39 @@ func MakeAndSignVote(
vote.Signature = v.Signature
return vote
}

// MakeAndSignVoteWithForgedValAddress makes and signs a vote using two different keys:
// one to derive the validator address in the vote and a second to sign it.
func MakeAndSignVoteWithForgedValAddress(
blockID tmtypes.BlockID,
blockHeight int64,
blockTime time.Time,
valSet *tmtypes.ValidatorSet,
signer tmtypes.PrivValidator,
chainID string,
) *tmtypes.Vote {

// create the vote using a different key than the signing key
forgedSigner := tmtypes.NewMockPV()
vote, err := tmtypes.MakeVote(
blockHeight,
blockID,
valSet,
forgedSigner,
chainID,
blockTime,
)
if err != nil {
panic(err)
}

// sign vote using the given private key
v := vote.ToProto()
err = signer.SignVote(chainID, v)
if err != nil {
panic(err)
}

vote.Signature = v.Signature
return vote
}
5 changes: 0 additions & 5 deletions x/ccv/provider/client/proposal_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,9 +439,4 @@ func postConsumerRemovalProposalHandlerFn(clientCtx client.Context) http.Handler
tx.WriteGeneratedTxResponse(clientCtx, w, req.BaseReq, msg)
}
}
func CheckPropUnbondingPeriod(clientCtx client.Context, propUnbondingPeriod time.Duration) {
queryClient := stakingtypes.NewQueryClient(clientCtx)
*/
9 changes: 9 additions & 0 deletions x/ccv/provider/keeper/double_vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ func (k Keeper) VerifyDoubleVotingEvidence(
return fmt.Errorf("validator public key cannot be empty")
}

// check that the validator address in the evidence is derived from the provided public key
if !bytes.Equal(pubkey.Address(), evidence.VoteA.ValidatorAddress) {
return errorsmod.Wrapf(
ccvtypes.ErrInvalidDoubleVotingEvidence,
"public key %s doesn't correspond to the validator address %s in double vote evidence",
pubkey.String(), evidence.VoteA.ValidatorAddress.String(),
)
}

// Note that since we're only jailing validators for double voting on a consumer chain,
// the age of the evidence is irrelevant and therefore isn't checked.

Expand Down
24 changes: 24 additions & 0 deletions x/ccv/provider/keeper/double_vote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,30 @@ func TestVerifyDoubleVotingEvidence(t *testing.T) {
pubkey cryptotypes.PubKey
expPass bool
}{
{
"verifying public key doesn't correspond to validator address",
[]*tmtypes.Vote{
testutil.MakeAndSignVoteWithForgedValAddress(
blockID1,
ctx.BlockHeight(),
ctx.BlockTime(),
valSet,
signer1,
chainID,
),
testutil.MakeAndSignVoteWithForgedValAddress(
blockID2,
ctx.BlockHeight(),
ctx.BlockTime(),
valSet,
signer1,
chainID,
),
},
chainID,
valPubkey1,
false,
},
{
"evidence has votes with different block height - shouldn't pass",
[]*tmtypes.Vote{
Expand Down
6 changes: 2 additions & 4 deletions x/ccv/provider/keeper/punish_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ func (k Keeper) JailAndTombstoneValidator(ctx sdk.Context, providerAddr types.Pr
k.stakingKeeper.Jail(ctx, providerAddr.ToSdkConsAddr())
}

// Jail the validator to trigger the unbonding of the validator
// (see cosmos/cosmos-sdk/blob/v0.45.16-ics-lsm/x/staking/keeper/val_state_change.go#L192).
k.slashingKeeper.JailUntil(ctx, providerAddr.ToSdkConsAddr(), evidencetypes.DoubleSignJailEndTime)

// Tombstone the validator so that we cannot slash the validator more than once
Expand Down Expand Up @@ -85,12 +83,12 @@ func (k Keeper) SlashValidator(ctx sdk.Context, providerAddr types.ProviderConsA
return errorsmod.Wrapf(slashingtypes.ErrNoValidatorForAddress, "provider consensus address: %s", providerAddr.String())
}

// check if the validator is unbonded to prevent panicking when slashing (see cosmos/cosmos-sdk/blob/v0.47.5/x/staking/keeper/slash.go#L61)
// check if the validator is unbonded to prevent panicking when slashing (see cosmos/cosmos-sdk/blob/v0.47.5/x/staking/keeper/slash.go#L61)
if validator.IsUnbonded() {
return fmt.Errorf("validator is unbonded. provider consensus address: %s", providerAddr.String())
}

// check if the validator is already tombstoned to avoid slashing a validator more than once
// check if the validator is already tombstoned to avoid slashing a validator more than once
if k.slashingKeeper.IsTombstoned(ctx, providerAddr.ToSdkConsAddr()) {
return fmt.Errorf("validator is tombstoned. provider consensus address: %s", providerAddr.String())
}
Expand Down

0 comments on commit 9f23165

Please sign in to comment.