bitbucket.org/number571/tendermint@v0.8.14/types/evidence.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/binary" 7 "errors" 8 "fmt" 9 "sort" 10 "strings" 11 "time" 12 13 abci "bitbucket.org/number571/tendermint/abci/types" 14 "bitbucket.org/number571/tendermint/crypto/merkle" 15 "bitbucket.org/number571/tendermint/crypto/tmhash" 16 tmjson "bitbucket.org/number571/tendermint/libs/json" 17 tmrand "bitbucket.org/number571/tendermint/libs/rand" 18 tmproto "bitbucket.org/number571/tendermint/proto/tendermint/types" 19 ) 20 21 // Evidence represents any provable malicious activity by a validator. 22 // Verification logic for each evidence is part of the evidence module. 23 type Evidence interface { 24 ABCI() []abci.Evidence // forms individual evidence to be sent to the application 25 Bytes() []byte // bytes which comprise the evidence 26 Hash() []byte // hash of the evidence 27 Height() int64 // height of the infraction 28 String() string // string format of the evidence 29 Time() time.Time // time of the infraction 30 ValidateBasic() error // basic consistency check 31 } 32 33 //-------------------------------------------------------------------------------------- 34 35 // DuplicateVoteEvidence contains evidence of a single validator signing two conflicting votes. 36 type DuplicateVoteEvidence struct { 37 VoteA *Vote `json:"vote_a"` 38 VoteB *Vote `json:"vote_b"` 39 40 // abci specific information 41 TotalVotingPower int64 42 ValidatorPower int64 43 Timestamp time.Time 44 } 45 46 var _ Evidence = &DuplicateVoteEvidence{} 47 48 // NewDuplicateVoteEvidence creates DuplicateVoteEvidence with right ordering given 49 // two conflicting votes. If one of the votes is nil, evidence returned is nil as well 50 func NewDuplicateVoteEvidence(vote1, vote2 *Vote, blockTime time.Time, valSet *ValidatorSet) *DuplicateVoteEvidence { 51 var voteA, voteB *Vote 52 if vote1 == nil || vote2 == nil || valSet == nil { 53 return nil 54 } 55 idx, val := valSet.GetByAddress(vote1.ValidatorAddress) 56 if idx == -1 { 57 return nil 58 } 59 60 if strings.Compare(vote1.BlockID.Key(), vote2.BlockID.Key()) == -1 { 61 voteA = vote1 62 voteB = vote2 63 } else { 64 voteA = vote2 65 voteB = vote1 66 } 67 return &DuplicateVoteEvidence{ 68 VoteA: voteA, 69 VoteB: voteB, 70 TotalVotingPower: valSet.TotalVotingPower(), 71 ValidatorPower: val.VotingPower, 72 Timestamp: blockTime, 73 } 74 } 75 76 // ABCI returns the application relevant representation of the evidence 77 func (dve *DuplicateVoteEvidence) ABCI() []abci.Evidence { 78 return []abci.Evidence{{ 79 Type: abci.EvidenceType_DUPLICATE_VOTE, 80 Validator: abci.Validator{ 81 Address: dve.VoteA.ValidatorAddress, 82 Power: dve.ValidatorPower, 83 }, 84 Height: dve.VoteA.Height, 85 Time: dve.Timestamp, 86 TotalVotingPower: dve.TotalVotingPower, 87 }} 88 } 89 90 // Bytes returns the proto-encoded evidence as a byte array. 91 func (dve *DuplicateVoteEvidence) Bytes() []byte { 92 pbe := dve.ToProto() 93 bz, err := pbe.Marshal() 94 if err != nil { 95 panic(err) 96 } 97 98 return bz 99 } 100 101 // Hash returns the hash of the evidence. 102 func (dve *DuplicateVoteEvidence) Hash() []byte { 103 return tmhash.Sum(dve.Bytes()) 104 } 105 106 // Height returns the height of the infraction 107 func (dve *DuplicateVoteEvidence) Height() int64 { 108 return dve.VoteA.Height 109 } 110 111 // String returns a string representation of the evidence. 112 func (dve *DuplicateVoteEvidence) String() string { 113 return fmt.Sprintf("DuplicateVoteEvidence{VoteA: %v, VoteB: %v}", dve.VoteA, dve.VoteB) 114 } 115 116 // Time returns the time of the infraction 117 func (dve *DuplicateVoteEvidence) Time() time.Time { 118 return dve.Timestamp 119 } 120 121 // ValidateBasic performs basic validation. 122 func (dve *DuplicateVoteEvidence) ValidateBasic() error { 123 if dve == nil { 124 return errors.New("empty duplicate vote evidence") 125 } 126 127 if dve.VoteA == nil || dve.VoteB == nil { 128 return fmt.Errorf("one or both of the votes are empty %v, %v", dve.VoteA, dve.VoteB) 129 } 130 if err := dve.VoteA.ValidateBasic(); err != nil { 131 return fmt.Errorf("invalid VoteA: %w", err) 132 } 133 if err := dve.VoteB.ValidateBasic(); err != nil { 134 return fmt.Errorf("invalid VoteB: %w", err) 135 } 136 // Enforce Votes are lexicographically sorted on blockID 137 if strings.Compare(dve.VoteA.BlockID.Key(), dve.VoteB.BlockID.Key()) >= 0 { 138 return errors.New("duplicate votes in invalid order") 139 } 140 return nil 141 } 142 143 // ValidateABCI validates the ABCI component of the evidence by checking the 144 // timestamp, validator power and total voting power. 145 func (dve *DuplicateVoteEvidence) ValidateABCI( 146 val *Validator, 147 valSet *ValidatorSet, 148 evidenceTime time.Time, 149 ) error { 150 151 if dve.Timestamp != evidenceTime { 152 return fmt.Errorf( 153 "evidence has a different time to the block it is associated with (%v != %v)", 154 dve.Timestamp, evidenceTime) 155 } 156 157 if val.VotingPower != dve.ValidatorPower { 158 return fmt.Errorf("validator power from evidence and our validator set does not match (%d != %d)", 159 dve.ValidatorPower, val.VotingPower) 160 } 161 if valSet.TotalVotingPower() != dve.TotalVotingPower { 162 return fmt.Errorf("total voting power from the evidence and our validator set does not match (%d != %d)", 163 dve.TotalVotingPower, valSet.TotalVotingPower()) 164 } 165 166 return nil 167 } 168 169 // GenerateABCI populates the ABCI component of the evidence. This includes the 170 // validator power, timestamp and total voting power. 171 func (dve *DuplicateVoteEvidence) GenerateABCI( 172 val *Validator, 173 valSet *ValidatorSet, 174 evidenceTime time.Time, 175 ) { 176 dve.ValidatorPower = val.VotingPower 177 dve.TotalVotingPower = valSet.TotalVotingPower() 178 dve.Timestamp = evidenceTime 179 } 180 181 // ToProto encodes DuplicateVoteEvidence to protobuf 182 func (dve *DuplicateVoteEvidence) ToProto() *tmproto.DuplicateVoteEvidence { 183 voteB := dve.VoteB.ToProto() 184 voteA := dve.VoteA.ToProto() 185 tp := tmproto.DuplicateVoteEvidence{ 186 VoteA: voteA, 187 VoteB: voteB, 188 TotalVotingPower: dve.TotalVotingPower, 189 ValidatorPower: dve.ValidatorPower, 190 Timestamp: dve.Timestamp, 191 } 192 return &tp 193 } 194 195 // DuplicateVoteEvidenceFromProto decodes protobuf into DuplicateVoteEvidence 196 func DuplicateVoteEvidenceFromProto(pb *tmproto.DuplicateVoteEvidence) (*DuplicateVoteEvidence, error) { 197 if pb == nil { 198 return nil, errors.New("nil duplicate vote evidence") 199 } 200 201 vA, err := VoteFromProto(pb.VoteA) 202 if err != nil { 203 return nil, err 204 } 205 206 vB, err := VoteFromProto(pb.VoteB) 207 if err != nil { 208 return nil, err 209 } 210 211 dve := &DuplicateVoteEvidence{ 212 VoteA: vA, 213 VoteB: vB, 214 TotalVotingPower: pb.TotalVotingPower, 215 ValidatorPower: pb.ValidatorPower, 216 Timestamp: pb.Timestamp, 217 } 218 219 return dve, dve.ValidateBasic() 220 } 221 222 //------------------------------------ LIGHT EVIDENCE -------------------------------------- 223 224 // LightClientAttackEvidence is a generalized evidence that captures all forms of known attacks on 225 // a light client such that a full node can verify, propose and commit the evidence on-chain for 226 // punishment of the malicious validators. There are three forms of attacks: Lunatic, Equivocation 227 // and Amnesia. These attacks are exhaustive. You can find a more detailed overview of this at 228 // tendermint/docs/architecture/adr-047-handling-evidence-from-light-client.md 229 // 230 // CommonHeight is used to indicate the type of attack. If the height is different to the conflicting block 231 // height, then nodes will treat this as of the Lunatic form, else it is of the Equivocation form. 232 type LightClientAttackEvidence struct { 233 ConflictingBlock *LightBlock 234 CommonHeight int64 235 236 // abci specific information 237 ByzantineValidators []*Validator // validators in the validator set that misbehaved in creating the conflicting block 238 TotalVotingPower int64 // total voting power of the validator set at the common height 239 Timestamp time.Time // timestamp of the block at the common height 240 } 241 242 var _ Evidence = &LightClientAttackEvidence{} 243 244 // ABCI forms an array of abci evidence for each byzantine validator 245 func (l *LightClientAttackEvidence) ABCI() []abci.Evidence { 246 abciEv := make([]abci.Evidence, len(l.ByzantineValidators)) 247 for idx, val := range l.ByzantineValidators { 248 abciEv[idx] = abci.Evidence{ 249 Type: abci.EvidenceType_LIGHT_CLIENT_ATTACK, 250 Validator: TM2PB.Validator(val), 251 Height: l.Height(), 252 Time: l.Timestamp, 253 TotalVotingPower: l.TotalVotingPower, 254 } 255 } 256 return abciEv 257 } 258 259 // Bytes returns the proto-encoded evidence as a byte array 260 func (l *LightClientAttackEvidence) Bytes() []byte { 261 pbe, err := l.ToProto() 262 if err != nil { 263 panic(err) 264 } 265 bz, err := pbe.Marshal() 266 if err != nil { 267 panic(err) 268 } 269 return bz 270 } 271 272 // GetByzantineValidators finds out what style of attack LightClientAttackEvidence was and then works out who 273 // the malicious validators were and returns them. This is used both for forming the ByzantineValidators 274 // field and for validating that it is correct. Validators are ordered based on validator power 275 func (l *LightClientAttackEvidence) GetByzantineValidators(commonVals *ValidatorSet, 276 trusted *SignedHeader) []*Validator { 277 var validators []*Validator 278 // First check if the header is invalid. This means that it is a lunatic attack and therefore we take the 279 // validators who are in the commonVals and voted for the lunatic header 280 if l.ConflictingHeaderIsInvalid(trusted.Header) { 281 for _, commitSig := range l.ConflictingBlock.Commit.Signatures { 282 if !commitSig.ForBlock() { 283 continue 284 } 285 286 _, val := commonVals.GetByAddress(commitSig.ValidatorAddress) 287 if val == nil { 288 // validator wasn't in the common validator set 289 continue 290 } 291 validators = append(validators, val) 292 } 293 sort.Sort(ValidatorsByVotingPower(validators)) 294 return validators 295 } else if trusted.Commit.Round == l.ConflictingBlock.Commit.Round { 296 // This is an equivocation attack as both commits are in the same round. We then find the validators 297 // from the conflicting light block validator set that voted in both headers. 298 // Validator hashes are the same therefore the indexing order of validators are the same and thus we 299 // only need a single loop to find the validators that voted twice. 300 for i := 0; i < len(l.ConflictingBlock.Commit.Signatures); i++ { 301 sigA := l.ConflictingBlock.Commit.Signatures[i] 302 if !sigA.ForBlock() { 303 continue 304 } 305 306 sigB := trusted.Commit.Signatures[i] 307 if !sigB.ForBlock() { 308 continue 309 } 310 311 _, val := l.ConflictingBlock.ValidatorSet.GetByAddress(sigA.ValidatorAddress) 312 validators = append(validators, val) 313 } 314 sort.Sort(ValidatorsByVotingPower(validators)) 315 return validators 316 } 317 // if the rounds are different then this is an amnesia attack. Unfortunately, given the nature of the attack, 318 // we aren't able yet to deduce which are malicious validators and which are not hence we return an 319 // empty validator set. 320 return validators 321 } 322 323 // ConflictingHeaderIsInvalid takes a trusted header and matches it againt a conflicting header 324 // to determine whether the conflicting header was the product of a valid state transition 325 // or not. If it is then all the deterministic fields of the header should be the same. 326 // If not, it is an invalid header and constitutes a lunatic attack. 327 func (l *LightClientAttackEvidence) ConflictingHeaderIsInvalid(trustedHeader *Header) bool { 328 return !bytes.Equal(trustedHeader.ValidatorsHash, l.ConflictingBlock.ValidatorsHash) || 329 !bytes.Equal(trustedHeader.NextValidatorsHash, l.ConflictingBlock.NextValidatorsHash) || 330 !bytes.Equal(trustedHeader.ConsensusHash, l.ConflictingBlock.ConsensusHash) || 331 !bytes.Equal(trustedHeader.AppHash, l.ConflictingBlock.AppHash) || 332 !bytes.Equal(trustedHeader.LastResultsHash, l.ConflictingBlock.LastResultsHash) 333 334 } 335 336 // Hash returns the hash of the header and the commonHeight. This is designed to cause hash collisions 337 // with evidence that have the same conflicting header and common height but different permutations 338 // of validator commit signatures. The reason for this is that we don't want to allow several 339 // permutations of the same evidence to be committed on chain. Ideally we commit the header with the 340 // most commit signatures (captures the most byzantine validators) but anything greater than 1/3 is 341 // sufficient. 342 // TODO: We should change the hash to include the commit, header, total voting power, byzantine 343 // validators and timestamp 344 func (l *LightClientAttackEvidence) Hash() []byte { 345 buf := make([]byte, binary.MaxVarintLen64) 346 n := binary.PutVarint(buf, l.CommonHeight) 347 bz := make([]byte, tmhash.Size+n) 348 copy(bz[:tmhash.Size-1], l.ConflictingBlock.Hash().Bytes()) 349 copy(bz[tmhash.Size:], buf) 350 return tmhash.Sum(bz) 351 } 352 353 // Height returns the last height at which the primary provider and witness provider had the same header. 354 // We use this as the height of the infraction rather than the actual conflicting header because we know 355 // that the malicious validators were bonded at this height which is important for evidence expiry 356 func (l *LightClientAttackEvidence) Height() int64 { 357 return l.CommonHeight 358 } 359 360 // String returns a string representation of LightClientAttackEvidence 361 func (l *LightClientAttackEvidence) String() string { 362 return fmt.Sprintf(`LightClientAttackEvidence{ 363 ConflictingBlock: %v, 364 CommonHeight: %d, 365 ByzatineValidators: %v, 366 TotalVotingPower: %d, 367 Timestamp: %v}#%X`, 368 l.ConflictingBlock.String(), l.CommonHeight, l.ByzantineValidators, 369 l.TotalVotingPower, l.Timestamp, l.Hash()) 370 } 371 372 // Time returns the time of the common block where the infraction leveraged off. 373 func (l *LightClientAttackEvidence) Time() time.Time { 374 return l.Timestamp 375 } 376 377 // ValidateBasic performs basic validation such that the evidence is consistent and can now be used for verification. 378 func (l *LightClientAttackEvidence) ValidateBasic() error { 379 if l.ConflictingBlock == nil { 380 return errors.New("conflicting block is nil") 381 } 382 383 // this check needs to be done before we can run validate basic 384 if l.ConflictingBlock.Header == nil { 385 return errors.New("conflicting block missing header") 386 } 387 388 if l.TotalVotingPower <= 0 { 389 return errors.New("negative or zero total voting power") 390 } 391 392 if l.CommonHeight <= 0 { 393 return errors.New("negative or zero common height") 394 } 395 396 // check that common height isn't ahead of the height of the conflicting block. It 397 // is possible that they are the same height if the light node witnesses either an 398 // amnesia or a equivocation attack. 399 if l.CommonHeight > l.ConflictingBlock.Height { 400 return fmt.Errorf("common height is ahead of the conflicting block height (%d > %d)", 401 l.CommonHeight, l.ConflictingBlock.Height) 402 } 403 404 if err := l.ConflictingBlock.ValidateBasic(l.ConflictingBlock.ChainID); err != nil { 405 return fmt.Errorf("invalid conflicting light block: %w", err) 406 } 407 408 return nil 409 } 410 411 // ValidateABCI validates the ABCI component of the evidence by checking the 412 // timestamp, byzantine validators and total voting power all match. ABCI 413 // components are validated separately because they can be re generated if 414 // invalid. 415 func (l *LightClientAttackEvidence) ValidateABCI( 416 commonVals *ValidatorSet, 417 trustedHeader *SignedHeader, 418 evidenceTime time.Time, 419 ) error { 420 421 if evTotal, valsTotal := l.TotalVotingPower, commonVals.TotalVotingPower(); evTotal != valsTotal { 422 return fmt.Errorf("total voting power from the evidence and our validator set does not match (%d != %d)", 423 evTotal, valsTotal) 424 } 425 426 if l.Timestamp != evidenceTime { 427 return fmt.Errorf( 428 "evidence has a different time to the block it is associated with (%v != %v)", 429 l.Timestamp, evidenceTime) 430 } 431 432 // Find out what type of attack this was and thus extract the malicious 433 // validators. Note, in the case of an Amnesia attack we don't have any 434 // malicious validators. 435 validators := l.GetByzantineValidators(commonVals, trustedHeader) 436 437 // Ensure this matches the validators that are listed in the evidence. They 438 // should be ordered based on power. 439 if validators == nil && l.ByzantineValidators != nil { 440 return fmt.Errorf( 441 "expected nil validators from an amnesia light client attack but got %d", 442 len(l.ByzantineValidators), 443 ) 444 } 445 446 if exp, got := len(validators), len(l.ByzantineValidators); exp != got { 447 return fmt.Errorf("expected %d byzantine validators from evidence but got %d", exp, got) 448 } 449 450 for idx, val := range validators { 451 if !bytes.Equal(l.ByzantineValidators[idx].Address, val.Address) { 452 return fmt.Errorf( 453 "evidence contained an unexpected byzantine validator address; expected: %v, got: %v", 454 val.Address, l.ByzantineValidators[idx].Address, 455 ) 456 } 457 458 if l.ByzantineValidators[idx].VotingPower != val.VotingPower { 459 return fmt.Errorf( 460 "evidence contained unexpected byzantine validator power; expected %d, got %d", 461 val.VotingPower, l.ByzantineValidators[idx].VotingPower, 462 ) 463 } 464 } 465 466 return nil 467 } 468 469 // GenerateABCI populates the ABCI component of the evidence: the timestamp, 470 // total voting power and byantine validators 471 func (l *LightClientAttackEvidence) GenerateABCI( 472 commonVals *ValidatorSet, 473 trustedHeader *SignedHeader, 474 evidenceTime time.Time, 475 ) { 476 l.Timestamp = evidenceTime 477 l.TotalVotingPower = commonVals.TotalVotingPower() 478 l.ByzantineValidators = l.GetByzantineValidators(commonVals, trustedHeader) 479 } 480 481 // ToProto encodes LightClientAttackEvidence to protobuf 482 func (l *LightClientAttackEvidence) ToProto() (*tmproto.LightClientAttackEvidence, error) { 483 conflictingBlock, err := l.ConflictingBlock.ToProto() 484 if err != nil { 485 return nil, err 486 } 487 488 byzVals := make([]*tmproto.Validator, len(l.ByzantineValidators)) 489 for idx, val := range l.ByzantineValidators { 490 valpb, err := val.ToProto() 491 if err != nil { 492 return nil, err 493 } 494 byzVals[idx] = valpb 495 } 496 497 return &tmproto.LightClientAttackEvidence{ 498 ConflictingBlock: conflictingBlock, 499 CommonHeight: l.CommonHeight, 500 ByzantineValidators: byzVals, 501 TotalVotingPower: l.TotalVotingPower, 502 Timestamp: l.Timestamp, 503 }, nil 504 } 505 506 // LightClientAttackEvidenceFromProto decodes protobuf 507 func LightClientAttackEvidenceFromProto(lpb *tmproto.LightClientAttackEvidence) (*LightClientAttackEvidence, error) { 508 if lpb == nil { 509 return nil, errors.New("empty light client attack evidence") 510 } 511 512 conflictingBlock, err := LightBlockFromProto(lpb.ConflictingBlock) 513 if err != nil { 514 return nil, err 515 } 516 517 byzVals := make([]*Validator, len(lpb.ByzantineValidators)) 518 for idx, valpb := range lpb.ByzantineValidators { 519 val, err := ValidatorFromProto(valpb) 520 if err != nil { 521 return nil, err 522 } 523 byzVals[idx] = val 524 } 525 526 l := &LightClientAttackEvidence{ 527 ConflictingBlock: conflictingBlock, 528 CommonHeight: lpb.CommonHeight, 529 ByzantineValidators: byzVals, 530 TotalVotingPower: lpb.TotalVotingPower, 531 Timestamp: lpb.Timestamp, 532 } 533 534 return l, l.ValidateBasic() 535 } 536 537 //------------------------------------------------------------------------------------------ 538 539 // EvidenceList is a list of Evidence. Evidences is not a word. 540 type EvidenceList []Evidence 541 542 // Hash returns the simple merkle root hash of the EvidenceList. 543 func (evl EvidenceList) Hash() []byte { 544 // These allocations are required because Evidence is not of type Bytes, and 545 // golang slices can't be typed cast. This shouldn't be a performance problem since 546 // the Evidence size is capped. 547 evidenceBzs := make([][]byte, len(evl)) 548 for i := 0; i < len(evl); i++ { 549 // TODO: We should change this to the hash. Using bytes contains some unexported data that 550 // may cause different hashes 551 evidenceBzs[i] = evl[i].Bytes() 552 } 553 return merkle.HashFromByteSlices(evidenceBzs) 554 } 555 556 func (evl EvidenceList) String() string { 557 s := "" 558 for _, e := range evl { 559 s += fmt.Sprintf("%s\t\t", e) 560 } 561 return s 562 } 563 564 // Has returns true if the evidence is in the EvidenceList. 565 func (evl EvidenceList) Has(evidence Evidence) bool { 566 for _, ev := range evl { 567 if bytes.Equal(evidence.Hash(), ev.Hash()) { 568 return true 569 } 570 } 571 return false 572 } 573 574 //------------------------------------------ PROTO -------------------------------------- 575 576 // EvidenceToProto is a generalized function for encoding evidence that conforms to the 577 // evidence interface to protobuf 578 func EvidenceToProto(evidence Evidence) (*tmproto.Evidence, error) { 579 if evidence == nil { 580 return nil, errors.New("nil evidence") 581 } 582 583 switch evi := evidence.(type) { 584 case *DuplicateVoteEvidence: 585 pbev := evi.ToProto() 586 return &tmproto.Evidence{ 587 Sum: &tmproto.Evidence_DuplicateVoteEvidence{ 588 DuplicateVoteEvidence: pbev, 589 }, 590 }, nil 591 592 case *LightClientAttackEvidence: 593 pbev, err := evi.ToProto() 594 if err != nil { 595 return nil, err 596 } 597 return &tmproto.Evidence{ 598 Sum: &tmproto.Evidence_LightClientAttackEvidence{ 599 LightClientAttackEvidence: pbev, 600 }, 601 }, nil 602 603 default: 604 return nil, fmt.Errorf("toproto: evidence is not recognized: %T", evi) 605 } 606 } 607 608 // EvidenceFromProto is a generalized function for decoding protobuf into the 609 // evidence interface 610 func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) { 611 if evidence == nil { 612 return nil, errors.New("nil evidence") 613 } 614 615 switch evi := evidence.Sum.(type) { 616 case *tmproto.Evidence_DuplicateVoteEvidence: 617 return DuplicateVoteEvidenceFromProto(evi.DuplicateVoteEvidence) 618 case *tmproto.Evidence_LightClientAttackEvidence: 619 return LightClientAttackEvidenceFromProto(evi.LightClientAttackEvidence) 620 default: 621 return nil, errors.New("evidence is not recognized") 622 } 623 } 624 625 func init() { 626 tmjson.RegisterType(&DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence") 627 tmjson.RegisterType(&LightClientAttackEvidence{}, "tendermint/LightClientAttackEvidence") 628 } 629 630 //-------------------------------------------- ERRORS -------------------------------------- 631 632 // ErrInvalidEvidence wraps a piece of evidence and the error denoting how or why it is invalid. 633 type ErrInvalidEvidence struct { 634 Evidence Evidence 635 Reason error 636 } 637 638 // NewErrInvalidEvidence returns a new EvidenceInvalid with the given err. 639 func NewErrInvalidEvidence(ev Evidence, err error) *ErrInvalidEvidence { 640 return &ErrInvalidEvidence{ev, err} 641 } 642 643 // Error returns a string representation of the error. 644 func (err *ErrInvalidEvidence) Error() string { 645 return fmt.Sprintf("Invalid evidence: %v. Evidence: %v", err.Reason, err.Evidence) 646 } 647 648 // ErrEvidenceOverflow is for when there the amount of evidence exceeds the max bytes. 649 type ErrEvidenceOverflow struct { 650 Max int64 651 Got int64 652 } 653 654 // NewErrEvidenceOverflow returns a new ErrEvidenceOverflow where got > max. 655 func NewErrEvidenceOverflow(max, got int64) *ErrEvidenceOverflow { 656 return &ErrEvidenceOverflow{max, got} 657 } 658 659 // Error returns a string representation of the error. 660 func (err *ErrEvidenceOverflow) Error() string { 661 return fmt.Sprintf("Too much evidence: Max %d, got %d", err.Max, err.Got) 662 } 663 664 //-------------------------------------------- MOCKING -------------------------------------- 665 666 // unstable - use only for testing 667 668 // assumes the round to be 0 and the validator index to be 0 669 func NewMockDuplicateVoteEvidence(height int64, time time.Time, chainID string) *DuplicateVoteEvidence { 670 val := NewMockPV() 671 return NewMockDuplicateVoteEvidenceWithValidator(height, time, val, chainID) 672 } 673 674 // assumes voting power to be 10 and validator to be the only one in the set 675 func NewMockDuplicateVoteEvidenceWithValidator(height int64, time time.Time, 676 pv PrivValidator, chainID string) *DuplicateVoteEvidence { 677 pubKey, _ := pv.GetPubKey(context.Background()) 678 val := NewValidator(pubKey, 10) 679 voteA := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) 680 vA := voteA.ToProto() 681 _ = pv.SignVote(context.Background(), chainID, vA) 682 voteA.Signature = vA.Signature 683 voteB := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) 684 vB := voteB.ToProto() 685 _ = pv.SignVote(context.Background(), chainID, vB) 686 voteB.Signature = vB.Signature 687 return NewDuplicateVoteEvidence(voteA, voteB, time, NewValidatorSet([]*Validator{val})) 688 } 689 690 func makeMockVote(height int64, round, index int32, addr Address, 691 blockID BlockID, time time.Time) *Vote { 692 return &Vote{ 693 Type: tmproto.SignedMsgType(2), 694 Height: height, 695 Round: round, 696 BlockID: blockID, 697 Timestamp: time, 698 ValidatorAddress: addr, 699 ValidatorIndex: index, 700 } 701 } 702 703 func randBlockID() BlockID { 704 return BlockID{ 705 Hash: tmrand.Bytes(tmhash.Size), 706 PartSetHeader: PartSetHeader{ 707 Total: 1, 708 Hash: tmrand.Bytes(tmhash.Size), 709 }, 710 } 711 }