mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-04 07:07:13 +00:00
test: create common functions for easily producing tm data structures (#6435)
This commit is contained in:
+2
-2
@@ -1196,10 +1196,10 @@ func (blockID BlockID) Key() string {
|
||||
func (blockID BlockID) ValidateBasic() error {
|
||||
// Hash can be empty in case of POLBlockID in Proposal.
|
||||
if err := ValidateHash(blockID.Hash); err != nil {
|
||||
return fmt.Errorf("wrong Hash")
|
||||
return fmt.Errorf("wrong Hash: %w", err)
|
||||
}
|
||||
if err := blockID.PartSetHeader.ValidateBasic(); err != nil {
|
||||
return fmt.Errorf("wrong PartSetHeader: %v", err)
|
||||
return fmt.Errorf("wrong PartSetHeader: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+7
-7
@@ -40,7 +40,7 @@ func TestBlockAddEvidence(t *testing.T) {
|
||||
h := int64(3)
|
||||
|
||||
voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
|
||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
require.NoError(t, err)
|
||||
|
||||
ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain")
|
||||
@@ -60,7 +60,7 @@ func TestBlockValidateBasic(t *testing.T) {
|
||||
h := int64(3)
|
||||
|
||||
voteSet, valSet, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
|
||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
require.NoError(t, err)
|
||||
|
||||
ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain")
|
||||
@@ -137,7 +137,7 @@ func TestBlockMakePartSetWithEvidence(t *testing.T) {
|
||||
h := int64(3)
|
||||
|
||||
voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
|
||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
require.NoError(t, err)
|
||||
|
||||
ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain")
|
||||
@@ -154,7 +154,7 @@ func TestBlockHashesTo(t *testing.T) {
|
||||
lastID := makeBlockIDRandom()
|
||||
h := int64(3)
|
||||
voteSet, valSet, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
|
||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
require.NoError(t, err)
|
||||
|
||||
ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain")
|
||||
@@ -232,7 +232,7 @@ func TestCommit(t *testing.T) {
|
||||
lastID := makeBlockIDRandom()
|
||||
h := int64(3)
|
||||
voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
|
||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, h-1, commit.Height)
|
||||
@@ -444,7 +444,7 @@ func randCommit(now time.Time) *Commit {
|
||||
lastID := makeBlockIDRandom()
|
||||
h := int64(3)
|
||||
voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
|
||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, now)
|
||||
commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, now)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -525,7 +525,7 @@ func TestCommitToVoteSet(t *testing.T) {
|
||||
h := int64(3)
|
||||
|
||||
voteSet, valSet, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
|
||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
|
||||
assert.NoError(t, err)
|
||||
|
||||
chainID := voteSet.ChainID()
|
||||
|
||||
@@ -98,7 +98,7 @@ func TestLightClientAttackEvidenceBasic(t *testing.T) {
|
||||
header := makeHeaderRandom()
|
||||
header.Height = height
|
||||
blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
|
||||
commit, err := MakeCommit(blockID, height, 1, voteSet, privVals, defaultVoteTime)
|
||||
commit, err := makeCommit(blockID, height, 1, voteSet, privVals, defaultVoteTime)
|
||||
require.NoError(t, err)
|
||||
lcae := &LightClientAttackEvidence{
|
||||
ConflictingBlock: &LightBlock{
|
||||
@@ -158,7 +158,7 @@ func TestLightClientAttackEvidenceValidation(t *testing.T) {
|
||||
header.Height = height
|
||||
header.ValidatorsHash = valSet.Hash()
|
||||
blockID := makeBlockID(header.Hash(), math.MaxInt32, tmhash.Sum([]byte("partshash")))
|
||||
commit, err := MakeCommit(blockID, height, 1, voteSet, privVals, time.Now())
|
||||
commit, err := makeCommit(blockID, height, 1, voteSet, privVals, time.Now())
|
||||
require.NoError(t, err)
|
||||
lcae := &LightClientAttackEvidence{
|
||||
ConflictingBlock: &LightBlock{
|
||||
|
||||
+3
-3
@@ -14,12 +14,12 @@ import (
|
||||
func TestLightBlockValidateBasic(t *testing.T) {
|
||||
header := makeRandHeader()
|
||||
commit := randCommit(time.Now())
|
||||
vals, _ := RandValidatorSet(5, 1)
|
||||
vals, _ := randValidatorPrivValSet(5, 1)
|
||||
header.Height = commit.Height
|
||||
header.LastBlockID = commit.BlockID
|
||||
header.ValidatorsHash = vals.Hash()
|
||||
header.Version.Block = version.BlockProtocol
|
||||
vals2, _ := RandValidatorSet(3, 1)
|
||||
vals2, _ := randValidatorPrivValSet(3, 1)
|
||||
vals3 := vals.Copy()
|
||||
vals3.Proposer = &Validator{}
|
||||
commit.BlockID.Hash = header.Hash()
|
||||
@@ -59,7 +59,7 @@ func TestLightBlockValidateBasic(t *testing.T) {
|
||||
func TestLightBlockProtobuf(t *testing.T) {
|
||||
header := makeRandHeader()
|
||||
commit := randCommit(time.Now())
|
||||
vals, _ := RandValidatorSet(5, 1)
|
||||
vals, _ := randValidatorPrivValSet(5, 1)
|
||||
header.Height = commit.Height
|
||||
header.LastBlockID = commit.BlockID
|
||||
header.Version.Block = version.BlockProtocol
|
||||
|
||||
+1
-35
@@ -8,7 +8,7 @@ import (
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
)
|
||||
|
||||
func MakeCommit(blockID BlockID, height int64, round int32,
|
||||
func makeCommit(blockID BlockID, height int64, round int32,
|
||||
voteSet *VoteSet, validators []PrivValidator, now time.Time) (*Commit, error) {
|
||||
|
||||
// all sign
|
||||
@@ -45,37 +45,3 @@ func signAddVote(privVal PrivValidator, vote *Vote, voteSet *VoteSet) (signed bo
|
||||
vote.Signature = v.Signature
|
||||
return voteSet.AddVote(vote)
|
||||
}
|
||||
|
||||
func MakeVote(
|
||||
height int64,
|
||||
blockID BlockID,
|
||||
valSet *ValidatorSet,
|
||||
privVal PrivValidator,
|
||||
chainID string,
|
||||
now time.Time,
|
||||
) (*Vote, error) {
|
||||
pubKey, err := privVal.GetPubKey(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get pubkey: %w", err)
|
||||
}
|
||||
addr := pubKey.Address()
|
||||
idx, _ := valSet.GetByAddress(addr)
|
||||
vote := &Vote{
|
||||
ValidatorAddress: addr,
|
||||
ValidatorIndex: idx,
|
||||
Height: height,
|
||||
Round: 0,
|
||||
Timestamp: now,
|
||||
Type: tmproto.PrecommitType,
|
||||
BlockID: blockID,
|
||||
}
|
||||
v := vote.ToProto()
|
||||
|
||||
if err := privVal.SignVote(context.Background(), chainID, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vote.Signature = v.Signature
|
||||
|
||||
return vote, nil
|
||||
}
|
||||
|
||||
@@ -2,10 +2,8 @@ package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
mrand "math/rand"
|
||||
"strings"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
@@ -173,23 +171,3 @@ func ValidatorFromProto(vp *tmproto.Validator) (*Validator, error) {
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// RandValidator
|
||||
|
||||
// RandValidator returns a randomized validator, useful for testing.
|
||||
// UNSTABLE
|
||||
func RandValidator(randPower bool, minPower int64) (*Validator, PrivValidator) {
|
||||
privVal := NewMockPV()
|
||||
votePower := minPower
|
||||
if randPower {
|
||||
// nolint:gosec // G404: Use of weak random number generator
|
||||
votePower += int64(mrand.Uint32())
|
||||
}
|
||||
pubKey, err := privVal.GetPubKey(context.Background())
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("could not retrieve pubkey %w", err))
|
||||
}
|
||||
val := NewValidator(pubKey, votePower)
|
||||
return val, privVal
|
||||
}
|
||||
|
||||
@@ -1097,27 +1097,6 @@ func ValidatorSetFromExistingValidators(valz []*Validator) (*ValidatorSet, error
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// RandValidatorSet returns a randomized validator set (size: +numValidators+),
|
||||
// where each validator has a voting power of +votingPower+.
|
||||
//
|
||||
// EXPOSED FOR TESTING.
|
||||
func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []PrivValidator) {
|
||||
var (
|
||||
valz = make([]*Validator, numValidators)
|
||||
privValidators = make([]PrivValidator, numValidators)
|
||||
)
|
||||
|
||||
for i := 0; i < numValidators; i++ {
|
||||
val, privValidator := RandValidator(false, votingPower)
|
||||
valz[i] = val
|
||||
privValidators[i] = privValidator
|
||||
}
|
||||
|
||||
sort.Sort(PrivValidatorsByAddress(privValidators))
|
||||
|
||||
return NewValidatorSet(valz), privValidators
|
||||
}
|
||||
|
||||
// safe addition/subtraction/multiplication
|
||||
|
||||
func safeAdd(a, b int64) (int64, bool) {
|
||||
|
||||
+34
-20
@@ -52,7 +52,7 @@ func TestValidatorSetBasic(t *testing.T) {
|
||||
0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95,
|
||||
0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}, vset.Hash())
|
||||
// add
|
||||
val = randValidator(vset.TotalVotingPower())
|
||||
val = randModuloValidator(vset.TotalVotingPower())
|
||||
assert.NoError(t, vset.UpdateWithChangeSet([]*Validator{val}))
|
||||
|
||||
assert.True(t, vset.HasAddress(val.Address))
|
||||
@@ -67,7 +67,7 @@ func TestValidatorSetBasic(t *testing.T) {
|
||||
assert.Equal(t, val.Address, vset.GetProposer().Address)
|
||||
|
||||
// update
|
||||
val = randValidator(vset.TotalVotingPower())
|
||||
val = randModuloValidator(vset.TotalVotingPower())
|
||||
assert.NoError(t, vset.UpdateWithChangeSet([]*Validator{val}))
|
||||
_, val = vset.GetByAddress(val.Address)
|
||||
val.VotingPower += 100
|
||||
@@ -81,7 +81,7 @@ func TestValidatorSetBasic(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidatorSetValidateBasic(t *testing.T) {
|
||||
val, _ := RandValidator(false, 1)
|
||||
val, _ := randValidator(false, 1)
|
||||
badVal := &Validator{}
|
||||
|
||||
testCases := []struct {
|
||||
@@ -139,7 +139,7 @@ func TestValidatorSetValidateBasic(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCopy(t *testing.T) {
|
||||
vset := randValidatorSet(10)
|
||||
vset := randModuloValidatorSet(10)
|
||||
vsetHash := vset.Hash()
|
||||
if len(vsetHash) == 0 {
|
||||
t.Fatalf("ValidatorSet had unexpected zero hash")
|
||||
@@ -374,7 +374,7 @@ func randPubKey() crypto.PubKey {
|
||||
return ed25519.PubKey(tmrand.Bytes(32))
|
||||
}
|
||||
|
||||
func randValidator(totalVotingPower int64) *Validator {
|
||||
func randModuloValidator(totalVotingPower int64) *Validator {
|
||||
// this modulo limits the ProposerPriority/VotingPower to stay in the
|
||||
// bounds of MaxTotalVotingPower minus the already existing voting power:
|
||||
val := NewValidator(randPubKey(), int64(rand.Uint64()%uint64(MaxTotalVotingPower-totalVotingPower)))
|
||||
@@ -382,11 +382,25 @@ func randValidator(totalVotingPower int64) *Validator {
|
||||
return val
|
||||
}
|
||||
|
||||
func randValidatorSet(numValidators int) *ValidatorSet {
|
||||
func randValidator(randPower bool, minPower int64) (*Validator, PrivValidator) {
|
||||
privVal := NewMockPV()
|
||||
votePower := minPower
|
||||
if randPower {
|
||||
votePower += int64(rand.Uint32())
|
||||
}
|
||||
pubKey, err := privVal.GetPubKey(context.Background())
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("could not retrieve pubkey %w", err))
|
||||
}
|
||||
val := NewValidator(pubKey, votePower)
|
||||
return val, privVal
|
||||
}
|
||||
|
||||
func randModuloValidatorSet(numValidators int) *ValidatorSet {
|
||||
validators := make([]*Validator, numValidators)
|
||||
totalVotingPower := int64(0)
|
||||
for i := 0; i < numValidators; i++ {
|
||||
validators[i] = randValidator(totalVotingPower)
|
||||
validators[i] = randModuloValidator(totalVotingPower)
|
||||
totalVotingPower += validators[i].VotingPower
|
||||
}
|
||||
return NewValidatorSet(validators)
|
||||
@@ -751,7 +765,7 @@ func TestValidatorSet_VerifyCommit_CheckAllSignatures(t *testing.T) {
|
||||
)
|
||||
|
||||
voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, 4, 10)
|
||||
commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
require.NoError(t, err)
|
||||
|
||||
// malleate 4th signature
|
||||
@@ -776,7 +790,7 @@ func TestValidatorSet_VerifyCommitLight_ReturnsAsSoonAsMajorityOfVotingPowerSign
|
||||
)
|
||||
|
||||
voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, 4, 10)
|
||||
commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
require.NoError(t, err)
|
||||
|
||||
// malleate 4th signature (3 signatures are enough for 2/3+)
|
||||
@@ -799,7 +813,7 @@ func TestValidatorSet_VerifyCommitLightTrusting_ReturnsAsSoonAsTrustLevelOfVotin
|
||||
)
|
||||
|
||||
voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, 4, 10)
|
||||
commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
require.NoError(t, err)
|
||||
|
||||
// malleate 3rd signature (2 signatures are enough for 1/3+ trust level)
|
||||
@@ -1521,8 +1535,8 @@ func TestValidatorSet_VerifyCommitLightTrusting(t *testing.T) {
|
||||
var (
|
||||
blockID = makeBlockIDRandom()
|
||||
voteSet, originalValset, vals = randVoteSet(1, 1, tmproto.PrecommitType, 6, 1)
|
||||
commit, err = MakeCommit(blockID, 1, 1, voteSet, vals, time.Now())
|
||||
newValSet, _ = RandValidatorSet(2, 1)
|
||||
commit, err = makeCommit(blockID, 1, 1, voteSet, vals, time.Now())
|
||||
newValSet, _ = randValidatorPrivValSet(2, 1)
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1562,7 +1576,7 @@ func TestValidatorSet_VerifyCommitLightTrustingErrorsOnOverflow(t *testing.T) {
|
||||
var (
|
||||
blockID = makeBlockIDRandom()
|
||||
voteSet, valSet, vals = randVoteSet(1, 1, tmproto.PrecommitType, 1, MaxTotalVotingPower)
|
||||
commit, err = MakeCommit(blockID, 1, 1, voteSet, vals, time.Now())
|
||||
commit, err = makeCommit(blockID, 1, 1, voteSet, vals, time.Now())
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1600,14 +1614,14 @@ func TestSafeMul(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidatorSetProtoBuf(t *testing.T) {
|
||||
valset, _ := RandValidatorSet(10, 100)
|
||||
valset2, _ := RandValidatorSet(10, 100)
|
||||
valset, _ := randValidatorPrivValSet(10, 100)
|
||||
valset2, _ := randValidatorPrivValSet(10, 100)
|
||||
valset2.Validators[0] = &Validator{}
|
||||
|
||||
valset3, _ := RandValidatorSet(10, 100)
|
||||
valset3, _ := randValidatorPrivValSet(10, 100)
|
||||
valset3.Proposer = nil
|
||||
|
||||
valset4, _ := RandValidatorSet(10, 100)
|
||||
valset4, _ := randValidatorPrivValSet(10, 100)
|
||||
valset4.Proposer = &Validator{}
|
||||
|
||||
testCases := []struct {
|
||||
@@ -1725,7 +1739,7 @@ func BenchmarkValidatorSet_VerifyCommit_Ed25519(b *testing.B) {
|
||||
// generate n validators
|
||||
voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, n, int64(n*5))
|
||||
// create a commit with n validators
|
||||
commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
require.NoError(b, err)
|
||||
|
||||
for i := 0; i < b.N/n; i++ {
|
||||
@@ -1749,7 +1763,7 @@ func BenchmarkValidatorSet_VerifyCommitLight_Ed25519(b *testing.B) {
|
||||
// generate n validators
|
||||
voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, n, int64(n*5))
|
||||
// create a commit with n validators
|
||||
commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
require.NoError(b, err)
|
||||
|
||||
for i := 0; i < b.N/n; i++ {
|
||||
@@ -1773,7 +1787,7 @@ func BenchmarkValidatorSet_VerifyCommitLightTrusting_Ed25519(b *testing.B) {
|
||||
// generate n validators
|
||||
voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, n, int64(n*5))
|
||||
// create a commit with n validators
|
||||
commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now())
|
||||
require.NoError(b, err)
|
||||
|
||||
for i := 0; i < b.N/n; i++ {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func TestValidatorProtoBuf(t *testing.T) {
|
||||
val, _ := RandValidator(true, 100)
|
||||
val, _ := randValidator(true, 100)
|
||||
testCases := []struct {
|
||||
msg string
|
||||
v1 *Validator
|
||||
|
||||
+19
-1
@@ -3,6 +3,7 @@ package types
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -483,10 +484,27 @@ func randVoteSet(
|
||||
numValidators int,
|
||||
votingPower int64,
|
||||
) (*VoteSet, *ValidatorSet, []PrivValidator) {
|
||||
valSet, privValidators := RandValidatorSet(numValidators, votingPower)
|
||||
valSet, privValidators := randValidatorPrivValSet(numValidators, votingPower)
|
||||
return NewVoteSet("test_chain_id", height, round, signedMsgType, valSet), valSet, privValidators
|
||||
}
|
||||
|
||||
func randValidatorPrivValSet(numValidators int, votingPower int64) (*ValidatorSet, []PrivValidator) {
|
||||
var (
|
||||
valz = make([]*Validator, numValidators)
|
||||
privValidators = make([]PrivValidator, numValidators)
|
||||
)
|
||||
|
||||
for i := 0; i < numValidators; i++ {
|
||||
val, privValidator := randValidator(false, votingPower)
|
||||
valz[i] = val
|
||||
privValidators[i] = privValidator
|
||||
}
|
||||
|
||||
sort.Sort(PrivValidatorsByAddress(privValidators))
|
||||
|
||||
return NewValidatorSet(valz), privValidators
|
||||
}
|
||||
|
||||
// Convenience: Return new vote with different validator address/index
|
||||
func withValidator(vote *Vote, addr []byte, idx int32) *Vote {
|
||||
vote = vote.Copy()
|
||||
|
||||
Reference in New Issue
Block a user