You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

964 lines
28 KiB

lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
  1. package types
  2. import (
  3. "bytes"
  4. "fmt"
  5. "strings"
  6. "time"
  7. "github.com/pkg/errors"
  8. "github.com/tendermint/tendermint/crypto/tmhash"
  9. tmmath "github.com/tendermint/tendermint/libs/math"
  10. amino "github.com/tendermint/go-amino"
  11. "github.com/tendermint/tendermint/crypto"
  12. "github.com/tendermint/tendermint/crypto/merkle"
  13. )
  14. const (
  15. // MaxEvidenceBytes is a maximum size of any evidence (including amino overhead).
  16. MaxEvidenceBytes int64 = 444
  17. // An invalid field in the header from LunaticValidatorEvidence.
  18. // Must be a function of the ABCI application state.
  19. ValidatorsHashField = "ValidatorsHash"
  20. NextValidatorsHashField = "NextValidatorsHash"
  21. ConsensusHashField = "ConsensusHash"
  22. AppHashField = "AppHash"
  23. LastResultsHashField = "LastResultsHash"
  24. )
  25. // ErrEvidenceInvalid wraps a piece of evidence and the error denoting how or why it is invalid.
  26. type ErrEvidenceInvalid struct {
  27. Evidence Evidence
  28. ErrorValue error
  29. }
  30. // NewErrEvidenceInvalid returns a new EvidenceInvalid with the given err.
  31. func NewErrEvidenceInvalid(ev Evidence, err error) *ErrEvidenceInvalid {
  32. return &ErrEvidenceInvalid{ev, err}
  33. }
  34. // Error returns a string representation of the error.
  35. func (err *ErrEvidenceInvalid) Error() string {
  36. return fmt.Sprintf("Invalid evidence: %v. Evidence: %v", err.ErrorValue, err.Evidence)
  37. }
  38. // ErrEvidenceOverflow is for when there is too much evidence in a block.
  39. type ErrEvidenceOverflow struct {
  40. MaxNum int
  41. GotNum int
  42. }
  43. // NewErrEvidenceOverflow returns a new ErrEvidenceOverflow where got > max.
  44. func NewErrEvidenceOverflow(max, got int) *ErrEvidenceOverflow {
  45. return &ErrEvidenceOverflow{max, got}
  46. }
  47. // Error returns a string representation of the error.
  48. func (err *ErrEvidenceOverflow) Error() string {
  49. return fmt.Sprintf("Too much evidence: Max %d, got %d", err.MaxNum, err.GotNum)
  50. }
  51. //-------------------------------------------
  52. // Evidence represents any provable malicious activity by a validator.
  53. type Evidence interface {
  54. Height() int64 // height of the equivocation
  55. Time() time.Time // time of the equivocation
  56. Address() []byte // address of the equivocating validator
  57. Bytes() []byte // bytes which comprise the evidence
  58. Hash() []byte // hash of the evidence
  59. Verify(chainID string, pubKey crypto.PubKey) error // verify the evidence
  60. Equal(Evidence) bool // check equality of evidence
  61. ValidateBasic() error
  62. String() string
  63. }
  64. type CompositeEvidence interface {
  65. VerifyComposite(committedHeader *Header, valSet *ValidatorSet) error
  66. Split(committedHeader *Header, valSet *ValidatorSet, valToLastHeight map[string]int64) []Evidence
  67. }
  68. func RegisterEvidences(cdc *amino.Codec) {
  69. cdc.RegisterInterface((*Evidence)(nil), nil)
  70. cdc.RegisterConcrete(&DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence", nil)
  71. cdc.RegisterConcrete(&ConflictingHeadersEvidence{}, "tendermint/ConflictingHeadersEvidence", nil)
  72. cdc.RegisterConcrete(&PhantomValidatorEvidence{}, "tendermint/PhantomValidatorEvidence", nil)
  73. cdc.RegisterConcrete(&LunaticValidatorEvidence{}, "tendermint/LunaticValidatorEvidence", nil)
  74. cdc.RegisterConcrete(&PotentialAmnesiaEvidence{}, "tendermint/PotentialAmnesiaEvidence", nil)
  75. }
  76. func RegisterMockEvidences(cdc *amino.Codec) {
  77. cdc.RegisterConcrete(MockEvidence{}, "tendermint/MockEvidence", nil)
  78. cdc.RegisterConcrete(MockRandomEvidence{}, "tendermint/MockRandomEvidence", nil)
  79. }
  80. //-------------------------------------------
  81. // DuplicateVoteEvidence contains evidence a validator signed two conflicting
  82. // votes.
  83. type DuplicateVoteEvidence struct {
  84. VoteA *Vote
  85. VoteB *Vote
  86. }
  87. var _ Evidence = &DuplicateVoteEvidence{}
  88. // NewDuplicateVoteEvidence creates DuplicateVoteEvidence with right ordering given
  89. // two conflicting votes. If one of the votes is nil, evidence returned is nil as well
  90. func NewDuplicateVoteEvidence(vote1 *Vote, vote2 *Vote) *DuplicateVoteEvidence {
  91. var voteA, voteB *Vote
  92. if vote1 == nil || vote2 == nil {
  93. return nil
  94. }
  95. if strings.Compare(vote1.BlockID.Key(), vote2.BlockID.Key()) == -1 {
  96. voteA = vote1
  97. voteB = vote2
  98. } else {
  99. voteA = vote2
  100. voteB = vote1
  101. }
  102. return &DuplicateVoteEvidence{
  103. VoteA: voteA,
  104. VoteB: voteB,
  105. }
  106. }
  107. // String returns a string representation of the evidence.
  108. func (dve *DuplicateVoteEvidence) String() string {
  109. return fmt.Sprintf("DuplicateVoteEvidence{VoteA: %v, VoteB: %v}", dve.VoteA, dve.VoteB)
  110. }
  111. // Height returns the height this evidence refers to.
  112. func (dve *DuplicateVoteEvidence) Height() int64 {
  113. return dve.VoteA.Height
  114. }
  115. // Time returns the time the evidence was created.
  116. func (dve *DuplicateVoteEvidence) Time() time.Time {
  117. return dve.VoteA.Timestamp
  118. }
  119. // Address returns the address of the validator.
  120. func (dve *DuplicateVoteEvidence) Address() []byte {
  121. return dve.VoteA.ValidatorAddress
  122. }
  123. // Hash returns the hash of the evidence.
  124. func (dve *DuplicateVoteEvidence) Bytes() []byte {
  125. return cdcEncode(dve)
  126. }
  127. // Hash returns the hash of the evidence.
  128. func (dve *DuplicateVoteEvidence) Hash() []byte {
  129. return tmhash.Sum(cdcEncode(dve))
  130. }
  131. // Verify returns an error if the two votes aren't conflicting.
  132. //
  133. // To be conflicting, they must be from the same validator, for the same H/R/S,
  134. // but for different blocks.
  135. func (dve *DuplicateVoteEvidence) Verify(chainID string, pubKey crypto.PubKey) error {
  136. // H/R/S must be the same
  137. if dve.VoteA.Height != dve.VoteB.Height ||
  138. dve.VoteA.Round != dve.VoteB.Round ||
  139. dve.VoteA.Type != dve.VoteB.Type {
  140. return fmt.Errorf("h/r/s does not match: %d/%d/%v vs %d/%d/%v",
  141. dve.VoteA.Height, dve.VoteA.Round, dve.VoteA.Type,
  142. dve.VoteB.Height, dve.VoteB.Round, dve.VoteB.Type)
  143. }
  144. // Address must be the same
  145. if !bytes.Equal(dve.VoteA.ValidatorAddress, dve.VoteB.ValidatorAddress) {
  146. return fmt.Errorf("validator addresses do not match: %X vs %X",
  147. dve.VoteA.ValidatorAddress,
  148. dve.VoteB.ValidatorAddress,
  149. )
  150. }
  151. // Index must be the same
  152. if dve.VoteA.ValidatorIndex != dve.VoteB.ValidatorIndex {
  153. return fmt.Errorf(
  154. "validator indices do not match: %d and %d",
  155. dve.VoteA.ValidatorIndex,
  156. dve.VoteB.ValidatorIndex,
  157. )
  158. }
  159. // BlockIDs must be different
  160. if dve.VoteA.BlockID.Equals(dve.VoteB.BlockID) {
  161. return fmt.Errorf(
  162. "block IDs are the same (%v) - not a real duplicate vote",
  163. dve.VoteA.BlockID,
  164. )
  165. }
  166. // pubkey must match address (this should already be true, sanity check)
  167. addr := dve.VoteA.ValidatorAddress
  168. if !bytes.Equal(pubKey.Address(), addr) {
  169. return fmt.Errorf("address (%X) doesn't match pubkey (%v - %X)",
  170. addr, pubKey, pubKey.Address())
  171. }
  172. // Signatures must be valid
  173. if !pubKey.VerifyBytes(dve.VoteA.SignBytes(chainID), dve.VoteA.Signature) {
  174. return fmt.Errorf("verifying VoteA: %w", ErrVoteInvalidSignature)
  175. }
  176. if !pubKey.VerifyBytes(dve.VoteB.SignBytes(chainID), dve.VoteB.Signature) {
  177. return fmt.Errorf("verifying VoteB: %w", ErrVoteInvalidSignature)
  178. }
  179. return nil
  180. }
  181. // Equal checks if two pieces of evidence are equal.
  182. func (dve *DuplicateVoteEvidence) Equal(ev Evidence) bool {
  183. if _, ok := ev.(*DuplicateVoteEvidence); !ok {
  184. return false
  185. }
  186. // just check their hashes
  187. dveHash := tmhash.Sum(cdcEncode(dve))
  188. evHash := tmhash.Sum(cdcEncode(ev))
  189. return bytes.Equal(dveHash, evHash)
  190. }
  191. // ValidateBasic performs basic validation.
  192. func (dve *DuplicateVoteEvidence) ValidateBasic() error {
  193. if dve.VoteA == nil || dve.VoteB == nil {
  194. return fmt.Errorf("one or both of the votes are empty %v, %v", dve.VoteA, dve.VoteB)
  195. }
  196. if err := dve.VoteA.ValidateBasic(); err != nil {
  197. return fmt.Errorf("invalid VoteA: %w", err)
  198. }
  199. if err := dve.VoteB.ValidateBasic(); err != nil {
  200. return fmt.Errorf("invalid VoteB: %w", err)
  201. }
  202. // Enforce Votes are lexicographically sorted on blockID
  203. if strings.Compare(dve.VoteA.BlockID.Key(), dve.VoteB.BlockID.Key()) >= 0 {
  204. return errors.New("duplicate votes in invalid order")
  205. }
  206. return nil
  207. }
  208. //-------------------------------------------
  209. // EvidenceList is a list of Evidence. Evidences is not a word.
  210. type EvidenceList []Evidence
  211. // Hash returns the simple merkle root hash of the EvidenceList.
  212. func (evl EvidenceList) Hash() []byte {
  213. // These allocations are required because Evidence is not of type Bytes, and
  214. // golang slices can't be typed cast. This shouldn't be a performance problem since
  215. // the Evidence size is capped.
  216. evidenceBzs := make([][]byte, len(evl))
  217. for i := 0; i < len(evl); i++ {
  218. evidenceBzs[i] = evl[i].Bytes()
  219. }
  220. return merkle.SimpleHashFromByteSlices(evidenceBzs)
  221. }
  222. func (evl EvidenceList) String() string {
  223. s := ""
  224. for _, e := range evl {
  225. s += fmt.Sprintf("%s\t\t", e)
  226. }
  227. return s
  228. }
  229. // Has returns true if the evidence is in the EvidenceList.
  230. func (evl EvidenceList) Has(evidence Evidence) bool {
  231. for _, ev := range evl {
  232. if ev.Equal(evidence) {
  233. return true
  234. }
  235. }
  236. return false
  237. }
  238. //-------------------------------------------
  239. // ConflictingHeadersEvidence is primarily used by the light client when it
  240. // observes two conflicting headers, both having 1/3+ of the voting power of
  241. // the currently trusted validator set.
  242. type ConflictingHeadersEvidence struct {
  243. H1 *SignedHeader `json:"h_1"`
  244. H2 *SignedHeader `json:"h_2"`
  245. }
  246. var _ Evidence = &ConflictingHeadersEvidence{}
  247. var _ CompositeEvidence = &ConflictingHeadersEvidence{}
  248. var _ Evidence = ConflictingHeadersEvidence{}
  249. var _ CompositeEvidence = ConflictingHeadersEvidence{}
  250. // Split breaks up eviddence into smaller chunks (one per validator except for
  251. // PotentialAmnesiaEvidence): PhantomValidatorEvidence,
  252. // LunaticValidatorEvidence, DuplicateVoteEvidence and
  253. // PotentialAmnesiaEvidence.
  254. //
  255. // committedHeader - header at height H1.Height == H2.Height
  256. // valSet - validator set at height H1.Height == H2.Height
  257. // valToLastHeight - map between active validators and respective last heights
  258. func (ev ConflictingHeadersEvidence) Split(committedHeader *Header, valSet *ValidatorSet,
  259. valToLastHeight map[string]int64) []Evidence {
  260. evList := make([]Evidence, 0)
  261. var alternativeHeader *SignedHeader
  262. if bytes.Equal(committedHeader.Hash(), ev.H1.Hash()) {
  263. alternativeHeader = ev.H2
  264. } else {
  265. alternativeHeader = ev.H1
  266. }
  267. // If there are signers(alternativeHeader) that are not part of
  268. // validators(committedHeader), they misbehaved as they are signing protocol
  269. // messages in heights they are not validators => immediately slashable
  270. // (#F4).
  271. for i, sig := range alternativeHeader.Commit.Signatures {
  272. if sig.Absent() {
  273. continue
  274. }
  275. lastHeightValidatorWasInSet, ok := valToLastHeight[string(sig.ValidatorAddress)]
  276. if !ok {
  277. continue
  278. }
  279. if !valSet.HasAddress(sig.ValidatorAddress) {
  280. evList = append(evList, &PhantomValidatorEvidence{
  281. Header: alternativeHeader.Header,
  282. Vote: alternativeHeader.Commit.GetVote(i),
  283. LastHeightValidatorWasInSet: lastHeightValidatorWasInSet,
  284. })
  285. }
  286. }
  287. // If ValidatorsHash, NextValidatorsHash, ConsensusHash, AppHash, and
  288. // LastResultsHash in alternativeHeader are different (incorrect application
  289. // state transition), then it is a lunatic misbehavior => immediately
  290. // slashable (#F5).
  291. var invalidField string
  292. switch {
  293. case !bytes.Equal(committedHeader.ValidatorsHash, alternativeHeader.ValidatorsHash):
  294. invalidField = "ValidatorsHash"
  295. case !bytes.Equal(committedHeader.NextValidatorsHash, alternativeHeader.NextValidatorsHash):
  296. invalidField = "NextValidatorsHash"
  297. case !bytes.Equal(committedHeader.ConsensusHash, alternativeHeader.ConsensusHash):
  298. invalidField = "ConsensusHash"
  299. case !bytes.Equal(committedHeader.AppHash, alternativeHeader.AppHash):
  300. invalidField = "AppHash"
  301. case !bytes.Equal(committedHeader.LastResultsHash, alternativeHeader.LastResultsHash):
  302. invalidField = "LastResultsHash"
  303. }
  304. if invalidField != "" {
  305. for i, sig := range alternativeHeader.Commit.Signatures {
  306. if sig.Absent() {
  307. continue
  308. }
  309. evList = append(evList, &LunaticValidatorEvidence{
  310. Header: alternativeHeader.Header,
  311. Vote: alternativeHeader.Commit.GetVote(i),
  312. InvalidHeaderField: invalidField,
  313. })
  314. }
  315. return evList
  316. }
  317. // Use the fact that signatures are sorted by ValidatorAddress.
  318. var (
  319. i = 0
  320. j = 0
  321. )
  322. OUTER_LOOP:
  323. for i < len(ev.H1.Commit.Signatures) {
  324. sigA := ev.H1.Commit.Signatures[i]
  325. if sigA.Absent() {
  326. i++
  327. continue
  328. }
  329. // FIXME: Replace with HasAddress once DuplicateVoteEvidence#PubKey is
  330. // removed.
  331. _, val := valSet.GetByAddress(sigA.ValidatorAddress)
  332. if val == nil {
  333. i++
  334. continue
  335. }
  336. for j < len(ev.H2.Commit.Signatures) {
  337. sigB := ev.H2.Commit.Signatures[j]
  338. if sigB.Absent() {
  339. j++
  340. continue
  341. }
  342. switch bytes.Compare(sigA.ValidatorAddress, sigB.ValidatorAddress) {
  343. case 0:
  344. // if H1.Round == H2.Round, and some signers signed different precommit
  345. // messages in both commits, then it is an equivocation misbehavior =>
  346. // immediately slashable (#F1).
  347. if ev.H1.Commit.Round == ev.H2.Commit.Round {
  348. evList = append(evList, &DuplicateVoteEvidence{
  349. VoteA: ev.H1.Commit.GetVote(i),
  350. VoteB: ev.H2.Commit.GetVote(j),
  351. })
  352. } else {
  353. // if H1.Round != H2.Round we need to run full detection procedure => not
  354. // immediately slashable.
  355. evList = append(evList, &PotentialAmnesiaEvidence{
  356. VoteA: ev.H1.Commit.GetVote(i),
  357. VoteB: ev.H2.Commit.GetVote(j),
  358. })
  359. }
  360. i++
  361. j++
  362. continue OUTER_LOOP
  363. case 1:
  364. i++
  365. continue OUTER_LOOP
  366. case -1:
  367. j++
  368. }
  369. }
  370. }
  371. return evList
  372. }
  373. func (ev ConflictingHeadersEvidence) Height() int64 { return ev.H1.Height }
  374. // XXX: this is not the time of equivocation
  375. func (ev ConflictingHeadersEvidence) Time() time.Time { return ev.H1.Time }
  376. func (ev ConflictingHeadersEvidence) Address() []byte {
  377. panic("use ConflictingHeadersEvidence#Split to split evidence into individual pieces")
  378. }
  379. func (ev ConflictingHeadersEvidence) Bytes() []byte {
  380. return cdcEncode(ev)
  381. }
  382. func (ev ConflictingHeadersEvidence) Hash() []byte {
  383. bz := make([]byte, tmhash.Size*2)
  384. copy(bz[:tmhash.Size-1], ev.H1.Hash().Bytes())
  385. copy(bz[tmhash.Size:], ev.H2.Hash().Bytes())
  386. return tmhash.Sum(bz)
  387. }
  388. func (ev ConflictingHeadersEvidence) Verify(chainID string, _ crypto.PubKey) error {
  389. panic("use ConflictingHeadersEvidence#VerifyComposite to verify composite evidence")
  390. }
  391. // VerifyComposite verifies that both headers belong to the same chain, same
  392. // height and signed by 1/3+ of validators at height H1.Height == H2.Height.
  393. func (ev ConflictingHeadersEvidence) VerifyComposite(committedHeader *Header, valSet *ValidatorSet) error {
  394. var alternativeHeader *SignedHeader
  395. switch {
  396. case bytes.Equal(committedHeader.Hash(), ev.H1.Hash()):
  397. alternativeHeader = ev.H2
  398. case bytes.Equal(committedHeader.Hash(), ev.H2.Hash()):
  399. alternativeHeader = ev.H1
  400. default:
  401. return errors.New("none of the headers are committed from this node's perspective")
  402. }
  403. // ChainID must be the same
  404. if committedHeader.ChainID != alternativeHeader.ChainID {
  405. return errors.New("alt header is from a different chain")
  406. }
  407. // Height must be the same
  408. if committedHeader.Height != alternativeHeader.Height {
  409. return errors.New("alt header is from a different height")
  410. }
  411. // Limit the number of signatures to avoid DoS attacks where a header
  412. // contains too many signatures.
  413. //
  414. // Validator set size = 100 [node]
  415. // Max validator set size = 100 * 2 = 200 [fork?]
  416. maxNumValidators := valSet.Size() * 2
  417. if len(alternativeHeader.Commit.Signatures) > maxNumValidators {
  418. return errors.Errorf("alt commit contains too many signatures: %d, expected no more than %d",
  419. len(alternativeHeader.Commit.Signatures),
  420. maxNumValidators)
  421. }
  422. // Header must be signed by at least 1/3+ of voting power of currently
  423. // trusted validator set.
  424. if err := valSet.VerifyCommitTrusting(
  425. alternativeHeader.ChainID,
  426. alternativeHeader.Commit,
  427. tmmath.Fraction{Numerator: 1, Denominator: 3}); err != nil {
  428. return errors.Wrap(err, "alt header does not have 1/3+ of voting power of our validator set")
  429. }
  430. return nil
  431. }
  432. func (ev ConflictingHeadersEvidence) Equal(ev2 Evidence) bool {
  433. switch e2 := ev2.(type) {
  434. case ConflictingHeadersEvidence:
  435. return bytes.Equal(ev.H1.Hash(), e2.H1.Hash()) && bytes.Equal(ev.H2.Hash(), e2.H2.Hash())
  436. case *ConflictingHeadersEvidence:
  437. return bytes.Equal(ev.H1.Hash(), e2.H1.Hash()) && bytes.Equal(ev.H2.Hash(), e2.H2.Hash())
  438. default:
  439. return false
  440. }
  441. }
  442. func (ev ConflictingHeadersEvidence) ValidateBasic() error {
  443. if ev.H1 == nil {
  444. return errors.New("first header is missing")
  445. }
  446. if ev.H2 == nil {
  447. return errors.New("second header is missing")
  448. }
  449. if err := ev.H1.ValidateBasic(ev.H1.ChainID); err != nil {
  450. return fmt.Errorf("h1: %w", err)
  451. }
  452. if err := ev.H2.ValidateBasic(ev.H2.ChainID); err != nil {
  453. return fmt.Errorf("h2: %w", err)
  454. }
  455. return nil
  456. }
  457. func (ev ConflictingHeadersEvidence) String() string {
  458. return fmt.Sprintf("ConflictingHeadersEvidence{H1: %d#%X, H2: %d#%X}",
  459. ev.H1.Height, ev.H1.Hash(),
  460. ev.H2.Height, ev.H2.Hash())
  461. }
  462. //-------------------------------------------
  463. type PhantomValidatorEvidence struct {
  464. Header *Header `json:"header"`
  465. Vote *Vote `json:"vote"`
  466. LastHeightValidatorWasInSet int64 `json:"last_height_validator_was_in_set"`
  467. }
  468. var _ Evidence = &PhantomValidatorEvidence{}
  469. var _ Evidence = PhantomValidatorEvidence{}
  470. func (e PhantomValidatorEvidence) Height() int64 {
  471. return e.Header.Height
  472. }
  473. func (e PhantomValidatorEvidence) Time() time.Time {
  474. return e.Header.Time
  475. }
  476. func (e PhantomValidatorEvidence) Address() []byte {
  477. return e.Vote.ValidatorAddress
  478. }
  479. func (e PhantomValidatorEvidence) Hash() []byte {
  480. bz := make([]byte, tmhash.Size+crypto.AddressSize)
  481. copy(bz[:tmhash.Size-1], e.Header.Hash().Bytes())
  482. copy(bz[tmhash.Size:], e.Vote.ValidatorAddress.Bytes())
  483. return tmhash.Sum(bz)
  484. }
  485. func (e PhantomValidatorEvidence) Bytes() []byte {
  486. return cdcEncode(e)
  487. }
  488. func (e PhantomValidatorEvidence) Verify(chainID string, pubKey crypto.PubKey) error {
  489. // chainID must be the same
  490. if chainID != e.Header.ChainID {
  491. return fmt.Errorf("chainID do not match: %s vs %s",
  492. chainID,
  493. e.Header.ChainID,
  494. )
  495. }
  496. if !pubKey.VerifyBytes(e.Vote.SignBytes(chainID), e.Vote.Signature) {
  497. return errors.New("invalid signature")
  498. }
  499. return nil
  500. }
  501. func (e PhantomValidatorEvidence) Equal(ev Evidence) bool {
  502. switch e2 := ev.(type) {
  503. case PhantomValidatorEvidence:
  504. return bytes.Equal(e.Header.Hash(), e2.Header.Hash()) &&
  505. bytes.Equal(e.Vote.ValidatorAddress, e2.Vote.ValidatorAddress)
  506. case *PhantomValidatorEvidence:
  507. return bytes.Equal(e.Header.Hash(), e2.Header.Hash()) &&
  508. bytes.Equal(e.Vote.ValidatorAddress, e2.Vote.ValidatorAddress)
  509. default:
  510. return false
  511. }
  512. }
  513. func (e PhantomValidatorEvidence) ValidateBasic() error {
  514. if e.Header == nil {
  515. return errors.New("empty header")
  516. }
  517. if e.Vote == nil {
  518. return errors.New("empty vote")
  519. }
  520. if err := e.Header.ValidateBasic(); err != nil {
  521. return fmt.Errorf("invalid header: %v", err)
  522. }
  523. if err := e.Vote.ValidateBasic(); err != nil {
  524. return fmt.Errorf("invalid signature: %v", err)
  525. }
  526. if !e.Vote.BlockID.IsComplete() {
  527. return errors.New("expected vote for block")
  528. }
  529. if e.Header.Height != e.Vote.Height {
  530. return fmt.Errorf("header and vote have different heights: %d vs %d",
  531. e.Header.Height,
  532. e.Vote.Height,
  533. )
  534. }
  535. if e.LastHeightValidatorWasInSet <= 0 {
  536. return errors.New("negative or zero LastHeightValidatorWasInSet")
  537. }
  538. return nil
  539. }
  540. func (e PhantomValidatorEvidence) String() string {
  541. return fmt.Sprintf("PhantomValidatorEvidence{%X voted for %d/%X}",
  542. e.Vote.ValidatorAddress, e.Header.Height, e.Header.Hash())
  543. }
  544. //-------------------------------------------
  545. type LunaticValidatorEvidence struct {
  546. Header *Header `json:"header"`
  547. Vote *Vote `json:"vote"`
  548. InvalidHeaderField string `json:"invalid_header_field"`
  549. }
  550. var _ Evidence = &LunaticValidatorEvidence{}
  551. var _ Evidence = LunaticValidatorEvidence{}
  552. func (e LunaticValidatorEvidence) Height() int64 {
  553. return e.Header.Height
  554. }
  555. func (e LunaticValidatorEvidence) Time() time.Time {
  556. return e.Header.Time
  557. }
  558. func (e LunaticValidatorEvidence) Address() []byte {
  559. return e.Vote.ValidatorAddress
  560. }
  561. func (e LunaticValidatorEvidence) Hash() []byte {
  562. bz := make([]byte, tmhash.Size+crypto.AddressSize)
  563. copy(bz[:tmhash.Size-1], e.Header.Hash().Bytes())
  564. copy(bz[tmhash.Size:], e.Vote.ValidatorAddress.Bytes())
  565. return tmhash.Sum(bz)
  566. }
  567. func (e LunaticValidatorEvidence) Bytes() []byte {
  568. return cdcEncode(e)
  569. }
  570. func (e LunaticValidatorEvidence) Verify(chainID string, pubKey crypto.PubKey) error {
  571. // chainID must be the same
  572. if chainID != e.Header.ChainID {
  573. return fmt.Errorf("chainID do not match: %s vs %s",
  574. chainID,
  575. e.Header.ChainID,
  576. )
  577. }
  578. if !pubKey.VerifyBytes(e.Vote.SignBytes(chainID), e.Vote.Signature) {
  579. return errors.New("invalid signature")
  580. }
  581. return nil
  582. }
  583. func (e LunaticValidatorEvidence) Equal(ev Evidence) bool {
  584. switch e2 := ev.(type) {
  585. case LunaticValidatorEvidence:
  586. return bytes.Equal(e.Header.Hash(), e2.Header.Hash()) &&
  587. bytes.Equal(e.Vote.ValidatorAddress, e2.Vote.ValidatorAddress)
  588. case *LunaticValidatorEvidence:
  589. return bytes.Equal(e.Header.Hash(), e2.Header.Hash()) &&
  590. bytes.Equal(e.Vote.ValidatorAddress, e2.Vote.ValidatorAddress)
  591. default:
  592. return false
  593. }
  594. }
  595. func (e LunaticValidatorEvidence) ValidateBasic() error {
  596. if e.Header == nil {
  597. return errors.New("empty header")
  598. }
  599. if e.Vote == nil {
  600. return errors.New("empty vote")
  601. }
  602. if err := e.Header.ValidateBasic(); err != nil {
  603. return fmt.Errorf("invalid header: %v", err)
  604. }
  605. if err := e.Vote.ValidateBasic(); err != nil {
  606. return fmt.Errorf("invalid signature: %v", err)
  607. }
  608. if !e.Vote.BlockID.IsComplete() {
  609. return errors.New("expected vote for block")
  610. }
  611. if e.Header.Height != e.Vote.Height {
  612. return fmt.Errorf("header and vote have different heights: %d vs %d",
  613. e.Header.Height,
  614. e.Vote.Height,
  615. )
  616. }
  617. switch e.InvalidHeaderField {
  618. case "ValidatorsHash", "NextValidatorsHash", "ConsensusHash", "AppHash", "LastResultsHash":
  619. return nil
  620. default:
  621. return errors.New("unknown invalid header field")
  622. }
  623. }
  624. func (e LunaticValidatorEvidence) String() string {
  625. return fmt.Sprintf("LunaticValidatorEvidence{%X voted for %d/%X, which contains invalid %s}",
  626. e.Vote.ValidatorAddress, e.Header.Height, e.Header.Hash(), e.InvalidHeaderField)
  627. }
  628. func (e LunaticValidatorEvidence) VerifyHeader(committedHeader *Header) error {
  629. matchErr := func(field string) error {
  630. return fmt.Errorf("%s matches committed hash", field)
  631. }
  632. switch e.InvalidHeaderField {
  633. case ValidatorsHashField:
  634. if bytes.Equal(committedHeader.ValidatorsHash, e.Header.ValidatorsHash) {
  635. return matchErr(ValidatorsHashField)
  636. }
  637. case NextValidatorsHashField:
  638. if bytes.Equal(committedHeader.NextValidatorsHash, e.Header.NextValidatorsHash) {
  639. return matchErr(NextValidatorsHashField)
  640. }
  641. case ConsensusHashField:
  642. if bytes.Equal(committedHeader.ConsensusHash, e.Header.ConsensusHash) {
  643. return matchErr(ConsensusHashField)
  644. }
  645. case AppHashField:
  646. if bytes.Equal(committedHeader.AppHash, e.Header.AppHash) {
  647. return matchErr(AppHashField)
  648. }
  649. case LastResultsHashField:
  650. if bytes.Equal(committedHeader.LastResultsHash, e.Header.LastResultsHash) {
  651. return matchErr(LastResultsHashField)
  652. }
  653. default:
  654. return errors.New("unknown InvalidHeaderField")
  655. }
  656. return nil
  657. }
  658. //-------------------------------------------
  659. type PotentialAmnesiaEvidence struct {
  660. VoteA *Vote `json:"vote_a"`
  661. VoteB *Vote `json:"vote_b"`
  662. }
  663. var _ Evidence = &PotentialAmnesiaEvidence{}
  664. var _ Evidence = PotentialAmnesiaEvidence{}
  665. func (e PotentialAmnesiaEvidence) Height() int64 {
  666. return e.VoteA.Height
  667. }
  668. func (e PotentialAmnesiaEvidence) Time() time.Time {
  669. if e.VoteA.Timestamp.Before(e.VoteB.Timestamp) {
  670. return e.VoteA.Timestamp
  671. }
  672. return e.VoteB.Timestamp
  673. }
  674. func (e PotentialAmnesiaEvidence) Address() []byte {
  675. return e.VoteA.ValidatorAddress
  676. }
  677. func (e PotentialAmnesiaEvidence) Hash() []byte {
  678. return tmhash.Sum(cdcEncode(e))
  679. }
  680. func (e PotentialAmnesiaEvidence) Bytes() []byte {
  681. return cdcEncode(e)
  682. }
  683. func (e PotentialAmnesiaEvidence) Verify(chainID string, pubKey crypto.PubKey) error {
  684. // pubkey must match address (this should already be true, sanity check)
  685. addr := e.VoteA.ValidatorAddress
  686. if !bytes.Equal(pubKey.Address(), addr) {
  687. return fmt.Errorf("address (%X) doesn't match pubkey (%v - %X)",
  688. addr, pubKey, pubKey.Address())
  689. }
  690. // Signatures must be valid
  691. if !pubKey.VerifyBytes(e.VoteA.SignBytes(chainID), e.VoteA.Signature) {
  692. return fmt.Errorf("verifying VoteA: %w", ErrVoteInvalidSignature)
  693. }
  694. if !pubKey.VerifyBytes(e.VoteB.SignBytes(chainID), e.VoteB.Signature) {
  695. return fmt.Errorf("verifying VoteB: %w", ErrVoteInvalidSignature)
  696. }
  697. return nil
  698. }
  699. func (e PotentialAmnesiaEvidence) Equal(ev Evidence) bool {
  700. switch e2 := ev.(type) {
  701. case PotentialAmnesiaEvidence:
  702. return bytes.Equal(e.Hash(), e2.Hash())
  703. case *PotentialAmnesiaEvidence:
  704. return bytes.Equal(e.Hash(), e2.Hash())
  705. default:
  706. return false
  707. }
  708. }
  709. func (e PotentialAmnesiaEvidence) ValidateBasic() error {
  710. if e.VoteA == nil || e.VoteB == nil {
  711. return fmt.Errorf("one or both of the votes are empty %v, %v", e.VoteA, e.VoteB)
  712. }
  713. if err := e.VoteA.ValidateBasic(); err != nil {
  714. return fmt.Errorf("invalid VoteA: %v", err)
  715. }
  716. if err := e.VoteB.ValidateBasic(); err != nil {
  717. return fmt.Errorf("invalid VoteB: %v", err)
  718. }
  719. // Enforce Votes are lexicographically sorted on blockID
  720. if strings.Compare(e.VoteA.BlockID.Key(), e.VoteB.BlockID.Key()) >= 0 {
  721. return errors.New("amnesia votes in invalid order")
  722. }
  723. // H/S must be the same
  724. if e.VoteA.Height != e.VoteB.Height ||
  725. e.VoteA.Type != e.VoteB.Type {
  726. return fmt.Errorf("h/s do not match: %d/%v vs %d/%v",
  727. e.VoteA.Height, e.VoteA.Type, e.VoteB.Height, e.VoteB.Type)
  728. }
  729. // R must be different
  730. if e.VoteA.Round == e.VoteB.Round {
  731. return fmt.Errorf("expected votes from different rounds, got %d", e.VoteA.Round)
  732. }
  733. // Address must be the same
  734. if !bytes.Equal(e.VoteA.ValidatorAddress, e.VoteB.ValidatorAddress) {
  735. return fmt.Errorf("validator addresses do not match: %X vs %X",
  736. e.VoteA.ValidatorAddress,
  737. e.VoteB.ValidatorAddress,
  738. )
  739. }
  740. // Index must be the same
  741. // https://github.com/tendermint/tendermint/issues/4619
  742. if e.VoteA.ValidatorIndex != e.VoteB.ValidatorIndex {
  743. return fmt.Errorf(
  744. "duplicateVoteEvidence Error: Validator indices do not match. Got %d and %d",
  745. e.VoteA.ValidatorIndex,
  746. e.VoteB.ValidatorIndex,
  747. )
  748. }
  749. // BlockIDs must be different
  750. if e.VoteA.BlockID.Equals(e.VoteB.BlockID) {
  751. return fmt.Errorf(
  752. "block IDs are the same (%v) - not a real duplicate vote",
  753. e.VoteA.BlockID,
  754. )
  755. }
  756. return nil
  757. }
  758. func (e PotentialAmnesiaEvidence) String() string {
  759. return fmt.Sprintf("PotentialAmnesiaEvidence{VoteA: %v, VoteB: %v}", e.VoteA, e.VoteB)
  760. }
  761. //-----------------------------------------------------------------
  762. // UNSTABLE
  763. type MockRandomEvidence struct {
  764. MockEvidence
  765. randBytes []byte
  766. }
  767. var _ Evidence = &MockRandomEvidence{}
  768. // UNSTABLE
  769. func NewMockRandomEvidence(height int64, eTime time.Time, address []byte, randBytes []byte) MockRandomEvidence {
  770. return MockRandomEvidence{
  771. MockEvidence{
  772. EvidenceHeight: height,
  773. EvidenceTime: eTime,
  774. EvidenceAddress: address}, randBytes,
  775. }
  776. }
  777. func (e MockRandomEvidence) Hash() []byte {
  778. return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.randBytes))
  779. }
  780. // UNSTABLE
  781. type MockEvidence struct {
  782. EvidenceHeight int64
  783. EvidenceTime time.Time
  784. EvidenceAddress []byte
  785. }
  786. var _ Evidence = &MockEvidence{}
  787. // UNSTABLE
  788. func NewMockEvidence(height int64, eTime time.Time, address []byte) MockEvidence {
  789. return MockEvidence{
  790. EvidenceHeight: height,
  791. EvidenceTime: eTime,
  792. EvidenceAddress: address}
  793. }
  794. func (e MockEvidence) Height() int64 { return e.EvidenceHeight }
  795. func (e MockEvidence) Time() time.Time { return e.EvidenceTime }
  796. func (e MockEvidence) Address() []byte { return e.EvidenceAddress }
  797. func (e MockEvidence) Hash() []byte {
  798. return []byte(fmt.Sprintf("%d-%x-%s",
  799. e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime))
  800. }
  801. func (e MockEvidence) Bytes() []byte {
  802. return []byte(fmt.Sprintf("%d-%x-%s",
  803. e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime))
  804. }
  805. func (e MockEvidence) Verify(chainID string, pubKey crypto.PubKey) error { return nil }
  806. func (e MockEvidence) Equal(ev Evidence) bool {
  807. e2 := ev.(MockEvidence)
  808. return e.EvidenceHeight == e2.EvidenceHeight &&
  809. bytes.Equal(e.EvidenceAddress, e2.EvidenceAddress)
  810. }
  811. func (e MockEvidence) ValidateBasic() error { return nil }
  812. func (e MockEvidence) String() string {
  813. return fmt.Sprintf("Evidence: %d/%s/%s", e.EvidenceHeight, e.Time(), e.EvidenceAddress)
  814. }