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.

387 lines
11 KiB

  1. package types
  2. import (
  3. "bytes"
  4. "sort"
  5. "testing"
  6. "time"
  7. "github.com/stretchr/testify/assert"
  8. tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
  9. )
  10. var (
  11. valEd25519 = []string{ABCIPubKeyTypeEd25519}
  12. valSecp256k1 = []string{ABCIPubKeyTypeSecp256k1}
  13. valSr25519 = []string{ABCIPubKeyTypeSr25519}
  14. )
  15. func TestConsensusParamsValidation(t *testing.T) {
  16. testCases := []struct {
  17. params ConsensusParams
  18. valid bool
  19. }{
  20. // test block params
  21. {
  22. params: makeParams(makeParamsArgs{
  23. blockBytes: 1,
  24. evidenceAge: 2,
  25. precision: 1,
  26. messageDelay: 1}),
  27. valid: true,
  28. },
  29. {
  30. params: makeParams(makeParamsArgs{
  31. blockBytes: 0,
  32. evidenceAge: 2,
  33. precision: 1,
  34. messageDelay: 1}),
  35. valid: false,
  36. },
  37. {
  38. params: makeParams(makeParamsArgs{
  39. blockBytes: 47 * 1024 * 1024,
  40. evidenceAge: 2,
  41. precision: 1,
  42. messageDelay: 1}),
  43. valid: true,
  44. },
  45. {
  46. params: makeParams(makeParamsArgs{
  47. blockBytes: 10,
  48. evidenceAge: 2,
  49. precision: 1,
  50. messageDelay: 1}),
  51. valid: true,
  52. },
  53. {
  54. params: makeParams(makeParamsArgs{
  55. blockBytes: 100 * 1024 * 1024,
  56. evidenceAge: 2,
  57. precision: 1,
  58. messageDelay: 1}),
  59. valid: true,
  60. },
  61. {
  62. params: makeParams(makeParamsArgs{
  63. blockBytes: 101 * 1024 * 1024,
  64. evidenceAge: 2,
  65. precision: 1,
  66. messageDelay: 1}),
  67. valid: false,
  68. },
  69. {
  70. params: makeParams(makeParamsArgs{
  71. blockBytes: 1024 * 1024 * 1024,
  72. evidenceAge: 2,
  73. precision: 1,
  74. messageDelay: 1}),
  75. valid: false,
  76. },
  77. {
  78. params: makeParams(makeParamsArgs{
  79. blockBytes: 1024 * 1024 * 1024,
  80. evidenceAge: 2,
  81. precision: 1,
  82. messageDelay: 1}),
  83. valid: false,
  84. },
  85. // test evidence params
  86. {
  87. params: makeParams(makeParamsArgs{
  88. blockBytes: 1,
  89. evidenceAge: 0,
  90. maxEvidenceBytes: 0,
  91. precision: 1,
  92. messageDelay: 1}),
  93. valid: false,
  94. },
  95. {
  96. params: makeParams(makeParamsArgs{
  97. blockBytes: 1,
  98. evidenceAge: 2,
  99. maxEvidenceBytes: 2,
  100. precision: 1,
  101. messageDelay: 1}),
  102. valid: false,
  103. },
  104. {
  105. params: makeParams(makeParamsArgs{
  106. blockBytes: 1000,
  107. evidenceAge: 2,
  108. maxEvidenceBytes: 1,
  109. precision: 1,
  110. messageDelay: 1}),
  111. valid: true,
  112. },
  113. {
  114. params: makeParams(makeParamsArgs{
  115. blockBytes: 1,
  116. evidenceAge: -1,
  117. maxEvidenceBytes: 0,
  118. precision: 1,
  119. messageDelay: 1}),
  120. valid: false,
  121. },
  122. // test no pubkey type provided
  123. {
  124. params: makeParams(makeParamsArgs{
  125. evidenceAge: 2,
  126. pubkeyTypes: []string{},
  127. precision: 1,
  128. messageDelay: 1}),
  129. valid: false,
  130. },
  131. // test invalid pubkey type provided
  132. {
  133. params: makeParams(makeParamsArgs{
  134. evidenceAge: 2,
  135. pubkeyTypes: []string{"potatoes make good pubkeys"},
  136. precision: 1,
  137. messageDelay: 1}),
  138. valid: false,
  139. },
  140. // test invalid pubkey type provided
  141. {
  142. params: makeParams(makeParamsArgs{
  143. evidenceAge: 2,
  144. precision: 1,
  145. messageDelay: -1}),
  146. valid: false,
  147. },
  148. {
  149. params: makeParams(makeParamsArgs{
  150. evidenceAge: 2,
  151. precision: -1,
  152. messageDelay: 1}),
  153. valid: false,
  154. },
  155. }
  156. for i, tc := range testCases {
  157. if tc.valid {
  158. assert.NoErrorf(t, tc.params.ValidateConsensusParams(), "expected no error for valid params (#%d)", i)
  159. } else {
  160. assert.Errorf(t, tc.params.ValidateConsensusParams(), "expected error for non valid params (#%d)", i)
  161. }
  162. }
  163. }
  164. type makeParamsArgs struct {
  165. blockBytes int64
  166. blockGas int64
  167. evidenceAge int64
  168. maxEvidenceBytes int64
  169. pubkeyTypes []string
  170. precision time.Duration
  171. messageDelay time.Duration
  172. propose time.Duration
  173. proposeDelta time.Duration
  174. vote time.Duration
  175. voteDelta time.Duration
  176. commit time.Duration
  177. bypassCommitTimeout bool
  178. }
  179. func makeParams(args makeParamsArgs) ConsensusParams {
  180. if args.pubkeyTypes == nil {
  181. args.pubkeyTypes = valEd25519
  182. }
  183. return ConsensusParams{
  184. Block: BlockParams{
  185. MaxBytes: args.blockBytes,
  186. MaxGas: args.blockGas,
  187. },
  188. Evidence: EvidenceParams{
  189. MaxAgeNumBlocks: args.evidenceAge,
  190. MaxAgeDuration: time.Duration(args.evidenceAge),
  191. MaxBytes: args.maxEvidenceBytes,
  192. },
  193. Validator: ValidatorParams{
  194. PubKeyTypes: args.pubkeyTypes,
  195. },
  196. Synchrony: SynchronyParams{
  197. Precision: args.precision,
  198. MessageDelay: args.messageDelay,
  199. },
  200. Timeout: TimeoutParams{
  201. Propose: args.propose,
  202. ProposeDelta: args.proposeDelta,
  203. Vote: args.vote,
  204. VoteDelta: args.voteDelta,
  205. Commit: args.commit,
  206. BypassCommitTimeout: args.bypassCommitTimeout,
  207. },
  208. }
  209. }
  210. func TestConsensusParamsHash(t *testing.T) {
  211. params := []ConsensusParams{
  212. makeParams(makeParamsArgs{blockBytes: 4, blockGas: 2, evidenceAge: 3, maxEvidenceBytes: 1}),
  213. makeParams(makeParamsArgs{blockBytes: 1, blockGas: 4, evidenceAge: 3, maxEvidenceBytes: 1}),
  214. makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 4, maxEvidenceBytes: 1}),
  215. makeParams(makeParamsArgs{blockBytes: 2, blockGas: 5, evidenceAge: 7, maxEvidenceBytes: 1}),
  216. makeParams(makeParamsArgs{blockBytes: 1, blockGas: 7, evidenceAge: 6, maxEvidenceBytes: 1}),
  217. makeParams(makeParamsArgs{blockBytes: 9, blockGas: 5, evidenceAge: 4, maxEvidenceBytes: 1}),
  218. makeParams(makeParamsArgs{blockBytes: 7, blockGas: 8, evidenceAge: 9, maxEvidenceBytes: 1}),
  219. makeParams(makeParamsArgs{blockBytes: 4, blockGas: 6, evidenceAge: 5, maxEvidenceBytes: 1}),
  220. }
  221. hashes := make([][]byte, len(params))
  222. for i := range params {
  223. hashes[i] = params[i].HashConsensusParams()
  224. }
  225. // make sure there are no duplicates...
  226. // sort, then check in order for matches
  227. sort.Slice(hashes, func(i, j int) bool {
  228. return bytes.Compare(hashes[i], hashes[j]) < 0
  229. })
  230. for i := 0; i < len(hashes)-1; i++ {
  231. assert.NotEqual(t, hashes[i], hashes[i+1])
  232. }
  233. }
  234. func TestConsensusParamsUpdate(t *testing.T) {
  235. testCases := []struct {
  236. intialParams ConsensusParams
  237. updates *tmproto.ConsensusParams
  238. updatedParams ConsensusParams
  239. }{
  240. // empty updates
  241. {
  242. intialParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}),
  243. updates: &tmproto.ConsensusParams{},
  244. updatedParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}),
  245. },
  246. {
  247. // update synchrony params
  248. intialParams: makeParams(makeParamsArgs{evidenceAge: 3, precision: time.Second, messageDelay: 3 * time.Second}),
  249. updates: &tmproto.ConsensusParams{
  250. Synchrony: &tmproto.SynchronyParams{
  251. Precision: durationPtr(time.Second * 2),
  252. MessageDelay: durationPtr(time.Second * 4),
  253. },
  254. },
  255. updatedParams: makeParams(makeParamsArgs{evidenceAge: 3, precision: 2 * time.Second, messageDelay: 4 * time.Second}),
  256. },
  257. {
  258. // update timeout params
  259. intialParams: makeParams(makeParamsArgs{
  260. propose: 3 * time.Second,
  261. proposeDelta: 500 * time.Millisecond,
  262. vote: time.Second,
  263. voteDelta: 500 * time.Millisecond,
  264. commit: time.Second,
  265. bypassCommitTimeout: false,
  266. }),
  267. updates: &tmproto.ConsensusParams{
  268. Timeout: &tmproto.TimeoutParams{
  269. Propose: durationPtr(2 * time.Second),
  270. ProposeDelta: durationPtr(400 * time.Millisecond),
  271. Vote: durationPtr(5 * time.Second),
  272. VoteDelta: durationPtr(400 * time.Millisecond),
  273. Commit: durationPtr(time.Minute),
  274. BypassCommitTimeout: true,
  275. },
  276. },
  277. updatedParams: makeParams(makeParamsArgs{
  278. propose: 2 * time.Second,
  279. proposeDelta: 400 * time.Millisecond,
  280. vote: 5 * time.Second,
  281. voteDelta: 400 * time.Millisecond,
  282. commit: time.Minute,
  283. bypassCommitTimeout: true,
  284. }),
  285. },
  286. // fine updates
  287. {
  288. intialParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}),
  289. updates: &tmproto.ConsensusParams{
  290. Block: &tmproto.BlockParams{
  291. MaxBytes: 100,
  292. MaxGas: 200,
  293. },
  294. Evidence: &tmproto.EvidenceParams{
  295. MaxAgeNumBlocks: 300,
  296. MaxAgeDuration: time.Duration(300),
  297. MaxBytes: 50,
  298. },
  299. Validator: &tmproto.ValidatorParams{
  300. PubKeyTypes: valSecp256k1,
  301. },
  302. },
  303. updatedParams: makeParams(makeParamsArgs{
  304. blockBytes: 100, blockGas: 200,
  305. evidenceAge: 300,
  306. maxEvidenceBytes: 50,
  307. pubkeyTypes: valSecp256k1}),
  308. },
  309. {
  310. intialParams: makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3}),
  311. updates: &tmproto.ConsensusParams{
  312. Block: &tmproto.BlockParams{
  313. MaxBytes: 100,
  314. MaxGas: 200,
  315. },
  316. Evidence: &tmproto.EvidenceParams{
  317. MaxAgeNumBlocks: 300,
  318. MaxAgeDuration: time.Duration(300),
  319. MaxBytes: 50,
  320. },
  321. Validator: &tmproto.ValidatorParams{
  322. PubKeyTypes: valSr25519,
  323. },
  324. },
  325. updatedParams: makeParams(makeParamsArgs{
  326. blockBytes: 100,
  327. blockGas: 200,
  328. evidenceAge: 300,
  329. maxEvidenceBytes: 50,
  330. pubkeyTypes: valSr25519}),
  331. },
  332. }
  333. for _, tc := range testCases {
  334. assert.Equal(t, tc.updatedParams, tc.intialParams.UpdateConsensusParams(tc.updates))
  335. }
  336. }
  337. func TestConsensusParamsUpdate_AppVersion(t *testing.T) {
  338. params := makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 3})
  339. assert.EqualValues(t, 0, params.Version.AppVersion)
  340. updated := params.UpdateConsensusParams(
  341. &tmproto.ConsensusParams{Version: &tmproto.VersionParams{AppVersion: 1}})
  342. assert.EqualValues(t, 1, updated.Version.AppVersion)
  343. }
  344. func TestProto(t *testing.T) {
  345. params := []ConsensusParams{
  346. makeParams(makeParamsArgs{blockBytes: 4, blockGas: 2, evidenceAge: 3, maxEvidenceBytes: 1}),
  347. makeParams(makeParamsArgs{blockBytes: 1, blockGas: 4, evidenceAge: 3, maxEvidenceBytes: 1}),
  348. makeParams(makeParamsArgs{blockBytes: 1, blockGas: 2, evidenceAge: 4, maxEvidenceBytes: 1}),
  349. makeParams(makeParamsArgs{blockBytes: 2, blockGas: 5, evidenceAge: 7, maxEvidenceBytes: 1}),
  350. makeParams(makeParamsArgs{blockBytes: 1, blockGas: 7, evidenceAge: 6, maxEvidenceBytes: 1}),
  351. makeParams(makeParamsArgs{blockBytes: 9, blockGas: 5, evidenceAge: 4, maxEvidenceBytes: 1}),
  352. makeParams(makeParamsArgs{blockBytes: 7, blockGas: 8, evidenceAge: 9, maxEvidenceBytes: 1}),
  353. makeParams(makeParamsArgs{blockBytes: 4, blockGas: 6, evidenceAge: 5, maxEvidenceBytes: 1}),
  354. makeParams(makeParamsArgs{precision: time.Second, messageDelay: time.Minute}),
  355. makeParams(makeParamsArgs{precision: time.Nanosecond, messageDelay: time.Millisecond}),
  356. }
  357. for i := range params {
  358. pbParams := params[i].ToProto()
  359. oriParams := ConsensusParamsFromProto(pbParams)
  360. assert.Equal(t, params[i], oriParams)
  361. }
  362. }
  363. func durationPtr(t time.Duration) *time.Duration {
  364. return &t
  365. }