github.com/okex/exchain@v1.8.0/libs/tendermint/types/evidence.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "fmt" 6 "strings" 7 "time" 8 9 "github.com/pkg/errors" 10 amino "github.com/tendermint/go-amino" 11 12 "github.com/okex/exchain/libs/tendermint/crypto" 13 cryptoenc "github.com/okex/exchain/libs/tendermint/crypto/encoding" 14 cryptoamino "github.com/okex/exchain/libs/tendermint/crypto/encoding/amino" 15 "github.com/okex/exchain/libs/tendermint/crypto/merkle" 16 "github.com/okex/exchain/libs/tendermint/crypto/tmhash" 17 tmproto "github.com/okex/exchain/libs/tendermint/proto/types" 18 ) 19 20 const ( 21 // MaxEvidenceBytes is a maximum size of any evidence (including amino overhead). 22 MaxEvidenceBytes int64 = 484 23 24 DuplicateVoteEvidenceName = "tendermint/DuplicateVoteEvidence" 25 ) 26 27 // ErrEvidenceInvalid wraps a piece of evidence and the error denoting how or why it is invalid. 28 type ErrEvidenceInvalid struct { 29 Evidence Evidence 30 ErrorValue error 31 } 32 33 // NewErrEvidenceInvalid returns a new EvidenceInvalid with the given err. 34 func NewErrEvidenceInvalid(ev Evidence, err error) *ErrEvidenceInvalid { 35 return &ErrEvidenceInvalid{ev, err} 36 } 37 38 // Error returns a string representation of the error. 39 func (err *ErrEvidenceInvalid) Error() string { 40 return fmt.Sprintf("Invalid evidence: %v. Evidence: %v", err.ErrorValue, err.Evidence) 41 } 42 43 // ErrEvidenceOverflow is for when there is too much evidence in a block. 44 type ErrEvidenceOverflow struct { 45 MaxNum int64 46 GotNum int64 47 } 48 49 // NewErrEvidenceOverflow returns a new ErrEvidenceOverflow where got > max. 50 func NewErrEvidenceOverflow(max, got int64) *ErrEvidenceOverflow { 51 return &ErrEvidenceOverflow{max, got} 52 } 53 54 // Error returns a string representation of the error. 55 func (err *ErrEvidenceOverflow) Error() string { 56 return fmt.Sprintf("Too much evidence: Max %d, got %d", err.MaxNum, err.GotNum) 57 } 58 59 //------------------------------------------- 60 61 // Evidence represents any provable malicious activity by a validator 62 type Evidence interface { 63 Height() int64 // height of the equivocation 64 Time() time.Time // time of the equivocation 65 Address() []byte // address of the equivocating validator 66 Bytes() []byte // bytes which comprise the evidence 67 Hash() []byte // hash of the evidence 68 Verify(chainID string, pubKey crypto.PubKey) error // verify the evidence 69 Equal(Evidence) bool // check equality of evidence 70 71 ValidateBasic() error 72 String() string 73 } 74 75 func EvidenceToProto(evidence Evidence) (*tmproto.Evidence, error) { 76 if evidence == nil { 77 return nil, errors.New("nil evidence") 78 } 79 80 switch evi := evidence.(type) { 81 case *DuplicateVoteEvidence: 82 voteB := evi.VoteB.ToProto() 83 voteA := evi.VoteA.ToProto() 84 pk, err := cryptoenc.PubKeyToProto(evi.PubKey) 85 if err != nil { 86 return nil, err 87 } 88 tp := &tmproto.Evidence{ 89 Sum: &tmproto.Evidence_DuplicateVoteEvidence{ 90 DuplicateVoteEvidence: &tmproto.DuplicateVoteEvidence{ 91 PubKey: &pk, 92 VoteA: voteA, 93 VoteB: voteB, 94 }, 95 }, 96 } 97 return tp, nil 98 case MockEvidence: 99 if err := evi.ValidateBasic(); err != nil { 100 return nil, err 101 } 102 103 tp := &tmproto.Evidence{ 104 Sum: &tmproto.Evidence_MockEvidence{ 105 MockEvidence: &tmproto.MockEvidence{ 106 EvidenceHeight: evi.Height(), 107 EvidenceTime: evi.Time(), 108 EvidenceAddress: evi.Address(), 109 }, 110 }, 111 } 112 113 return tp, nil 114 case MockRandomEvidence: 115 if err := evi.ValidateBasic(); err != nil { 116 return nil, err 117 } 118 119 tp := &tmproto.Evidence{ 120 Sum: &tmproto.Evidence_MockRandomEvidence{ 121 MockRandomEvidence: &tmproto.MockRandomEvidence{ 122 EvidenceHeight: evi.Height(), 123 EvidenceTime: evi.Time(), 124 EvidenceAddress: evi.Address(), 125 RandBytes: evi.randBytes, 126 }, 127 }, 128 } 129 return tp, nil 130 default: 131 return nil, fmt.Errorf("toproto: evidence is not recognized: %T", evi) 132 } 133 } 134 135 func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) { 136 if evidence == nil { 137 return nil, errors.New("nil evidence") 138 } 139 140 switch evi := evidence.Sum.(type) { 141 case *tmproto.Evidence_DuplicateVoteEvidence: 142 143 vA, err := VoteFromProto(evi.DuplicateVoteEvidence.VoteA) 144 if err != nil { 145 return nil, err 146 } 147 148 vB, err := VoteFromProto(evi.DuplicateVoteEvidence.VoteB) 149 if err != nil { 150 return nil, err 151 } 152 153 pk, _, err := cryptoenc.PubKeyFromProto(evi.DuplicateVoteEvidence.GetPubKey()) 154 if err != nil { 155 return nil, err 156 } 157 158 dve := DuplicateVoteEvidence{ 159 PubKey: pk, 160 VoteA: vA, 161 VoteB: vB, 162 } 163 164 return &dve, dve.ValidateBasic() 165 case *tmproto.Evidence_MockEvidence: 166 me := MockEvidence{ 167 EvidenceHeight: evi.MockEvidence.GetEvidenceHeight(), 168 EvidenceAddress: evi.MockEvidence.GetEvidenceAddress(), 169 EvidenceTime: evi.MockEvidence.GetEvidenceTime(), 170 } 171 return me, me.ValidateBasic() 172 case *tmproto.Evidence_MockRandomEvidence: 173 mre := MockRandomEvidence{ 174 MockEvidence: MockEvidence{ 175 EvidenceHeight: evi.MockRandomEvidence.GetEvidenceHeight(), 176 EvidenceAddress: evi.MockRandomEvidence.GetEvidenceAddress(), 177 EvidenceTime: evi.MockRandomEvidence.GetEvidenceTime(), 178 }, 179 randBytes: evi.MockRandomEvidence.RandBytes, 180 } 181 return mre, mre.ValidateBasic() 182 default: 183 return nil, errors.New("evidence is not recognized") 184 } 185 } 186 187 func RegisterEvidences(cdc *amino.Codec) { 188 cdc.RegisterInterface((*Evidence)(nil), nil) 189 cdc.RegisterConcrete(&DuplicateVoteEvidence{}, DuplicateVoteEvidenceName, nil) 190 191 cdc.RegisterConcreteUnmarshaller(DuplicateVoteEvidenceName, func(codec *amino.Codec, data []byte) (interface{}, int, error) { 192 var dve DuplicateVoteEvidence 193 err := dve.UnmarshalFromAmino(codec, data) 194 if err != nil { 195 return nil, 0, err 196 } 197 return &dve, len(data), nil 198 }) 199 } 200 201 func RegisterMockEvidences(cdc *amino.Codec) { 202 cdc.RegisterConcrete(MockEvidence{}, "tendermint/MockEvidence", nil) 203 cdc.RegisterConcrete(MockRandomEvidence{}, "tendermint/MockRandomEvidence", nil) 204 } 205 206 const ( 207 MaxEvidenceBytesDenominator = 10 208 ) 209 210 // MaxEvidencePerBlock returns the maximum number of evidences 211 // allowed in the block and their maximum total size (limitted to 1/10th 212 // of the maximum block size). 213 // TODO: change to a constant, or to a fraction of the validator set size. 214 // See https://github.com/tendermint/tendermint/issues/2590 215 func MaxEvidencePerBlock(blockMaxBytes int64) (int64, int64) { 216 maxBytes := blockMaxBytes / MaxEvidenceBytesDenominator 217 maxNum := maxBytes / MaxEvidenceBytes 218 return maxNum, maxBytes 219 } 220 221 //------------------------------------------- 222 223 // DuplicateVoteEvidence contains evidence a validator signed two conflicting 224 // votes. 225 type DuplicateVoteEvidence struct { 226 PubKey crypto.PubKey 227 VoteA *Vote 228 VoteB *Vote 229 } 230 231 func (dve DuplicateVoteEvidence) AminoSize(cdc *amino.Codec) int { 232 var size = 0 233 234 if dve.PubKey != nil { 235 pubKeySize := cryptoamino.PubKeyAminoSize(dve.PubKey, cdc) 236 size += 1 + amino.UvarintSize(uint64(pubKeySize)) + pubKeySize 237 } 238 239 if dve.VoteA != nil { 240 voteASize := dve.VoteA.AminoSize(cdc) 241 size += 1 + amino.UvarintSize(uint64(voteASize)) + voteASize 242 } 243 244 if dve.VoteB != nil { 245 voteBSize := dve.VoteB.AminoSize(cdc) 246 size += 1 + amino.UvarintSize(uint64(voteBSize)) + voteBSize 247 } 248 249 return size 250 } 251 252 func (dve *DuplicateVoteEvidence) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error { 253 var dataLen uint64 = 0 254 var subData []byte 255 256 for { 257 data = data[dataLen:] 258 if len(data) == 0 { 259 break 260 } 261 262 pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0]) 263 if err != nil { 264 return err 265 } 266 data = data[1:] 267 268 if pbType == amino.Typ3_ByteLength { 269 var n int 270 dataLen, n, err = amino.DecodeUvarint(data) 271 if err != nil { 272 return err 273 } 274 data = data[n:] 275 if len(data) < int(dataLen) { 276 return fmt.Errorf("invalid data len") 277 } 278 subData = data[:dataLen] 279 } else { 280 return fmt.Errorf("unexpect pb type %d", pbType) 281 } 282 283 switch pos { 284 case 1: 285 dve.PubKey, err = cryptoamino.UnmarshalPubKeyFromAmino(cdc, subData) 286 if err != nil { 287 return err 288 } 289 case 2: 290 dve.VoteA = new(Vote) 291 err = dve.VoteA.UnmarshalFromAmino(cdc, subData) 292 if err != nil { 293 return err 294 } 295 case 3: 296 dve.VoteB = new(Vote) 297 err = dve.VoteB.UnmarshalFromAmino(cdc, subData) 298 if err != nil { 299 return err 300 } 301 default: 302 return fmt.Errorf("unexpect feild num %d", pos) 303 } 304 } 305 return nil 306 } 307 308 var _ Evidence = &DuplicateVoteEvidence{} 309 310 // NewDuplicateVoteEvidence creates DuplicateVoteEvidence with right ordering given 311 // two conflicting votes. If one of the votes is nil, evidence returned is nil as well 312 func NewDuplicateVoteEvidence(pubkey crypto.PubKey, vote1 *Vote, vote2 *Vote) *DuplicateVoteEvidence { 313 var voteA, voteB *Vote 314 if vote1 == nil || vote2 == nil { 315 return nil 316 } 317 if strings.Compare(vote1.BlockID.Key(), vote2.BlockID.Key()) == -1 { 318 voteA = vote1 319 voteB = vote2 320 } else { 321 voteA = vote2 322 voteB = vote1 323 } 324 return &DuplicateVoteEvidence{ 325 PubKey: pubkey, 326 VoteA: voteA, 327 VoteB: voteB, 328 } 329 } 330 331 // String returns a string representation of the evidence. 332 func (dve *DuplicateVoteEvidence) String() string { 333 return fmt.Sprintf("VoteA: %v; VoteB: %v", dve.VoteA, dve.VoteB) 334 335 } 336 337 // Height returns the height this evidence refers to. 338 func (dve *DuplicateVoteEvidence) Height() int64 { 339 return dve.VoteA.Height 340 } 341 342 // Time return the time the evidence was created 343 func (dve *DuplicateVoteEvidence) Time() time.Time { 344 return dve.VoteA.Timestamp 345 } 346 347 // Address returns the address of the validator. 348 func (dve *DuplicateVoteEvidence) Address() []byte { 349 return dve.PubKey.Address() 350 } 351 352 // Hash returns the hash of the evidence. 353 func (dve *DuplicateVoteEvidence) Bytes() []byte { 354 return cdcEncode(dve) 355 } 356 357 // Hash returns the hash of the evidence. 358 func (dve *DuplicateVoteEvidence) Hash() []byte { 359 return tmhash.Sum(cdcEncode(dve)) 360 } 361 362 // Verify returns an error if the two votes aren't conflicting. 363 // To be conflicting, they must be from the same validator, for the same H/R/S, but for different blocks. 364 func (dve *DuplicateVoteEvidence) Verify(chainID string, pubKey crypto.PubKey) error { 365 // H/R/S must be the same 366 if dve.VoteA.Height != dve.VoteB.Height || 367 dve.VoteA.Round != dve.VoteB.Round || 368 dve.VoteA.Type != dve.VoteB.Type { 369 return fmt.Errorf("duplicateVoteEvidence Error: H/R/S does not match. Got %v and %v", dve.VoteA, dve.VoteB) 370 } 371 372 // Address must be the same 373 if !bytes.Equal(dve.VoteA.ValidatorAddress, dve.VoteB.ValidatorAddress) { 374 return fmt.Errorf( 375 "duplicateVoteEvidence Error: Validator addresses do not match. Got %X and %X", 376 dve.VoteA.ValidatorAddress, 377 dve.VoteB.ValidatorAddress, 378 ) 379 } 380 381 // Index must be the same 382 if dve.VoteA.ValidatorIndex != dve.VoteB.ValidatorIndex { 383 return fmt.Errorf( 384 "duplicateVoteEvidence Error: Validator indices do not match. Got %d and %d", 385 dve.VoteA.ValidatorIndex, 386 dve.VoteB.ValidatorIndex, 387 ) 388 } 389 390 // BlockIDs must be different 391 if dve.VoteA.BlockID.Equals(dve.VoteB.BlockID) { 392 return fmt.Errorf( 393 "duplicateVoteEvidence Error: BlockIDs are the same (%v) - not a real duplicate vote", 394 dve.VoteA.BlockID, 395 ) 396 } 397 398 // pubkey must match address (this should already be true, sanity check) 399 addr := dve.VoteA.ValidatorAddress 400 if !bytes.Equal(pubKey.Address(), addr) { 401 return fmt.Errorf("duplicateVoteEvidence FAILED SANITY CHECK - address (%X) doesn't match pubkey (%v - %X)", 402 addr, pubKey, pubKey.Address()) 403 } 404 405 // Signatures must be valid 406 if !pubKey.VerifyBytes(dve.VoteA.SignBytes(chainID), dve.VoteA.Signature) { 407 return fmt.Errorf("duplicateVoteEvidence Error verifying VoteA: %v", ErrVoteInvalidSignature) 408 } 409 if !pubKey.VerifyBytes(dve.VoteB.SignBytes(chainID), dve.VoteB.Signature) { 410 return fmt.Errorf("duplicateVoteEvidence Error verifying VoteB: %v", ErrVoteInvalidSignature) 411 } 412 413 return nil 414 } 415 416 // Equal checks if two pieces of evidence are equal. 417 func (dve *DuplicateVoteEvidence) Equal(ev Evidence) bool { 418 if _, ok := ev.(*DuplicateVoteEvidence); !ok { 419 return false 420 } 421 422 // just check their hashes 423 dveHash := tmhash.Sum(cdcEncode(dve)) 424 evHash := tmhash.Sum(cdcEncode(ev)) 425 fmt.Println(dveHash, evHash) 426 return bytes.Equal(dveHash, evHash) 427 } 428 429 // ValidateBasic performs basic validation. 430 func (dve *DuplicateVoteEvidence) ValidateBasic() error { 431 if len(dve.PubKey.Bytes()) == 0 { 432 return errors.New("empty PubKey") 433 } 434 if dve.VoteA == nil || dve.VoteB == nil { 435 return fmt.Errorf("one or both of the votes are empty %v, %v", dve.VoteA, dve.VoteB) 436 } 437 if err := dve.VoteA.ValidateBasic(); err != nil { 438 return fmt.Errorf("invalid VoteA: %v", err) 439 } 440 if err := dve.VoteB.ValidateBasic(); err != nil { 441 return fmt.Errorf("invalid VoteB: %v", err) 442 } 443 // Enforce Votes are lexicographically sorted on blockID 444 if strings.Compare(dve.VoteA.BlockID.Key(), dve.VoteB.BlockID.Key()) >= 0 { 445 return errors.New("duplicate votes in invalid order") 446 } 447 return nil 448 } 449 450 //----------------------------------------------------------------- 451 452 // UNSTABLE 453 type MockRandomEvidence struct { 454 MockEvidence 455 randBytes []byte 456 } 457 458 var _ Evidence = &MockRandomEvidence{} 459 460 // UNSTABLE 461 func NewMockRandomEvidence(height int64, eTime time.Time, address []byte, randBytes []byte) MockRandomEvidence { 462 return MockRandomEvidence{ 463 MockEvidence{ 464 EvidenceHeight: height, 465 EvidenceTime: eTime, 466 EvidenceAddress: address}, randBytes, 467 } 468 } 469 470 func (e MockRandomEvidence) Hash() []byte { 471 return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.randBytes)) 472 } 473 474 // UNSTABLE 475 type MockEvidence struct { 476 EvidenceHeight int64 477 EvidenceTime time.Time 478 EvidenceAddress []byte 479 } 480 481 var _ Evidence = &MockEvidence{} 482 483 // UNSTABLE 484 func NewMockEvidence(height int64, eTime time.Time, idx int, address []byte) MockEvidence { 485 return MockEvidence{ 486 EvidenceHeight: height, 487 EvidenceTime: eTime, 488 EvidenceAddress: address} 489 } 490 491 func (e MockEvidence) Height() int64 { return e.EvidenceHeight } 492 func (e MockEvidence) Time() time.Time { return e.EvidenceTime } 493 func (e MockEvidence) Address() []byte { return e.EvidenceAddress } 494 func (e MockEvidence) Hash() []byte { 495 return []byte(fmt.Sprintf("%d-%x-%s", 496 e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime)) 497 } 498 func (e MockEvidence) Bytes() []byte { 499 return []byte(fmt.Sprintf("%d-%x-%s", 500 e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime)) 501 } 502 func (e MockEvidence) Verify(chainID string, pubKey crypto.PubKey) error { return nil } 503 func (e MockEvidence) Equal(ev Evidence) bool { 504 e2 := ev.(MockEvidence) 505 return e.EvidenceHeight == e2.EvidenceHeight && 506 bytes.Equal(e.EvidenceAddress, e2.EvidenceAddress) 507 } 508 func (e MockEvidence) ValidateBasic() error { return nil } 509 func (e MockEvidence) String() string { 510 return fmt.Sprintf("Evidence: %d/%s/%s", e.EvidenceHeight, e.Time(), e.EvidenceAddress) 511 } 512 513 //------------------------------------------- 514 515 // EvidenceList is a list of Evidence. Evidences is not a word. 516 type EvidenceList []Evidence 517 518 // Hash returns the simple merkle root hash of the EvidenceList. 519 func (evl EvidenceList) Hash() []byte { 520 // These allocations are required because Evidence is not of type Bytes, and 521 // golang slices can't be typed cast. This shouldn't be a performance problem since 522 // the Evidence size is capped. 523 evidenceBzs := make([][]byte, len(evl)) 524 for i := 0; i < len(evl); i++ { 525 evidenceBzs[i] = evl[i].Bytes() 526 } 527 return merkle.SimpleHashFromByteSlices(evidenceBzs) 528 } 529 530 func (evl EvidenceList) String() string { 531 s := "" 532 for _, e := range evl { 533 s += fmt.Sprintf("%s\t\t", e) 534 } 535 return s 536 } 537 538 // Has returns true if the evidence is in the EvidenceList. 539 func (evl EvidenceList) Has(evidence Evidence) bool { 540 for _, ev := range evl { 541 if ev.Equal(evidence) { 542 return true 543 } 544 } 545 return false 546 }