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.

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