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.

343 lines
10 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. amino "github.com/tendermint/go-amino"
  10. "github.com/tendermint/tendermint/crypto"
  11. "github.com/tendermint/tendermint/crypto/merkle"
  12. )
  13. const (
  14. // MaxEvidenceBytes is a maximum size of any evidence (including amino overhead).
  15. MaxEvidenceBytes int64 = 484
  16. )
  17. // ErrEvidenceInvalid wraps a piece of evidence and the error denoting how or why it is invalid.
  18. type ErrEvidenceInvalid struct {
  19. Evidence Evidence
  20. ErrorValue error
  21. }
  22. // NewErrEvidenceInvalid returns a new EvidenceInvalid with the given err.
  23. func NewErrEvidenceInvalid(ev Evidence, err error) *ErrEvidenceInvalid {
  24. return &ErrEvidenceInvalid{ev, err}
  25. }
  26. // Error returns a string representation of the error.
  27. func (err *ErrEvidenceInvalid) Error() string {
  28. return fmt.Sprintf("Invalid evidence: %v. Evidence: %v", err.ErrorValue, err.Evidence)
  29. }
  30. // ErrEvidenceOverflow is for when there is too much evidence in a block.
  31. type ErrEvidenceOverflow struct {
  32. MaxNum int64
  33. GotNum int64
  34. }
  35. // NewErrEvidenceOverflow returns a new ErrEvidenceOverflow where got > max.
  36. func NewErrEvidenceOverflow(max, got int64) *ErrEvidenceOverflow {
  37. return &ErrEvidenceOverflow{max, got}
  38. }
  39. // Error returns a string representation of the error.
  40. func (err *ErrEvidenceOverflow) Error() string {
  41. return fmt.Sprintf("Too much evidence: Max %d, got %d", err.MaxNum, err.GotNum)
  42. }
  43. //-------------------------------------------
  44. // Evidence represents any provable malicious activity by a validator
  45. type Evidence interface {
  46. Height() int64 // height of the equivocation
  47. Time() time.Time // time of the equivocation
  48. Address() []byte // address of the equivocating validator
  49. Bytes() []byte // bytes which comprise the evidence
  50. Hash() []byte // hash of the evidence
  51. Verify(chainID string, pubKey crypto.PubKey) error // verify the evidence
  52. Equal(Evidence) bool // check equality of evidence
  53. ValidateBasic() error
  54. String() string
  55. }
  56. func RegisterEvidences(cdc *amino.Codec) {
  57. cdc.RegisterInterface((*Evidence)(nil), nil)
  58. cdc.RegisterConcrete(&DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence", nil)
  59. }
  60. func RegisterMockEvidences(cdc *amino.Codec) {
  61. cdc.RegisterConcrete(MockEvidence{}, "tendermint/MockEvidence", nil)
  62. cdc.RegisterConcrete(MockRandomEvidence{}, "tendermint/MockRandomEvidence", nil)
  63. }
  64. const (
  65. MaxEvidenceBytesDenominator = 10
  66. )
  67. // MaxEvidencePerBlock returns the maximum number of evidences
  68. // allowed in the block and their maximum total size (limitted to 1/10th
  69. // of the maximum block size).
  70. // TODO: change to a constant, or to a fraction of the validator set size.
  71. // See https://github.com/tendermint/tendermint/issues/2590
  72. func MaxEvidencePerBlock(blockMaxBytes int64) (int64, int64) {
  73. maxBytes := blockMaxBytes / MaxEvidenceBytesDenominator
  74. maxNum := maxBytes / MaxEvidenceBytes
  75. return maxNum, maxBytes
  76. }
  77. //-------------------------------------------
  78. // DuplicateVoteEvidence contains evidence a validator signed two conflicting
  79. // votes.
  80. type DuplicateVoteEvidence struct {
  81. PubKey crypto.PubKey
  82. VoteA *Vote
  83. VoteB *Vote
  84. }
  85. var _ Evidence = &DuplicateVoteEvidence{}
  86. // NewDuplicateVoteEvidence creates DuplicateVoteEvidence with right ordering given
  87. // two conflicting votes. If one of the votes is nil, evidence returned is nil as well
  88. func NewDuplicateVoteEvidence(pubkey crypto.PubKey, vote1 *Vote, vote2 *Vote) *DuplicateVoteEvidence {
  89. var voteA, voteB *Vote
  90. if vote1 == nil || vote2 == nil {
  91. return nil
  92. }
  93. if strings.Compare(vote1.BlockID.Key(), vote2.BlockID.Key()) == -1 {
  94. voteA = vote1
  95. voteB = vote2
  96. } else {
  97. voteA = vote2
  98. voteB = vote1
  99. }
  100. return &DuplicateVoteEvidence{
  101. PubKey: pubkey,
  102. VoteA: voteA,
  103. VoteB: voteB,
  104. }
  105. }
  106. // String returns a string representation of the evidence.
  107. func (dve *DuplicateVoteEvidence) String() string {
  108. return fmt.Sprintf("VoteA: %v; VoteB: %v", dve.VoteA, dve.VoteB)
  109. }
  110. // Height returns the height this evidence refers to.
  111. func (dve *DuplicateVoteEvidence) Height() int64 {
  112. return dve.VoteA.Height
  113. }
  114. // Time return the time the evidence was created
  115. func (dve *DuplicateVoteEvidence) Time() time.Time {
  116. return dve.VoteA.Timestamp
  117. }
  118. // Address returns the address of the validator.
  119. func (dve *DuplicateVoteEvidence) Address() []byte {
  120. return dve.PubKey.Address()
  121. }
  122. // Hash returns the hash of the evidence.
  123. func (dve *DuplicateVoteEvidence) Bytes() []byte {
  124. return cdcEncode(dve)
  125. }
  126. // Hash returns the hash of the evidence.
  127. func (dve *DuplicateVoteEvidence) Hash() []byte {
  128. return tmhash.Sum(cdcEncode(dve))
  129. }
  130. // Verify returns an error if the two votes aren't conflicting.
  131. // To be conflicting, they must be from the same validator, for the same H/R/S, but for different blocks.
  132. func (dve *DuplicateVoteEvidence) Verify(chainID string, pubKey crypto.PubKey) error {
  133. // H/R/S must be the same
  134. if dve.VoteA.Height != dve.VoteB.Height ||
  135. dve.VoteA.Round != dve.VoteB.Round ||
  136. dve.VoteA.Type != dve.VoteB.Type {
  137. return fmt.Errorf("duplicateVoteEvidence Error: H/R/S does not match. Got %v and %v", dve.VoteA, dve.VoteB)
  138. }
  139. // Address must be the same
  140. if !bytes.Equal(dve.VoteA.ValidatorAddress, dve.VoteB.ValidatorAddress) {
  141. return fmt.Errorf(
  142. "duplicateVoteEvidence Error: Validator addresses do not match. Got %X and %X",
  143. dve.VoteA.ValidatorAddress,
  144. dve.VoteB.ValidatorAddress,
  145. )
  146. }
  147. // Index must be the same
  148. if dve.VoteA.ValidatorIndex != dve.VoteB.ValidatorIndex {
  149. return fmt.Errorf(
  150. "duplicateVoteEvidence Error: Validator indices do not match. Got %d and %d",
  151. dve.VoteA.ValidatorIndex,
  152. dve.VoteB.ValidatorIndex,
  153. )
  154. }
  155. // BlockIDs must be different
  156. if dve.VoteA.BlockID.Equals(dve.VoteB.BlockID) {
  157. return fmt.Errorf(
  158. "duplicateVoteEvidence Error: BlockIDs are the same (%v) - not a real duplicate vote",
  159. dve.VoteA.BlockID,
  160. )
  161. }
  162. // pubkey must match address (this should already be true, sanity check)
  163. addr := dve.VoteA.ValidatorAddress
  164. if !bytes.Equal(pubKey.Address(), addr) {
  165. return fmt.Errorf("duplicateVoteEvidence FAILED SANITY CHECK - address (%X) doesn't match pubkey (%v - %X)",
  166. addr, pubKey, pubKey.Address())
  167. }
  168. // Signatures must be valid
  169. if !pubKey.VerifyBytes(dve.VoteA.SignBytes(chainID), dve.VoteA.Signature) {
  170. return fmt.Errorf("duplicateVoteEvidence Error verifying VoteA: %v", ErrVoteInvalidSignature)
  171. }
  172. if !pubKey.VerifyBytes(dve.VoteB.SignBytes(chainID), dve.VoteB.Signature) {
  173. return fmt.Errorf("duplicateVoteEvidence Error verifying VoteB: %v", ErrVoteInvalidSignature)
  174. }
  175. return nil
  176. }
  177. // Equal checks if two pieces of evidence are equal.
  178. func (dve *DuplicateVoteEvidence) Equal(ev Evidence) bool {
  179. if _, ok := ev.(*DuplicateVoteEvidence); !ok {
  180. return false
  181. }
  182. // just check their hashes
  183. dveHash := tmhash.Sum(cdcEncode(dve))
  184. evHash := tmhash.Sum(cdcEncode(ev))
  185. return bytes.Equal(dveHash, evHash)
  186. }
  187. // ValidateBasic performs basic validation.
  188. func (dve *DuplicateVoteEvidence) ValidateBasic() error {
  189. if len(dve.PubKey.Bytes()) == 0 {
  190. return errors.New("empty PubKey")
  191. }
  192. if dve.VoteA == nil || dve.VoteB == nil {
  193. return fmt.Errorf("one or both of the votes are empty %v, %v", dve.VoteA, dve.VoteB)
  194. }
  195. if err := dve.VoteA.ValidateBasic(); err != nil {
  196. return fmt.Errorf("invalid VoteA: %v", err)
  197. }
  198. if err := dve.VoteB.ValidateBasic(); err != nil {
  199. return fmt.Errorf("invalid VoteB: %v", err)
  200. }
  201. // Enforce Votes are lexicographically sorted on blockID
  202. if strings.Compare(dve.VoteA.BlockID.Key(), dve.VoteB.BlockID.Key()) >= 0 {
  203. return errors.New("duplicate votes in invalid order")
  204. }
  205. return nil
  206. }
  207. //-----------------------------------------------------------------
  208. // UNSTABLE
  209. type MockRandomEvidence struct {
  210. MockEvidence
  211. randBytes []byte
  212. }
  213. var _ Evidence = &MockRandomEvidence{}
  214. // UNSTABLE
  215. func NewMockRandomEvidence(height int64, eTime time.Time, address []byte, randBytes []byte) MockRandomEvidence {
  216. return MockRandomEvidence{
  217. MockEvidence{
  218. EvidenceHeight: height,
  219. EvidenceTime: eTime,
  220. EvidenceAddress: address}, randBytes,
  221. }
  222. }
  223. func (e MockRandomEvidence) Hash() []byte {
  224. return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.randBytes))
  225. }
  226. // UNSTABLE
  227. type MockEvidence struct {
  228. EvidenceHeight int64
  229. EvidenceTime time.Time
  230. EvidenceAddress []byte
  231. }
  232. var _ Evidence = &MockEvidence{}
  233. // UNSTABLE
  234. func NewMockEvidence(height int64, eTime time.Time, idx int, address []byte) MockEvidence {
  235. return MockEvidence{
  236. EvidenceHeight: height,
  237. EvidenceTime: eTime,
  238. EvidenceAddress: address}
  239. }
  240. func (e MockEvidence) Height() int64 { return e.EvidenceHeight }
  241. func (e MockEvidence) Time() time.Time { return e.EvidenceTime }
  242. func (e MockEvidence) Address() []byte { return e.EvidenceAddress }
  243. func (e MockEvidence) Hash() []byte {
  244. return []byte(fmt.Sprintf("%d-%x-%s",
  245. e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime))
  246. }
  247. func (e MockEvidence) Bytes() []byte {
  248. return []byte(fmt.Sprintf("%d-%x-%s",
  249. e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime))
  250. }
  251. func (e MockEvidence) Verify(chainID string, pubKey crypto.PubKey) error { return nil }
  252. func (e MockEvidence) Equal(ev Evidence) bool {
  253. e2 := ev.(MockEvidence)
  254. return e.EvidenceHeight == e2.EvidenceHeight &&
  255. bytes.Equal(e.EvidenceAddress, e2.EvidenceAddress)
  256. }
  257. func (e MockEvidence) ValidateBasic() error { return nil }
  258. func (e MockEvidence) String() string {
  259. return fmt.Sprintf("Evidence: %d/%s/%s", e.EvidenceHeight, e.Time(), e.EvidenceAddress)
  260. }
  261. //-------------------------------------------
  262. // EvidenceList is a list of Evidence. Evidences is not a word.
  263. type EvidenceList []Evidence
  264. // Hash returns the simple merkle root hash of the EvidenceList.
  265. func (evl EvidenceList) Hash() []byte {
  266. // These allocations are required because Evidence is not of type Bytes, and
  267. // golang slices can't be typed cast. This shouldn't be a performance problem since
  268. // the Evidence size is capped.
  269. evidenceBzs := make([][]byte, len(evl))
  270. for i := 0; i < len(evl); i++ {
  271. evidenceBzs[i] = evl[i].Bytes()
  272. }
  273. return merkle.SimpleHashFromByteSlices(evidenceBzs)
  274. }
  275. func (evl EvidenceList) String() string {
  276. s := ""
  277. for _, e := range evl {
  278. s += fmt.Sprintf("%s\t\t", e)
  279. }
  280. return s
  281. }
  282. // Has returns true if the evidence is in the EvidenceList.
  283. func (evl EvidenceList) Has(evidence Evidence) bool {
  284. for _, ev := range evl {
  285. if ev.Equal(evidence) {
  286. return true
  287. }
  288. }
  289. return false
  290. }