Compare commits

...

29 Commits

Author SHA1 Message Date
Zarko Milosevic
4accdb5f59 Example of client send task and monitor task 2018-04-19 12:34:42 +02:00
Anton Kaliaev
ece3f678da [docs/spec] update msg type and Tendermint behavior (#1468)
Refs #1422
2018-04-17 19:38:10 +02:00
Ethan Buchman
45a05b4726 Merge pull request #1461 from tendermint/update-changelog
update changelog
2018-04-17 09:56:53 +02:00
Anton Kaliaev
1706ce6f7f update changelog for 0.19.0 release 2018-04-13 10:50:34 +02:00
Jae Kwon
d0beaba7e8 Bump version to 0.19.0 2018-04-13 01:32:47 -07:00
Anton Kaliaev
c28784de5e Merge pull request #1453 from tendermint/fix-localnet
Fix permissions and folder structure for localnet
2018-04-12 17:50:08 +02:00
Anton Kaliaev
d06390638d [localnet] use routable IPs 2018-04-12 16:02:31 +02:00
Anton Kaliaev
3a0edc561d log error from AddrBook#AddAddress in DialPeersAsync
Refs #1434
2018-04-12 15:51:17 +02:00
Anton Kaliaev
f8ed578325 [localnet] execute cmd from root
not secure, but we don't care because it's local tooling
2018-04-12 15:51:32 +02:00
Anton Kaliaev
5babaf9a88 [localnet] fix folder permissions errors 2018-04-12 15:51:17 +02:00
Greg Szabo
c0610b2c32 Greg/localnet (#1450)
* Added new Makefile targets for local testnet running using docker

* Added localnode docker image description, some documentation and refactored to use the tendermint testnet command

* Fixes for the new tendermint testnet command

* More fixes on tendermint testnet and docker-compose

* Changed logging

* Added missing targets to phony
2018-04-12 13:15:16 +02:00
Anton Kaliaev
1db2224241 do not use mask in testnet cmd (#1451)
fix node ids
2018-04-11 20:53:33 +02:00
Anton Kaliaev
0323b03daf improve testnet cmd (#1449)
* improve testnet cmd

* allow non-validators
* configurable prefix
* populating of persistent peers

* relax permissions

* cleanup output dir every time

* do not remove dir

* remove panic comments
2018-04-11 19:40:53 +02:00
Anton Kaliaev
379f9f875b update docs for latest develop (#1448)
* update docs for latest develop

* latest_app_hash, not app_hash
2018-04-11 17:36:14 +02:00
Thomas Corbière
ab00bf7c8b standardize PRNG access (#1411)
* replace math/rand with tmlibs equivalent.

* update tmlibs dependency
2018-04-11 11:38:30 +02:00
Bric3d
64879c1e6a 1417 status response format (#1424)
* Reformated the ResultStatus

* fix misuse of ResultStatus.

* updated changelog

* Fixed tests

* fixed rpc helper tests

* fixed rpc_tests

* fixed mock/status_test

* fixed typo

* fixed ommitempty on validatorstatus and the changelog

* fixed extra line in changelog

* Updated usage of the /status json response in tests after breaking changes

* Updated remaining tests with changes after searching the codebase for usage

* Reformated the ResultStatus

* fix misuse of ResultStatus.

* updated changelog

* Fixed tests

* fixed rpc helper tests

* fixed rpc_tests

* fixed mock/status_test

* fixed typo

* fixed ommitempty on validatorstatus and the changelog

* Updated usage of the /status json response in tests after breaking changes

* Updated remaining tests with changes after searching the codebase for usage

* rebased against develop
2018-04-11 10:38:34 +02:00
Vladislav Dmitriyev
7c22e47629 Replaced NodeInfo's pubkey to ID (#1443)
* Replaced NodeInfo PubKey to NodeID

* Fixed tests and replaced NodeID with ID

* Removed unnecessary method ID()

* Fixed codec_test.go

* Fixed codec_test.go

* Removed unnecessary bracket

* Fixed all tests

* Fixed peer_set_test.go

* Fixed peer_test.go

* Fixed common_test.go

* Fixed common_test.go

* Renamed node_id to id

* Removed peer.ID() from RPC net.go

* Replaced NodeInfo pubKey to ID

* Fixed codec_test.go

* Fixed peer_set_test.go

* Fix pex_reactor_test.go

* Refactored code for privateKey initiali

* Fixed peer_set_test.go

* Fixed test.proto and removed orphan string in codec_test.go

* Fixed pointer to a string

* generate node_key when running tendermint init

* [docs] prefix IPs with node IDs

Refs #1429

* gen_node_key cmd

* [docs/specification/secure-p2p] add a note about config

* fix data race

Closes #1442

```
WARNING: DATA RACE
Write at 0x00c4209de7c8 by goroutine 23:
  github.com/tendermint/tendermint/types.(*Block).fillHeader()
      /home/vagrant/go/src/github.com/tendermint/tendermint/types/block.go:88 +0x157
  github.com/tendermint/tendermint/types.(*Block).Hash()
      /home/vagrant/go/src/github.com/tendermint/tendermint/types/block.go:104 +0x121
  github.com/tendermint/tendermint/types.(*Block).HashesTo()
      /home/vagrant/go/src/github.com/tendermint/tendermint/types/block.go:135 +0x4f
  github.com/tendermint/tendermint/consensus.(*ConsensusState).enterPrecommit()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:1037 +0x182d
  github.com/tendermint/tendermint/consensus.(*ConsensusState).addVote()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:1425 +0x1a6c
  github.com/tendermint/tendermint/consensus.(*ConsensusState).tryAddVote()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:1318 +0x77
  github.com/tendermint/tendermint/consensus.(*ConsensusState).handleMsg()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:581 +0x7a9
  github.com/tendermint/tendermint/consensus.(*ConsensusState).receiveRoutine()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:539 +0x6c3

Previous read at 0x00c4209de7c8 by goroutine 47:
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*HexBytes).MarshalJSON()
      <autogenerated>:1 +0x52
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.invokeMarshalJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:433 +0x88
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:82 +0x8d2
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSONStruct()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:348 +0x539
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:119 +0x83f
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSONStruct()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:348 +0x539
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:119 +0x83f
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSONStruct()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:348 +0x539
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:119 +0x83f
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSONStruct()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:348 +0x539
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:119 +0x83f
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).MarshalJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/amino.go:296 +0x182
  github.com/tendermint/tendermint/rpc/lib/types.NewRPCSuccessResponse()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/lib/types/types.go:100 +0x12c
  github.com/tendermint/tendermint/rpc/lib/server.makeJSONRPCHandler.func1()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/lib/server/handlers.go:152 +0xab7
  net/http.HandlerFunc.ServeHTTP()
      /usr/lib/go-1.9/src/net/http/server.go:1918 +0x51
  net/http.(*ServeMux).ServeHTTP()
      /usr/lib/go-1.9/src/net/http/server.go:2254 +0xa2
  github.com/tendermint/tendermint/rpc/lib/server.RecoverAndLogHandler.func1()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/lib/server/http_server.go:138 +0x4fa
  net/http.HandlerFunc.ServeHTTP()
      /usr/lib/go-1.9/src/net/http/server.go:1918 +0x51
  net/http.serverHandler.ServeHTTP()
      /usr/lib/go-1.9/src/net/http/server.go:2619 +0xbc
  net/http.(*conn).serve()
      /usr/lib/go-1.9/src/net/http/server.go:1801 +0x83b

Goroutine 23 (running) created at:
  github.com/tendermint/tendermint/consensus.(*ConsensusState).OnStart()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:250 +0x35b
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x5fc
  github.com/tendermint/tendermint/consensus.(*ConsensusReactor).OnStart()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/reactor.go:69 +0x1b4
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x5fc
  github.com/tendermint/tendermint/consensus.(*ConsensusReactor).Start()
      <autogenerated>:1 +0x43
  github.com/tendermint/tendermint/p2p.(*Switch).OnStart()
      /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch.go:177 +0x124
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x5fc
  github.com/tendermint/tendermint/node.(*Node).OnStart()
      /home/vagrant/go/src/github.com/tendermint/tendermint/node/node.go:416 +0xa1b
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x5fc
  github.com/tendermint/tendermint/rpc/test.StartTendermint()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/test/helpers.go:100 +0x5b
  github.com/tendermint/tendermint/rpc/client_test.TestMain()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/client/main_test.go:17 +0x4c
  main.main()
      github.com/tendermint/tendermint/rpc/client/_test/_testmain.go:76 +0x1cd

Goroutine 47 (running) created at:
  net/http.(*Server).Serve()
      /usr/lib/go-1.9/src/net/http/server.go:2720 +0x37c
  net/http.Serve()
      /usr/lib/go-1.9/src/net/http/server.go:2323 +0xe2
  github.com/tendermint/tendermint/rpc/lib/server.StartHTTPServer.func1()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/lib/server/http_server.go:35 +0xb3
```

* removed excessive comment

Refs https://github.com/tendermint/tendermint/pull/1446#discussion_r180353446

* use the tag interface for pubsub. (#1438)

* use the tag interface for pubsub.

* update tmlibs.

* Fix unresolved conflict.

* improve `show_node_id` (#1433)

* fix show_node_id

* make LoadNodeKey public

* make LoadNodeKey public

* remove if

* remove if
2018-04-11 10:11:11 +02:00
suyuhuang
384b3ea065 improve show_node_id (#1433)
* fix show_node_id

* make LoadNodeKey public

* make LoadNodeKey public

* remove if

* remove if
2018-04-10 16:03:51 +02:00
Thomas Corbière
6a48bd0c88 use the tag interface for pubsub. (#1438)
* use the tag interface for pubsub.

* update tmlibs.

* Fix unresolved conflict.
2018-04-10 16:03:03 +02:00
Ethan Buchman
d93e177a69 Merge pull request #1446 from tendermint/1442-data-race-fix-attempt
fix data race
2018-04-10 16:49:36 +03:00
Anton Kaliaev
cef053386b Merge pull request #1439 from tendermint/1429-add-docs-for-node-ids
docs: update docs to include IDs or set auth_enc to false
2018-04-10 11:46:48 +02:00
Anton Kaliaev
cca1dd8e3e removed excessive comment
Refs https://github.com/tendermint/tendermint/pull/1446#discussion_r180353446
2018-04-10 11:36:31 +02:00
Anton Kaliaev
26c38e770e fix data race
Closes #1442

```
WARNING: DATA RACE
Write at 0x00c4209de7c8 by goroutine 23:
  github.com/tendermint/tendermint/types.(*Block).fillHeader()
      /home/vagrant/go/src/github.com/tendermint/tendermint/types/block.go:88 +0x157
  github.com/tendermint/tendermint/types.(*Block).Hash()
      /home/vagrant/go/src/github.com/tendermint/tendermint/types/block.go:104 +0x121
  github.com/tendermint/tendermint/types.(*Block).HashesTo()
      /home/vagrant/go/src/github.com/tendermint/tendermint/types/block.go:135 +0x4f
  github.com/tendermint/tendermint/consensus.(*ConsensusState).enterPrecommit()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:1037 +0x182d
  github.com/tendermint/tendermint/consensus.(*ConsensusState).addVote()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:1425 +0x1a6c
  github.com/tendermint/tendermint/consensus.(*ConsensusState).tryAddVote()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:1318 +0x77
  github.com/tendermint/tendermint/consensus.(*ConsensusState).handleMsg()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:581 +0x7a9
  github.com/tendermint/tendermint/consensus.(*ConsensusState).receiveRoutine()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:539 +0x6c3

Previous read at 0x00c4209de7c8 by goroutine 47:
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*HexBytes).MarshalJSON()
      <autogenerated>:1 +0x52
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.invokeMarshalJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:433 +0x88
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:82 +0x8d2
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSONStruct()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:348 +0x539
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:119 +0x83f
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSONStruct()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:348 +0x539
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:119 +0x83f
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSONStruct()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:348 +0x539
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:119 +0x83f
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSONStruct()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:348 +0x539
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec)._encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:119 +0x83f
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).encodeReflectJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/json-encode.go:50 +0x10e
  github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino.(*Codec).MarshalJSON()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-amino/amino.go:296 +0x182
  github.com/tendermint/tendermint/rpc/lib/types.NewRPCSuccessResponse()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/lib/types/types.go:100 +0x12c
  github.com/tendermint/tendermint/rpc/lib/server.makeJSONRPCHandler.func1()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/lib/server/handlers.go:152 +0xab7
  net/http.HandlerFunc.ServeHTTP()
      /usr/lib/go-1.9/src/net/http/server.go:1918 +0x51
  net/http.(*ServeMux).ServeHTTP()
      /usr/lib/go-1.9/src/net/http/server.go:2254 +0xa2
  github.com/tendermint/tendermint/rpc/lib/server.RecoverAndLogHandler.func1()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/lib/server/http_server.go:138 +0x4fa
  net/http.HandlerFunc.ServeHTTP()
      /usr/lib/go-1.9/src/net/http/server.go:1918 +0x51
  net/http.serverHandler.ServeHTTP()
      /usr/lib/go-1.9/src/net/http/server.go:2619 +0xbc
  net/http.(*conn).serve()
      /usr/lib/go-1.9/src/net/http/server.go:1801 +0x83b

Goroutine 23 (running) created at:
  github.com/tendermint/tendermint/consensus.(*ConsensusState).OnStart()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/state.go:250 +0x35b
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x5fc
  github.com/tendermint/tendermint/consensus.(*ConsensusReactor).OnStart()
      /home/vagrant/go/src/github.com/tendermint/tendermint/consensus/reactor.go:69 +0x1b4
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x5fc
  github.com/tendermint/tendermint/consensus.(*ConsensusReactor).Start()
      <autogenerated>:1 +0x43
  github.com/tendermint/tendermint/p2p.(*Switch).OnStart()
      /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch.go:177 +0x124
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x5fc
  github.com/tendermint/tendermint/node.(*Node).OnStart()
      /home/vagrant/go/src/github.com/tendermint/tendermint/node/node.go:416 +0xa1b
  github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.(*BaseService).Start()
      /home/vagrant/go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/service.go:130 +0x5fc
  github.com/tendermint/tendermint/rpc/test.StartTendermint()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/test/helpers.go:100 +0x5b
  github.com/tendermint/tendermint/rpc/client_test.TestMain()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/client/main_test.go:17 +0x4c
  main.main()
      github.com/tendermint/tendermint/rpc/client/_test/_testmain.go:76 +0x1cd

Goroutine 47 (running) created at:
  net/http.(*Server).Serve()
      /usr/lib/go-1.9/src/net/http/server.go:2720 +0x37c
  net/http.Serve()
      /usr/lib/go-1.9/src/net/http/server.go:2323 +0xe2
  github.com/tendermint/tendermint/rpc/lib/server.StartHTTPServer.func1()
      /home/vagrant/go/src/github.com/tendermint/tendermint/rpc/lib/server/http_server.go:35 +0xb3
```
2018-04-10 11:15:16 +02:00
Anton Kaliaev
609452958c [docs/specification/secure-p2p] add a note about config 2018-04-09 17:02:48 +02:00
Anton Kaliaev
c954fca376 gen_node_key cmd 2018-04-09 17:02:47 +02:00
Anton Kaliaev
9be16d56ba [docs] prefix IPs with node IDs
Refs #1429
2018-04-09 17:02:47 +02:00
Anton Kaliaev
2b732bc11a generate node_key when running tendermint init 2018-04-09 17:02:47 +02:00
Ethan Buchman
dcd00b0e68 update deps and changelog 2018-04-09 16:36:42 +03:00
Ethan Buchman
ff3f35c5f4 Merge pull request #1347 from tendermint/jae/aminoify
Convert Tendermint to use GoAmino
2018-04-09 16:24:38 +03:00
108 changed files with 1441 additions and 892 deletions

View File

@@ -24,6 +24,24 @@ BUG FIXES:
- Graceful handling/recovery for apps that have non-determinism or fail to halt - Graceful handling/recovery for apps that have non-determinism or fail to halt
- Graceful handling/recovery for violations of safety, or liveness - Graceful handling/recovery for violations of safety, or liveness
## 0.19.0 (April 13th, 2018)
BREAKING:
- [cmd] improved `testnet` command; now it can fill in `persistent_peers` for you in the config file and much more (see `tendermint testnet --help` for details)
- [cmd] `show_node_id` now returns an error if there is no node key
- [rpc]: changed the output format for the `/status` endpoint (see https://godoc.org/github.com/tendermint/tendermint/rpc/core#Status)
Upgrade from go-wire to go-amino. This is a sweeping change that breaks everything that is
serialized to disk or over the network.
See github.com/tendermint/go-amino for details on the new format.
See `scripts/wire2amino.go` for a tool to upgrade
genesis/priv_validator/node_key JSON files.
FEATURES:
- [cmd] added `gen_node_key` command
## 0.18.0 (April 6th, 2018) ## 0.18.0 (April 6th, 2018)
BREAKING: BREAKING:

23
Gopkg.lock generated
View File

@@ -191,8 +191,8 @@
[[projects]] [[projects]]
name = "github.com/spf13/pflag" name = "github.com/spf13/pflag"
packages = ["."] packages = ["."]
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66" revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
version = "v1.0.0" version = "v1.0.1"
[[projects]] [[projects]]
name = "github.com/spf13/viper" name = "github.com/spf13/viper"
@@ -238,8 +238,8 @@
"server", "server",
"types" "types"
] ]
revision = "c62aed95f2ce399ec815b0cafe478af002cdc4e6" revision = "78a8905690ef54f9d57e3b2b0ee7ad3a04ef3f1f"
version = "v0.10.3-dev" version = "v0.10.3"
[[projects]] [[projects]]
branch = "master" branch = "master"
@@ -260,8 +260,8 @@
[[projects]] [[projects]]
name = "github.com/tendermint/go-crypto" name = "github.com/tendermint/go-crypto"
packages = ["."] packages = ["."]
revision = "5d5f580f49ca66c13400938c64334186068c8b7c" revision = "915416979bf70efa4bcbf1c6cd5d64c5fff9fc19"
version = "v0.6.1" version = "v0.6.2"
[[projects]] [[projects]]
name = "github.com/tendermint/go-wire" name = "github.com/tendermint/go-wire"
@@ -285,8 +285,8 @@
"pubsub/query", "pubsub/query",
"test" "test"
] ]
revision = "2e24b64fc121dcdf1cabceab8dc2f7257675483c" revision = "97e1f1ad3f510048929a51475811a18686c894df"
version = "0.8.1" version = "0.8.2-rc0"
[[projects]] [[projects]]
branch = "master" branch = "master"
@@ -301,7 +301,7 @@
"ripemd160", "ripemd160",
"salsa20/salsa" "salsa20/salsa"
] ]
revision = "b2aa35443fbc700ab74c586ae79b81c171851023" revision = "d6449816ce06963d9d136eee5a56fca5b0616e7e"
[[projects]] [[projects]]
branch = "master" branch = "master"
@@ -348,7 +348,7 @@
branch = "master" branch = "master"
name = "google.golang.org/genproto" name = "google.golang.org/genproto"
packages = ["googleapis/rpc/status"] packages = ["googleapis/rpc/status"]
revision = "ce84044298496ef4b54b4a0a0909ba593cc60e30" revision = "51d0944304c3cbce4afe9e5247e21100037bff78"
[[projects]] [[projects]]
name = "google.golang.org/grpc" name = "google.golang.org/grpc"
@@ -372,7 +372,6 @@
"transport" "transport"
] ]
revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e"
source = "github.com/grpc/grpc-go"
version = "v1.7.5" version = "v1.7.5"
[[projects]] [[projects]]
@@ -384,6 +383,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "e5e6c7942710846bdb5589fba10c90a869773f2685da825b955510afe0d7c5a4" inputs-digest = "e70f8692c825e80ae8510546e297840b9560d00e11b2272749a55cc2ffd147f0"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@@ -71,25 +71,22 @@
[[constraint]] [[constraint]]
name = "github.com/tendermint/abci" name = "github.com/tendermint/abci"
version = "0.10.3-dev" version = "~0.10.3"
[[constraint]] [[constraint]]
name = "github.com/tendermint/go-crypto" name = "github.com/tendermint/go-crypto"
version = "0.6.1" version = "~0.6.2"
[[constraint]] [[constraint]]
name = "github.com/tendermint/go-amino" name = "github.com/tendermint/go-amino"
version = "0.9.6" version = "~0.9.6"
[[override]] [[constraint]]
# [[constraint]]
name = "github.com/tendermint/tmlibs" name = "github.com/tendermint/tmlibs"
version = "~0.8.1" version = "~0.8.2-rc0"
# branch = "develop"
[[constraint]] [[constraint]]
name = "google.golang.org/grpc" name = "google.golang.org/grpc"
source = "github.com/grpc/grpc-go"
version = "~1.7.3" version = "~1.7.3"
[prune] [prune]

View File

@@ -178,7 +178,25 @@ metalinter_all:
@echo "--> Running linter (all)" @echo "--> Running linter (all)"
gometalinter.v2 --vendor --deadline=600s --enable-all --disable=lll ./... gometalinter.v2 --vendor --deadline=600s --enable-all --disable=lll ./...
###########################################################
### Local testnet using docker
# Build linux binary on other platforms
build-linux:
GOOS=linux GOARCH=amd64 $(MAKE) build
# Run a 4-node testnet locally
docker-start:
@echo "Wait until 'Attaching to node0, node1, node2, node3' message appears"
@if ! [ -f build/node0/config/genesis.json ]; then docker run --rm -v `pwd`/build:/tendermint:Z tendermint/localnode testnet --v 4 --o . --populate-persistent-peers --starting-ip-address 192.167.10.2 ; fi
docker-compose up
# Stop testnet
docker-stop:
docker-compose down
# To avoid unintended conflicts with file names, always add to .PHONY # To avoid unintended conflicts with file names, always add to .PHONY
# unless there is a reason not to. # unless there is a reason not to.
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
.PHONY: check build build_race dist install check_tools get_tools update_tools get_vendor_deps draw_deps test_cover test_apps test_persistence test_p2p test test_race test_integrations test_release test100 vagrant_test fmt .PHONY: check build build_race dist install check_tools get_tools update_tools get_vendor_deps draw_deps test_cover test_apps test_persistence test_p2p test test_race test_integrations test_release test100 vagrant_test fmt build-linux docker-start docker-stop

View File

@@ -4,7 +4,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
proto "github.com/tendermint/tendermint/benchmarks/proto" proto "github.com/tendermint/tendermint/benchmarks/proto"
@@ -16,20 +16,24 @@ func BenchmarkEncodeStatusWire(b *testing.B) {
b.StopTimer() b.StopTimer()
cdc := amino.NewCodec() cdc := amino.NewCodec()
ctypes.RegisterAmino(cdc) ctypes.RegisterAmino(cdc)
pubKey := crypto.GenPrivKeyEd25519().PubKey() nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
status := &ctypes.ResultStatus{ status := &ctypes.ResultStatus{
NodeInfo: p2p.NodeInfo{ NodeInfo: p2p.NodeInfo{
PubKey: pubKey, ID: nodeKey.ID(),
Moniker: "SOMENAME", Moniker: "SOMENAME",
Network: "SOMENAME", Network: "SOMENAME",
ListenAddr: "SOMEADDR", ListenAddr: "SOMEADDR",
Version: "SOMEVER", Version: "SOMEVER",
Other: []string{"SOMESTRING", "OTHERSTRING"}, Other: []string{"SOMESTRING", "OTHERSTRING"},
}, },
PubKey: pubKey, SyncInfo: ctypes.SyncInfo{
LatestBlockHash: []byte("SOMEBYTES"), LatestBlockHash: []byte("SOMEBYTES"),
LatestBlockHeight: 123, LatestBlockHeight: 123,
LatestBlockTime: time.Unix(0, 1234), LatestBlockTime: time.Unix(0, 1234),
},
ValidatorInfo: ctypes.ValidatorInfo{
PubKey: nodeKey.PubKey(),
},
} }
b.StartTimer() b.StartTimer()
@@ -48,9 +52,9 @@ func BenchmarkEncodeNodeInfoWire(b *testing.B) {
b.StopTimer() b.StopTimer()
cdc := amino.NewCodec() cdc := amino.NewCodec()
ctypes.RegisterAmino(cdc) ctypes.RegisterAmino(cdc)
pubKey := crypto.GenPrivKeyEd25519().PubKey() nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
nodeInfo := p2p.NodeInfo{ nodeInfo := p2p.NodeInfo{
PubKey: pubKey, ID: nodeKey.ID(),
Moniker: "SOMENAME", Moniker: "SOMENAME",
Network: "SOMENAME", Network: "SOMENAME",
ListenAddr: "SOMEADDR", ListenAddr: "SOMEADDR",
@@ -73,9 +77,9 @@ func BenchmarkEncodeNodeInfoBinary(b *testing.B) {
b.StopTimer() b.StopTimer()
cdc := amino.NewCodec() cdc := amino.NewCodec()
ctypes.RegisterAmino(cdc) ctypes.RegisterAmino(cdc)
pubKey := crypto.GenPrivKeyEd25519().PubKey() nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
nodeInfo := p2p.NodeInfo{ nodeInfo := p2p.NodeInfo{
PubKey: pubKey, ID: nodeKey.ID(),
Moniker: "SOMENAME", Moniker: "SOMENAME",
Network: "SOMENAME", Network: "SOMENAME",
ListenAddr: "SOMEADDR", ListenAddr: "SOMEADDR",
@@ -94,15 +98,20 @@ func BenchmarkEncodeNodeInfoBinary(b *testing.B) {
func BenchmarkEncodeNodeInfoProto(b *testing.B) { func BenchmarkEncodeNodeInfoProto(b *testing.B) {
b.StopTimer() b.StopTimer()
pubKey := crypto.GenPrivKeyEd25519().PubKey().(crypto.PubKeyEd25519) nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
pubKey2 := &proto.PubKey{Ed25519: &proto.PubKeyEd25519{Bytes: pubKey[:]}} nodeID := string(nodeKey.ID())
someName := "SOMENAME"
someAddr := "SOMEADDR"
someVer := "SOMEVER"
someString := "SOMESTRING"
otherString := "OTHERSTRING"
nodeInfo := proto.NodeInfo{ nodeInfo := proto.NodeInfo{
PubKey: pubKey2, Id: &proto.ID{Id: &nodeID},
Moniker: "SOMENAME", Moniker: &someName,
Network: "SOMENAME", Network: &someName,
ListenAddr: "SOMEADDR", ListenAddr: &someAddr,
Version: "SOMEVER", Version: &someVer,
Other: []string{"SOMESTRING", "OTHERSTRING"}, Other: []string{someString, otherString},
} }
b.StartTimer() b.StartTimer()

View File

@@ -0,0 +1,26 @@
DIST_DIRS := find * -type d -exec
VERSION := $(shell perl -ne '/^var version.*"([^"]+)".*$$/ && print "v$$1\n"' main.go)
GOTOOLS = \
github.com/mitchellh/gox
tools:
go get $(GOTOOLS)
get_vendor_deps:
@hash glide 2>/dev/null || go get github.com/Masterminds/glide
glide install
build:
go build
install:
go install
test:
go test -race
clean:
rm -f ./experiments
rm -rf ./dist
.PHONY: tools get_vendor_deps build install test clean

View File

@@ -0,0 +1,12 @@
package: github.com/tendermint/tendermint/benchmarks/experiments
import:
- package: github.com/tendermint/tendermint
version: v0.16.0
subpackages:
- rpc/client
- rpc/lib/types
- types
- package: github.com/tendermint/tmlibs
version: v0.7.0
subpackages:
- log

View File

@@ -0,0 +1,126 @@
package main
import (
"encoding/binary"
"fmt"
"math/rand"
"os"
"sync"
"time"
"context"
"github.com/tendermint/tendermint/rpc/client"
"github.com/tendermint/tendermint/types"
"github.com/tendermint/tmlibs/log"
)
var logger = log.NewNopLogger()
var finishedTasks = 0
var mutex = &sync.Mutex{}
func main() {
var endpoint = "tcp://0.0.0.0:46657"
var httpClient = getHTTPClient(endpoint)
var res, err = httpClient.Status()
if err != nil {
logger.Info("something wrong happens", err)
}
logger.Info("received status", res)
go monitorTask(endpoint)
txCount := 10
var clientNumber = 10
for i := 0; i < clientNumber; i++ {
go clientTask(i, txCount, endpoint)
}
for finishedTasks < clientNumber+1 {
}
fmt.Printf("Done: %d\n", finishedTasks)
}
func clientTask(id, txCount int, endpoint string) {
var httpClient = getHTTPClient(endpoint)
for i := 0; i < txCount; i++ {
var _, err = httpClient.BroadcastTxSync(generateTx(id, rand.Int()))
if err != nil {
fmt.Printf("Something wrong happened: %s\n", err)
}
}
fmt.Printf("Finished client task: %d\n", id)
mutex.Lock()
finishedTasks++
mutex.Unlock()
}
func getHTTPClient(rpcAddr string) *client.HTTP {
return client.NewHTTP(rpcAddr, "/websocket")
}
func generateTx(i, valI int) []byte {
// a tx encodes the validator index, the tx number, and some random junk
tx := make([]byte, 250)
binary.PutUvarint(tx[:32], uint64(valI))
binary.PutUvarint(tx[32:64], uint64(i))
if _, err := rand.Read(tx[65:]); err != nil {
fmt.Println("err reading from crypto/rand", err)
os.Exit(1)
}
return tx
}
func monitorTask(endpoint string) {
fmt.Println("Monitor task started...")
var duration = 5 * time.Second
const subscriber = "monitor"
ctx, cancel := context.WithTimeout(context.Background(), duration)
defer cancel()
evts := make(chan interface{})
var httpClient = getHTTPClient(endpoint)
httpClient.Start()
evtTyp := types.EventNewBlockHeader
// register for the next event of this type
query := types.QueryForEvent(evtTyp)
err := httpClient.Subscribe(ctx, subscriber, query, evts)
if err != nil {
fmt.Println("error when subscribing", err)
}
// make sure to unregister after the test is over
defer httpClient.UnsubscribeAll(ctx, subscriber)
totalNumOfCommittedTxs := int64(0)
for {
fmt.Println("Starting main loop", err)
select {
case evt := <-evts:
event := evt.(types.TMEventData)
header, ok := event.Unwrap().(types.EventDataNewBlockHeader)
if ok {
fmt.Println("received header\n", header.Header.StringIndented(""))
} else {
fmt.Println("not able to unwrap header")
}
// Do some metric computation with header
totalNumOfCommittedTxs += header.Header.NumTxs
case <-ctx.Done():
fmt.Printf("Finished monitor task. Received %d transactions \n", totalNumOfCommittedTxs)
mutex.Lock()
finishedTasks++
mutex.Unlock()
return
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@ message ResultStatus {
} }
message NodeInfo { message NodeInfo {
required PubKey pubKey = 1; required ID id = 1;
required string moniker = 2; required string moniker = 2;
required string network = 3; required string network = 3;
required string remoteAddr = 4; required string remoteAddr = 4;
@@ -16,6 +16,10 @@ message NodeInfo {
repeated string other = 7; repeated string other = 7;
} }
message ID {
required string id = 1;
}
message PubKey { message PubKey {
optional PubKeyEd25519 ed25519 = 1; optional PubKeyEd25519 ed25519 = 1;
} }

View File

@@ -5,7 +5,7 @@ import (
"reflect" "reflect"
"time" "time"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
sm "github.com/tendermint/tendermint/state" sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"

View File

@@ -1,7 +1,7 @@
package blockchain package blockchain
import ( import (
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
) )

View File

@@ -0,0 +1,32 @@
package commands
import (
"fmt"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/p2p"
cmn "github.com/tendermint/tmlibs/common"
)
// GenNodeKeyCmd allows the generation of a node key. It prints node's ID to
// the standard output.
var GenNodeKeyCmd = &cobra.Command{
Use: "gen_node_key",
Short: "Generate a node key for this node and print its ID",
RunE: genNodeKey,
}
func genNodeKey(cmd *cobra.Command, args []string) error {
nodeKeyFile := config.NodeKeyFile()
if cmn.FileExists(nodeKeyFile) {
return fmt.Errorf("node key at %s already exists", nodeKeyFile)
}
nodeKey, err := p2p.LoadOrGenNodeKey(nodeKeyFile)
if err != nil {
return err
}
fmt.Println(nodeKey.ID())
return nil
}

View File

@@ -3,6 +3,8 @@ package commands
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
pvm "github.com/tendermint/tendermint/types/priv_validator" pvm "github.com/tendermint/tendermint/types/priv_validator"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
@@ -12,10 +14,14 @@ import (
var InitFilesCmd = &cobra.Command{ var InitFilesCmd = &cobra.Command{
Use: "init", Use: "init",
Short: "Initialize Tendermint", Short: "Initialize Tendermint",
Run: initFiles, RunE: initFiles,
} }
func initFiles(cmd *cobra.Command, args []string) { func initFiles(cmd *cobra.Command, args []string) error {
return initFilesWithConfig(config)
}
func initFilesWithConfig(config *cfg.Config) error {
// private validator // private validator
privValFile := config.PrivValidatorFile() privValFile := config.PrivValidatorFile()
var pv *pvm.FilePV var pv *pvm.FilePV
@@ -28,6 +34,16 @@ func initFiles(cmd *cobra.Command, args []string) {
logger.Info("Generated private validator", "path", privValFile) logger.Info("Generated private validator", "path", privValFile)
} }
nodeKeyFile := config.NodeKeyFile()
if cmn.FileExists(nodeKeyFile) {
logger.Info("Found node key", "path", nodeKeyFile)
} else {
if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil {
return err
}
logger.Info("Generated node key", "path", nodeKeyFile)
}
// genesis file // genesis file
genFile := config.GenesisFile() genFile := config.GenesisFile()
if cmn.FileExists(genFile) { if cmn.FileExists(genFile) {
@@ -42,8 +58,10 @@ func initFiles(cmd *cobra.Command, args []string) {
}} }}
if err := genDoc.SaveAs(genFile); err != nil { if err := genDoc.SaveAs(genFile); err != nil {
panic(err) return err
} }
logger.Info("Generated genesis file", "path", genFile) logger.Info("Generated genesis file", "path", genFile)
} }
return nil
} }

View File

@@ -16,10 +16,12 @@ var ShowNodeIDCmd = &cobra.Command{
} }
func showNodeID(cmd *cobra.Command, args []string) error { func showNodeID(cmd *cobra.Command, args []string) error {
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile())
if err != nil { if err != nil {
return err return err
} }
fmt.Println(nodeKey.ID()) fmt.Println(nodeKey.ID())
return nil return nil
} }

View File

@@ -2,6 +2,7 @@ package commands
import ( import (
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
privval "github.com/tendermint/tendermint/types/priv_validator" privval "github.com/tendermint/tendermint/types/priv_validator"

View File

@@ -2,60 +2,103 @@ package commands
import ( import (
"fmt" "fmt"
"net"
"os"
"path/filepath" "path/filepath"
"strings"
"time" "time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
cfg "github.com/tendermint/tendermint/config" cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
pvm "github.com/tendermint/tendermint/types/priv_validator" pvm "github.com/tendermint/tendermint/types/priv_validator"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
) )
//flags
var ( var (
nValidators int nValidators int
dataDir string nNonValidators int
outputDir string
nodeDirPrefix string
populatePersistentPeers bool
hostnamePrefix string
startingIPAddress string
p2pPort int
)
const (
nodeDirPerm = 0755
) )
func init() { func init() {
TestnetFilesCmd.Flags().IntVar(&nValidators, "n", 4, TestnetFilesCmd.Flags().IntVar(&nValidators, "v", 4,
"Number of validators to initialize the testnet with") "Number of validators to initialize the testnet with")
TestnetFilesCmd.Flags().StringVar(&dataDir, "dir", "mytestnet", TestnetFilesCmd.Flags().IntVar(&nNonValidators, "n", 0,
"Number of non-validators to initialize the testnet with")
TestnetFilesCmd.Flags().StringVar(&outputDir, "o", "./mytestnet",
"Directory to store initialization data for the testnet") "Directory to store initialization data for the testnet")
TestnetFilesCmd.Flags().StringVar(&nodeDirPrefix, "node-dir-prefix", "node",
"Prefix the directory name for each node with (node results in node0, node1, ...)")
TestnetFilesCmd.Flags().BoolVar(&populatePersistentPeers, "populate-persistent-peers", true,
"Update config of each node with the list of persistent peers build using either hostname-prefix or starting-ip-address")
TestnetFilesCmd.Flags().StringVar(&hostnamePrefix, "hostname-prefix", "node",
"Hostname prefix (node results in persistent peers list ID0@node0:46656, ID1@node1:46656, ...)")
TestnetFilesCmd.Flags().StringVar(&startingIPAddress, "starting-ip-address", "",
"Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
TestnetFilesCmd.Flags().IntVar(&p2pPort, "p2p-port", 46656,
"P2P Port")
} }
// TestnetFilesCmd allows initialisation of files for a // TestnetFilesCmd allows initialisation of files for a Tendermint testnet.
// Tendermint testnet.
var TestnetFilesCmd = &cobra.Command{ var TestnetFilesCmd = &cobra.Command{
Use: "testnet", Use: "testnet",
Short: "Initialize files for a Tendermint testnet", Short: "Initialize files for a Tendermint testnet",
Run: testnetFiles, RunE: testnetFiles,
} }
func testnetFiles(cmd *cobra.Command, args []string) { func testnetFiles(cmd *cobra.Command, args []string) error {
config := cfg.DefaultConfig()
genVals := make([]types.GenesisValidator, nValidators) genVals := make([]types.GenesisValidator, nValidators)
defaultConfig := cfg.DefaultBaseConfig()
// Initialize core dir and priv_validator.json's
for i := 0; i < nValidators; i++ { for i := 0; i < nValidators; i++ {
mach := cmn.Fmt("mach%d", i) nodeDirName := cmn.Fmt("%s%d", nodeDirPrefix, i)
err := initMachCoreDirectory(dataDir, mach) nodeDir := filepath.Join(outputDir, nodeDirName)
config.SetRoot(nodeDir)
err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm)
if err != nil { if err != nil {
cmn.Exit(err.Error()) _ = os.RemoveAll(outputDir)
return err
} }
// Read priv_validator.json to populate vals
pvFile := filepath.Join(dataDir, mach, defaultConfig.PrivValidator) initFilesWithConfig(config)
pvFile := filepath.Join(nodeDir, config.BaseConfig.PrivValidator)
pv := pvm.LoadFilePV(pvFile) pv := pvm.LoadFilePV(pvFile)
genVals[i] = types.GenesisValidator{ genVals[i] = types.GenesisValidator{
PubKey: pv.GetPubKey(), PubKey: pv.GetPubKey(),
Power: 1, Power: 1,
Name: mach, Name: nodeDirName,
} }
} }
for i := 0; i < nNonValidators; i++ {
nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i+nValidators))
config.SetRoot(nodeDir)
err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm)
if err != nil {
_ = os.RemoveAll(outputDir)
return err
}
initFilesWithConfig(config)
}
// Generate genesis doc from generated validators // Generate genesis doc from generated validators
genDoc := &types.GenesisDoc{ genDoc := &types.GenesisDoc{
GenesisTime: time.Now(), GenesisTime: time.Now(),
@@ -64,36 +107,65 @@ func testnetFiles(cmd *cobra.Command, args []string) {
} }
// Write genesis file. // Write genesis file.
for i := 0; i < nValidators; i++ { for i := 0; i < nValidators+nNonValidators; i++ {
mach := cmn.Fmt("mach%d", i) nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i))
if err := genDoc.SaveAs(filepath.Join(dataDir, mach, defaultConfig.Genesis)); err != nil { if err := genDoc.SaveAs(filepath.Join(nodeDir, config.BaseConfig.Genesis)); err != nil {
panic(err) _ = os.RemoveAll(outputDir)
return err
} }
} }
fmt.Println(cmn.Fmt("Successfully initialized %v node directories", nValidators)) if populatePersistentPeers {
} err := populatePersistentPeersInConfigAndWriteIt(config)
if err != nil {
// Initialize per-machine core directory _ = os.RemoveAll(outputDir)
func initMachCoreDirectory(base, mach string) error { return err
// Create priv_validator.json file if not present }
defaultConfig := cfg.DefaultBaseConfig()
dir := filepath.Join(base, mach)
pvPath := filepath.Join(dir, defaultConfig.PrivValidator)
dir = filepath.Dir(pvPath)
err := cmn.EnsureDir(dir, 0700)
if err != nil {
return err
} }
ensurePrivValidator(pvPath)
fmt.Printf("Successfully initialized %v node directories\n", nValidators+nNonValidators)
return nil return nil
} }
func ensurePrivValidator(file string) { func hostnameOrIP(i int) string {
if cmn.FileExists(file) { if startingIPAddress != "" {
return ip := net.ParseIP(startingIPAddress)
ip = ip.To4()
if ip == nil {
fmt.Printf("%v: non ipv4 address\n", startingIPAddress)
os.Exit(1)
}
for j := 0; j < i; j++ {
ip[3]++
}
return ip.String()
} }
pv := pvm.GenFilePV(file)
pv.Save() return fmt.Sprintf("%s%d", hostnamePrefix, i)
}
func populatePersistentPeersInConfigAndWriteIt(config *cfg.Config) error {
persistentPeers := make([]string, nValidators+nNonValidators)
for i := 0; i < nValidators+nNonValidators; i++ {
nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i))
config.SetRoot(nodeDir)
nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile())
if err != nil {
return err
}
persistentPeers[i] = p2p.IDAddressString(nodeKey.ID(), fmt.Sprintf("%s:%d", hostnameOrIP(i), p2pPort))
}
persistentPeersList := strings.Join(persistentPeers, ",")
for i := 0; i < nValidators+nNonValidators; i++ {
nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i))
config.SetRoot(nodeDir)
config.P2P.PersistentPeers = persistentPeersList
// overwrite default config
cfg.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), config)
}
return nil
} }

View File

@@ -1,7 +1,7 @@
package commands package commands
import ( import (
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
) )

View File

@@ -25,6 +25,7 @@ func main() {
cmd.ShowValidatorCmd, cmd.ShowValidatorCmd,
cmd.TestnetFilesCmd, cmd.TestnetFilesCmd,
cmd.ShowNodeIDCmd, cmd.ShowNodeIDCmd,
cmd.GenNodeKeyCmd,
cmd.VersionCmd) cmd.VersionCmd)
// NOTE: // NOTE:

View File

@@ -37,16 +37,21 @@ func EnsureRoot(rootDir string) {
// Write default config file if missing. // Write default config file if missing.
if !cmn.FileExists(configFilePath) { if !cmn.FileExists(configFilePath) {
writeConfigFile(configFilePath) writeDefaultCondigFile(configFilePath)
} }
} }
// XXX: this func should probably be called by cmd/tendermint/commands/init.go // XXX: this func should probably be called by cmd/tendermint/commands/init.go
// alongside the writing of the genesis.json and priv_validator.json // alongside the writing of the genesis.json and priv_validator.json
func writeConfigFile(configFilePath string) { func writeDefaultCondigFile(configFilePath string) {
WriteConfigFile(configFilePath, DefaultConfig())
}
// WriteConfigFile renders config using the template and writes it to configFilePath.
func WriteConfigFile(configFilePath string, config *Config) {
var buffer bytes.Buffer var buffer bytes.Buffer
if err := configTemplate.Execute(&buffer, DefaultConfig()); err != nil { if err := configTemplate.Execute(&buffer, config); err != nil {
panic(err) panic(err)
} }
@@ -124,11 +129,11 @@ unsafe = {{ .RPC.Unsafe }}
laddr = "{{ .P2P.ListenAddress }}" laddr = "{{ .P2P.ListenAddress }}"
# Comma separated list of seed nodes to connect to # Comma separated list of seed nodes to connect to
seeds = "" seeds = "{{ .P2P.Seeds }}"
# Comma separated list of nodes to keep persistent connections to # Comma separated list of nodes to keep persistent connections to
# Do not add private peers to this list if you don't want them advertised # Do not add private peers to this list if you don't want them advertised
persistent_peers = "" persistent_peers = "{{ .P2P.PersistentPeers }}"
# Path to address book # Path to address book
addr_book_file = "{{ .P2P.AddrBook }}" addr_book_file = "{{ .P2P.AddrBook }}"
@@ -262,7 +267,7 @@ func ResetTestRoot(testName string) *Config {
// Write default config file if missing. // Write default config file if missing.
if !cmn.FileExists(configFilePath) { if !cmn.FileExists(configFilePath) {
writeConfigFile(configFilePath) writeDefaultCondigFile(configFilePath)
} }
if !cmn.FileExists(genesisFilePath) { if !cmn.FileExists(genesisFilePath) {
cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644) cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644)

View File

@@ -395,7 +395,7 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF
func getSwitchIndex(switches []*p2p.Switch, peer p2p.Peer) int { func getSwitchIndex(switches []*p2p.Switch, peer p2p.Peer) int {
for i, s := range switches { for i, s := range switches {
if bytes.Equal(peer.NodeInfo().PubKey.Address(), s.NodeInfo().PubKey.Address()) { if peer.NodeInfo().ID == s.NodeInfo().ID {
return i return i
} }
} }

View File

@@ -9,7 +9,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tmlibs/log" "github.com/tendermint/tmlibs/log"
@@ -838,8 +838,8 @@ var (
ErrPeerStateInvalidStartTime = errors.New("Error peer state invalid startTime") ErrPeerStateInvalidStartTime = errors.New("Error peer state invalid startTime")
) )
// PeerState contains the known state of a peer, including its connection // PeerState contains the known state of a peer, including its connection and
// and threadsafe access to its PeerRoundState. // threadsafe access to its PeerRoundState.
type PeerState struct { type PeerState struct {
Peer p2p.Peer Peer p2p.Peer
logger log.Logger logger log.Logger
@@ -878,12 +878,14 @@ func NewPeerState(peer p2p.Peer) *PeerState {
} }
} }
// SetLogger allows to set a logger on the peer state. Returns the peer state
// itself.
func (ps *PeerState) SetLogger(logger log.Logger) *PeerState { func (ps *PeerState) SetLogger(logger log.Logger) *PeerState {
ps.logger = logger ps.logger = logger
return ps return ps
} }
// GetRoundState returns an atomic snapshot of the PeerRoundState. // GetRoundState returns an shallow copy of the PeerRoundState.
// There's no point in mutating it since it won't change PeerState. // There's no point in mutating it since it won't change PeerState.
func (ps *PeerState) GetRoundState() *cstypes.PeerRoundState { func (ps *PeerState) GetRoundState() *cstypes.PeerRoundState {
ps.mtx.Lock() ps.mtx.Lock()
@@ -893,6 +895,14 @@ func (ps *PeerState) GetRoundState() *cstypes.PeerRoundState {
return &prs return &prs
} }
// GetRoundStateJSON returns a json of PeerRoundState, marshalled using go-amino.
func (ps *PeerState) GetRoundStateJSON() ([]byte, error) {
ps.mtx.Lock()
defer ps.mtx.Unlock()
return cdc.MarshalJSON(ps.PeerRoundState)
}
// GetHeight returns an atomic snapshot of the PeerRoundState's height // GetHeight returns an atomic snapshot of the PeerRoundState's height
// used by the mempool to ensure peers are caught up before broadcasting new txs // used by the mempool to ensure peers are caught up before broadcasting new txs
func (ps *PeerState) GetHeight() int64 { func (ps *PeerState) GetHeight() int64 {
@@ -1055,7 +1065,7 @@ func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numValida
} }
} }
// EnsureVoteVitArrays ensures the bit-arrays have been allocated for tracking // EnsureVoteBitArrays ensures the bit-arrays have been allocated for tracking
// what votes this peer has received. // what votes this peer has received.
// NOTE: It's important to make sure that numValidators actually matches // NOTE: It's important to make sure that numValidators actually matches
// what the node sees as the number of validators for height. // what the node sees as the number of validators for height.

View File

@@ -168,18 +168,23 @@ func (cs *ConsensusState) GetState() sm.State {
return cs.state.Copy() return cs.state.Copy()
} }
// GetRoundState returns a copy of the internal consensus state. // GetRoundState returns a shallow copy of the internal consensus state.
func (cs *ConsensusState) GetRoundState() *cstypes.RoundState { func (cs *ConsensusState) GetRoundState() *cstypes.RoundState {
cs.mtx.Lock() cs.mtx.Lock()
defer cs.mtx.Unlock() defer cs.mtx.Unlock()
return cs.getRoundState()
}
func (cs *ConsensusState) getRoundState() *cstypes.RoundState {
rs := cs.RoundState // copy rs := cs.RoundState // copy
return &rs return &rs
} }
// GetRoundStateJSON returns a json of RoundState, marshalled using go-amino.
func (cs *ConsensusState) GetRoundStateJSON() ([]byte, error) {
cs.mtx.Lock()
defer cs.mtx.Unlock()
return cdc.MarshalJSON(cs.RoundState)
}
// GetValidators returns a copy of the current validators. // GetValidators returns a copy of the current validators.
func (cs *ConsensusState) GetValidators() (int64, []*types.Validator) { func (cs *ConsensusState) GetValidators() (int64, []*types.Validator) {
cs.mtx.Lock() cs.mtx.Lock()

View File

@@ -52,9 +52,6 @@ func (rs RoundStepType) String() string {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// RoundState defines the internal consensus state. // RoundState defines the internal consensus state.
// It is Immutable when returned from ConsensusState.GetRoundState()
// TODO: Actually, only the top pointer is copied,
// so access to field pointers is still racey
// NOTE: Not thread safe. Should only be manipulated by functions downstream // NOTE: Not thread safe. Should only be manipulated by functions downstream
// of the cs.receiveRoutine // of the cs.receiveRoutine
type RoundState struct { type RoundState struct {

View File

@@ -10,7 +10,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
auto "github.com/tendermint/tmlibs/autofile" auto "github.com/tendermint/tmlibs/autofile"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"

View File

@@ -4,7 +4,6 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"fmt" "fmt"
"math/rand"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -117,7 +116,7 @@ func makePathname() string {
func randPort() int { func randPort() int {
// returns between base and base + spread // returns between base and base + spread
base, spread := 20000, 20000 base, spread := 20000, 20000
return base + rand.Intn(spread) return base + cmn.RandIntn(spread)
} }
func makeAddrs() (string, string, string) { func makeAddrs() (string, string, string) {

View File

@@ -1,7 +1,7 @@
package consensus package consensus
import ( import (
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
) )

68
docker-compose.yml Normal file
View File

@@ -0,0 +1,68 @@
version: '3'
services:
node0:
container_name: node0
image: "tendermint/localnode"
ports:
- "46656-46657:46656-46657"
environment:
- ID=0
- LOG=${LOG:-tendermint.log}
volumes:
- ${FOLDER:-./build}:/tendermint:Z
networks:
localnet:
ipv4_address: 192.167.10.2
node1:
container_name: node1
image: "tendermint/localnode"
ports:
- "46659-46660:46656-46657"
environment:
- ID=1
- LOG=${LOG:-tendermint.log}
volumes:
- ${FOLDER:-./build}:/tendermint:Z
networks:
localnet:
ipv4_address: 192.167.10.3
node2:
container_name: node2
image: "tendermint/localnode"
environment:
- ID=2
- LOG=${LOG:-tendermint.log}
ports:
- "46661-46662:46656-46657"
volumes:
- ${FOLDER:-./build}:/tendermint:Z
networks:
localnet:
ipv4_address: 192.167.10.4
node3:
container_name: node3
image: "tendermint/localnode"
environment:
- ID=3
- LOG=${LOG:-tendermint.log}
ports:
- "46663-46664:46656-46657"
volumes:
- ${FOLDER:-./build}:/tendermint:Z
networks:
localnet:
ipv4_address: 192.167.10.5
networks:
localnet:
driver: bridge
ipam:
driver: default
config:
-
subnet: 192.167.10.0/16

7
docker-compose/Makefile Normal file
View File

@@ -0,0 +1,7 @@
# Makefile for the "localnode" docker image.
all:
docker build --tag tendermint/localnode localnode
.PHONY: all

40
docker-compose/README.rst Normal file
View File

@@ -0,0 +1,40 @@
localnode
=========
It is assumed that you have already `setup docker <https://docs.docker.com/engine/installation/>`__.
Description
-----------
Image for local testnets.
Add the tendermint binary to the image by attaching it in a folder to the `/tendermint` mount point.
It assumes that the configuration was created by the `tendermint testnet` command and it is also attached to the `/tendermint` mount point.
Example:
This example builds a linux tendermint binary under the `build/` folder, creates tendermint configuration for a single-node validator and runs the node:
```
cd $GOPATH/src/github.com/tendermint/tendermint
#Build binary
make build-linux
#Create configuration
docker run -e LOG="stdout" -v `pwd`/build:/tendermint tendermint/localnode testnet --o . --v 1
#Run the node
docker run -v `pwd`/build:/tendermint tendermint/localnode
```
Logging
-------
Log is saved under the attached volume, in the `tendermint.log` file. If the `LOG` environment variable is set to `stdout` at start, the log is not saved, but printed on the screen.
Special binaries
----------------
If you have multiple binaries with different names, you can specify which one to run with the BINARY environment variable. The path of the binary is relative to the attached volume.
docker-compose.yml
==================
This file creates a 4-node network using the localnode image. The nodes of the network are exposed to the host machine on ports 46656-46657, 46659-46660, 46661-46662, 46663-46664 respectively.

View File

@@ -0,0 +1,16 @@
FROM alpine:3.7
MAINTAINER Greg Szabo <greg@tendermint.com>
RUN apk update && \
apk upgrade && \
apk --no-cache add curl jq file
VOLUME [ /tendermint ]
WORKDIR /tendermint
EXPOSE 46656 46657
ENTRYPOINT ["/usr/bin/wrapper.sh"]
CMD ["node", "--proxy_app dummy"]
STOPSIGNAL SIGTERM
COPY wrapper.sh /usr/bin/wrapper.sh

View File

@@ -0,0 +1,33 @@
#!/usr/bin/env sh
##
## Input parameters
##
BINARY=/tendermint/${BINARY:-tendermint}
ID=${ID:-0}
LOG=${LOG:-tendermint.log}
##
## Assert linux binary
##
if ! [ -f "${BINARY}" ]; then
echo "The binary `basename ${BINARY}` cannot be found. Please add the binary to the shared folder. Please use the BINARY environment variable if the name of the binary is not 'tendermint' E.g.: -e BINARY=tendermint_my_test_version"
exit 1
fi
BINARY_CHECK="`file $BINARY | grep 'ELF 64-bit LSB executable, x86-64'`"
if [ -z "${BINARY_CHECK}" ]; then
echo "Binary needs to be OS linux, ARCH amd64"
exit 1
fi
##
## Run binary with all parameters
##
export TMHOME="/tendermint/node${ID}"
if [ -d "${TMHOME}/${LOG}" ]; then
"$BINARY" $@ | tee "${TMHOME}/${LOG}"
else
"$BINARY" $@
fi

View File

@@ -11,26 +11,26 @@ Manual Deployments
It's relatively easy to setup a Tendermint cluster manually. The only It's relatively easy to setup a Tendermint cluster manually. The only
requirements for a particular Tendermint node are a private key for the requirements for a particular Tendermint node are a private key for the
validator, stored as ``priv_validator.json``, and a list of the public validator, stored as ``priv_validator.json``, a node key, stored as
keys of all validators, stored as ``genesis.json``. These files should ``node_key.json`` and a list of the public keys of all validators, stored as
be stored in ``~/.tendermint/config``, or wherever the ``$TMHOME`` variable ``genesis.json``. These files should be stored in ``~/.tendermint/config``, or
might be set to. wherever the ``$TMHOME`` variable might be set to.
Here are the steps to setting up a testnet manually: Here are the steps to setting up a testnet manually:
1) Provision nodes on your cloud provider of choice 1) Provision nodes on your cloud provider of choice
2) Install Tendermint and the application of interest on all nodes 2) Install Tendermint and the application of interest on all nodes
3) Generate a private key for each validator using 3) Generate a private key and a node key for each validator using
``tendermint gen_validator`` ``tendermint init``
4) Compile a list of public keys for each validator into a 4) Compile a list of public keys for each validator into a
``genesis.json`` file. ``genesis.json`` file and replace the existing file with it.
5) Run ``tendermint node --p2p.persistent_peers=< peer addresses >`` on each node, 5) Run ``tendermint node --p2p.persistent_peers=< peer addresses >`` on each node,
where ``< peer addresses >`` is a comma separated list of the IP:PORT where ``< peer addresses >`` is a comma separated list of the IP:PORT
combination for each node. The default port for Tendermint is combination for each node. The default port for Tendermint is
``46656``. Thus, if the IP addresses of your nodes were ``46656``. Thus, if the IP addresses of your nodes were
``192.168.0.1, 192.168.0.2, 192.168.0.3, 192.168.0.4``, the command ``192.168.0.1, 192.168.0.2, 192.168.0.3, 192.168.0.4``, the command
would look like: would look like:
``tendermint node --p2p.persistent_peers=192.168.0.1:46656,192.168.0.2:46656,192.168.0.3:46656,192.168.0.4:46656``. ``tendermint node --p2p.persistent_peers=96663a3dd0d7b9d17d4c8211b191af259621c693@192.168.0.1:46656, 429fcf25974313b95673f58d77eacdd434402665@192.168.0.2:46656, 0491d373a8e0fcf1023aaf18c51d6a1d0d4f31bd@192.168.0.3:46656, f9baeaa15fedf5e1ef7448dd60f46c01f1a9e9c4@192.168.0.4:46656``.
After a few seconds, all the nodes should connect to each other and start After a few seconds, all the nodes should connect to each other and start
making blocks! For more information, see the Tendermint Networks section making blocks! For more information, see the Tendermint Networks section

View File

@@ -2,8 +2,9 @@
## Overview ## Overview
This is a quick start guide. If you have a vague idea about how Tendermint works This is a quick start guide. If you have a vague idea about how Tendermint
and want to get started right away, continue. Otherwise, [review the documentation](http://tendermint.readthedocs.io/en/master/) works and want to get started right away, continue. Otherwise, [review the
documentation](http://tendermint.readthedocs.io/en/master/).
## Install ## Install
@@ -42,7 +43,7 @@ Confirm installation:
``` ```
$ tendermint version $ tendermint version
0.15.0-381fe19 0.18.0-XXXXXXX
``` ```
## Initialization ## Initialization
@@ -117,7 +118,9 @@ where the value is returned in hex.
## Cluster of Nodes ## Cluster of Nodes
First create four Ubuntu cloud machines. The following was tested on Digital Ocean Ubuntu 16.04 x64 (3GB/1CPU, 20GB SSD). We'll refer to their respective IP addresses below as IP1, IP2, IP3, IP4. First create four Ubuntu cloud machines. The following was tested on Digital
Ocean Ubuntu 16.04 x64 (3GB/1CPU, 20GB SSD). We'll refer to their respective IP
addresses below as IP1, IP2, IP3, IP4.
Then, `ssh` into each machine, and execute [this script](https://git.io/vNLfY): Then, `ssh` into each machine, and execute [this script](https://git.io/vNLfY):
@@ -131,12 +134,16 @@ This will install `go` and other dependencies, get the Tendermint source code, t
Next, `cd` into `docs/examples`. Each command below should be run from each node, in sequence: Next, `cd` into `docs/examples`. Each command below should be run from each node, in sequence:
``` ```
tendermint node --home ./node1 --proxy_app=kvstore --p2p.seeds IP1:46656,IP2:46656,IP3:46656,IP4:46656 tendermint node --home ./node1 --proxy_app=kvstore --p2p.persistent_peers="3a558bd6f8c97453aa6c2372bb800e8b6ed8e6db@IP1:46656,ccf30d873fddda10a495f42687c8f33472a6569f@IP2:46656,9a4c3de5d6788a76c6ee3cd9ff41e3b45b4cfd14@IP3:46656,58e6f2ab297b3ceae107ba4c8c2898da5c009ff4@IP4:46656"
tendermint node --home ./node2 --proxy_app=kvstore --p2p.seeds IP1:46656,IP2:46656,IP3:46656,IP4:46656 tendermint node --home ./node2 --proxy_app=kvstore --p2p.persistent_peers="3a558bd6f8c97453aa6c2372bb800e8b6ed8e6db@IP1:46656,ccf30d873fddda10a495f42687c8f33472a6569f@IP2:46656,9a4c3de5d6788a76c6ee3cd9ff41e3b45b4cfd14@IP3:46656,58e6f2ab297b3ceae107ba4c8c2898da5c009ff4@IP4:46656"
tendermint node --home ./node3 --proxy_app=kvstore --p2p.seeds IP1:46656,IP2:46656,IP3:46656,IP4:46656 tendermint node --home ./node3 --proxy_app=kvstore --p2p.persistent_peers="3a558bd6f8c97453aa6c2372bb800e8b6ed8e6db@IP1:46656,ccf30d873fddda10a495f42687c8f33472a6569f@IP2:46656,9a4c3de5d6788a76c6ee3cd9ff41e3b45b4cfd14@IP3:46656,58e6f2ab297b3ceae107ba4c8c2898da5c009ff4@IP4:46656"
tendermint node --home ./node4 --proxy_app=kvstore --p2p.seeds IP1:46656,IP2:46656,IP3:46656,IP4:46656 tendermint node --home ./node4 --proxy_app=kvstore --p2p.persistent_peers="3a558bd6f8c97453aa6c2372bb800e8b6ed8e6db@IP1:46656,ccf30d873fddda10a495f42687c8f33472a6569f@IP2:46656,9a4c3de5d6788a76c6ee3cd9ff41e3b45b4cfd14@IP3:46656,58e6f2ab297b3ceae107ba4c8c2898da5c009ff4@IP4:46656"
``` ```
Note that after the third node is started, blocks will start to stream in because >2/3 of validators (defined in the `genesis.json`) have come online. Seeds can also be specified in the `config.toml`. See [this PR](https://github.com/tendermint/tendermint/pull/792) for more information about configuration options. Note that after the third node is started, blocks will start to stream in
because >2/3 of validators (defined in the `genesis.json`) have come online.
Seeds can also be specified in the `config.toml`. See [this
PR](https://github.com/tendermint/tendermint/pull/792) for more information
about configuration options.
Transactions can then be sent as covered in the single, local node example above. Transactions can then be sent as covered in the single, local node example above.

View File

@@ -26,7 +26,7 @@ go get $REPO
cd $GOPATH/src/$REPO cd $GOPATH/src/$REPO
## build ## build
git checkout v0.17.0 git checkout v0.18.0
make get_tools make get_tools
make get_vendor_deps make get_vendor_deps
make install make install

View File

@@ -0,0 +1,6 @@
{
"priv_key" : {
"data" : "DA9BAABEA7211A6D93D9A1986B4279EAB3021FAA1653D459D53E6AB4D1CFB4C69BF7D52E48CF00AC5779AA0A6D3C368955D5636A677F72370B8ED19989714CFC",
"type" : "ed25519"
}
}

View File

@@ -0,0 +1,6 @@
{
"priv_key" : {
"data" : "F7BCABA165DFC0DDD50AE563EFB285BAA236EA805D35612504238A36EFA105958756442B1D9F942D7ABD259F2D59671657B6378E9C7194342A7AAA47A66D1E95",
"type" : "ed25519"
}
}

View File

@@ -0,0 +1,6 @@
{
"priv_key" : {
"data" : "95136FCC97E4446B3141EDF9841078107ECE755E99925D79CCBF91085492680B3CA1034D9917DF1DED4E4AB2D9BC225919F6CB2176F210D2368697CC339DF4E7",
"type" : "ed25519"
}
}

View File

@@ -0,0 +1,6 @@
{
"priv_key" : {
"data" : "8895D6C9A1B46AB83A8E2BAE2121B8C3E245B9E9126EBD797FEAC5058285F2F64FDE2E8182C88AD5185A49D837C581465D57BD478C41865A66D7D9742D8AEF57",
"type" : "ed25519"
}
}

View File

@@ -81,9 +81,8 @@ Tendermint node as follows:
curl -s localhost:46657/status curl -s localhost:46657/status
The ``-s`` just silences ``curl``. For nicer output, pipe the result The ``-s`` just silences ``curl``. For nicer output, pipe the result into a
into a tool like `jq <https://stedolan.github.io/jq/>`__ or tool like `jq <https://stedolan.github.io/jq/>`__ or ``json_pp``.
`jsonpp <https://github.com/jmhodges/jsonpp>`__.
Now let's send some transactions to the kvstore. Now let's send some transactions to the kvstore.
@@ -104,17 +103,23 @@ like:
"id": "", "id": "",
"result": { "result": {
"check_tx": { "check_tx": {
"code": 0, "fee": {}
"data": "",
"log": ""
}, },
"deliver_tx": { "deliver_tx": {
"code": 0, "tags": [
"data": "", {
"log": "" "key": "YXBwLmNyZWF0b3I=",
"value": "amFl"
},
{
"key": "YXBwLmtleQ==",
"value": "YWJjZA=="
}
],
"fee": {}
}, },
"hash": "2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF", "hash": "9DF66553F98DE3C26E3C3317A3E4CED54F714E39",
"height": 154 "height": 14
} }
} }
@@ -134,20 +139,17 @@ The result should look like:
"id": "", "id": "",
"result": { "result": {
"response": { "response": {
"code": 0, "log": "exists",
"index": 0, "index": "-1",
"key": "", "key": "YWJjZA==",
"value": "61626364", "value": "YWJjZA=="
"proof": "",
"height": 0,
"log": "exists"
} }
} }
} }
Note the ``value`` in the result (``61626364``); this is the Note the ``value`` in the result (``YWJjZA==``); this is the
hex-encoding of the ASCII of ``abcd``. You can verify this in base64-encoding of the ASCII of ``abcd``. You can verify this in
a python 2 shell by running ``"61626364".decode('hex')`` or in python 3 shell by running ``import codecs; codecs.decode("61626364", 'hex').decode('ascii')``. Stay a python 2 shell by running ``"61626364".decode('base64')`` or in python 3 shell by running ``import codecs; codecs.decode("61626364", 'base64').decode('ascii')``. Stay
tuned for a future release that `makes this output more human-readable <https://github.com/tendermint/abci/issues/32>`__. tuned for a future release that `makes this output more human-readable <https://github.com/tendermint/abci/issues/32>`__.
Now let's try setting a different key and value: Now let's try setting a different key and value:
@@ -157,7 +159,7 @@ Now let's try setting a different key and value:
curl -s 'localhost:46657/broadcast_tx_commit?tx="name=satoshi"' curl -s 'localhost:46657/broadcast_tx_commit?tx="name=satoshi"'
Now if we query for ``name``, we should get ``satoshi``, or Now if we query for ``name``, we should get ``satoshi``, or
``7361746F736869`` in hex: ``c2F0b3NoaQ==`` in base64:
:: ::
@@ -226,17 +228,15 @@ the number ``1``. If instead, we try to send a ``5``, we get an error:
"id": "", "id": "",
"result": { "result": {
"check_tx": { "check_tx": {
"code": 0, "fee": {}
"data": "",
"log": ""
}, },
"deliver_tx": { "deliver_tx": {
"code": 3, "code": 2,
"data": "", "log": "Invalid nonce. Expected 1, got 5",
"log": "Invalid nonce. Expected 1, got 5" "fee": {}
}, },
"hash": "33B93DFF98749B0D6996A70F64071347060DC19C", "hash": "33B93DFF98749B0D6996A70F64071347060DC19C",
"height": 38 "height": 34
} }
} }
@@ -250,17 +250,13 @@ But if we send a ``1``, it works again:
"id": "", "id": "",
"result": { "result": {
"check_tx": { "check_tx": {
"code": 0, "fee": {}
"data": "",
"log": ""
}, },
"deliver_tx": { "deliver_tx": {
"code": 0, "fee": {}
"data": "",
"log": ""
}, },
"hash": "F17854A977F6FA7EEA1BD758E296710B86F72F3D", "hash": "F17854A977F6FA7EEA1BD758E296710B86F72F3D",
"height": 87 "height": 60
} }
} }

View File

@@ -59,7 +59,7 @@ Next we replay all the messages from the WAL.
:: ::
I[10-04|13:54:30.391] Starting RPC HTTP server on tcp socket 0.0.0.0:46657 module=rpc-server I[10-04|13:54:30.391] Starting RPC HTTP server on tcp socket 0.0.0.0:46657 module=rpc-server
I[10-04|13:54:30.392] Started node module=main nodeInfo="NodeInfo{pk: PubKeyEd25519{DF22D7C92C91082324A1312F092AA1DA197FA598DBBFB6526E177003C4D6FD66}, moniker: anonymous, network: test-chain-3MNw2N [remote , listen 10.0.2.15:46656], version: 0.11.0-10f361fc ([wire_version=0.6.2 p2p_version=0.5.0 consensus_version=v1/0.2.2 rpc_version=0.7.0/3 tx_index=on rpc_addr=tcp://0.0.0.0:46657])}" I[10-04|13:54:30.392] Started node module=main nodeInfo="NodeInfo{id: DF22D7C92C91082324A1312F092AA1DA197FA598DBBFB6526E, moniker: anonymous, network: test-chain-3MNw2N [remote , listen 10.0.2.15:46656], version: 0.11.0-10f361fc ([wire_version=0.6.2 p2p_version=0.5.0 consensus_version=v1/0.2.2 rpc_version=0.7.0/3 tx_index=on rpc_addr=tcp://0.0.0.0:46657])}"
Next follows a standard block creation cycle, where we enter a new round, Next follows a standard block creation cycle, where we enter a new round,
propose a block, receive more than 2/3 of prevotes, then precommits and finally propose a block, receive more than 2/3 of prevotes, then precommits and finally

View File

@@ -4,7 +4,7 @@ Install Tendermint
From Binary From Binary
----------- -----------
To download pre-built binaries, see the `Download page <https://tendermint.com/download>`__. To download pre-built binaries, see the `Download page <https://tendermint.com/downloads>`__.
From Source From Source
----------- -----------
@@ -37,13 +37,13 @@ First, install ``dep``:
:: ::
cd $GOPATH/src/github.com/tendermint/tendermint
make get_tools make get_tools
Now we can fetch the correct versions of each dependency by running: Now we can fetch the correct versions of each dependency by running:
:: ::
cd $GOPATH/src/github.com/tendermint/tendermint
make get_vendor_deps make get_vendor_deps
make install make install
@@ -96,6 +96,7 @@ If ``go get`` failing bothers you, fetch the code using ``git``:
mkdir -p $GOPATH/src/github.com/tendermint mkdir -p $GOPATH/src/github.com/tendermint
git clone https://github.com/tendermint/tendermint $GOPATH/src/github.com/tendermint/tendermint git clone https://github.com/tendermint/tendermint $GOPATH/src/github.com/tendermint/tendermint
cd $GOPATH/src/github.com/tendermint/tendermint cd $GOPATH/src/github.com/tendermint/tendermint
make get_tools
make get_vendor_deps make get_vendor_deps
make install make install

View File

@@ -18,8 +18,8 @@ Fields
- ``power``: The validator's voting power. - ``power``: The validator's voting power.
- ``name``: Name of the validator (optional). - ``name``: Name of the validator (optional).
- ``app_hash``: The expected application hash (as returned by the - ``app_hash``: The expected application hash (as returned by the
``Commit`` ABCI message) upon genesis. If the app's hash does not ``ResponseInfo`` ABCI message) upon genesis. If the app's hash does not
match, a warning message is printed. match, Tendermint will panic.
- ``app_state``: The application state (e.g. initial distribution of tokens). - ``app_state``: The application state (e.g. initial distribution of tokens).
Sample genesis.json Sample genesis.json

View File

@@ -83,7 +83,7 @@ The Tendermint Version Handshake allows the peers to exchange their NodeInfo:
```golang ```golang
type NodeInfo struct { type NodeInfo struct {
PubKey crypto.PubKey ID p2p.ID
Moniker string Moniker string
Network string Network string
RemoteAddr string RemoteAddr string
@@ -95,7 +95,7 @@ type NodeInfo struct {
``` ```
The connection is disconnected if: The connection is disconnected if:
- `peer.NodeInfo.PubKey != peer.PubKey` - `peer.NodeInfo.ID` is not equal `peerConn.ID`
- `peer.NodeInfo.Version` is not formatted as `X.X.X` where X are integers known as Major, Minor, and Revision - `peer.NodeInfo.Version` is not formatted as `X.X.X` where X are integers known as Major, Minor, and Revision
- `peer.NodeInfo.Version` Major is not the same as ours - `peer.NodeInfo.Version` Major is not the same as ours
- `peer.NodeInfo.Version` Minor is not the same as ours - `peer.NodeInfo.Version` Minor is not the same as ours

View File

@@ -62,6 +62,13 @@ such as the Web-of-Trust or Certificate Authorities. In our case, we can
use the blockchain itself as a certificate authority to ensure that we use the blockchain itself as a certificate authority to ensure that we
are connected to at least one validator. are connected to at least one validator.
Config
------
Authenticated encryption is enabled by default. If you wish to use another
authentication scheme or your peers are connected via VPN, you can turn it off
by setting ``auth_enc`` to ``false`` in the config file.
Additional Reading Additional Reading
------------------ ------------------

View File

@@ -74,20 +74,17 @@ RPC server, for example:
curl http://localhost:46657/broadcast_tx_commit?tx=\"abcd\" curl http://localhost:46657/broadcast_tx_commit?tx=\"abcd\"
For handling responses, we recommend you `install the jsonpp
tool <http://jmhodges.github.io/jsonpp/>`__ to pretty print the JSON.
We can see the chain's status at the ``/status`` end-point: We can see the chain's status at the ``/status`` end-point:
:: ::
curl http://localhost:46657/status | jsonpp curl http://localhost:46657/status | json_pp
and the ``latest_app_hash`` in particular: and the ``latest_app_hash`` in particular:
:: ::
curl http://localhost:46657/status | jsonpp | grep app_hash curl http://localhost:46657/status | json_pp | grep latest_app_hash
Visit http://localhost:46657 in your browser to see the list of other Visit http://localhost:46657 in your browser to see the list of other
endpoints. Some take no arguments (like ``/status``), while others endpoints. Some take no arguments (like ``/status``), while others
@@ -185,7 +182,7 @@ once per second, it is possible to disable empty blocks or set a block creation
interval. In the former case, blocks will be created when there are new interval. In the former case, blocks will be created when there are new
transactions or when the AppHash changes. transactions or when the AppHash changes.
To configure Tendermint to not produce empty blocks unless there are To configure Tendermint to not produce empty blocks unless there are
transactions or the app hash changes, run Tendermint with this additional flag: transactions or the app hash changes, run Tendermint with this additional flag:
:: ::
@@ -260,19 +257,19 @@ When ``tendermint init`` is run, both a ``genesis.json`` and
:: ::
{ {
"app_hash": "", "validators" : [
"chain_id": "test-chain-HZw6TB", {
"genesis_time": "0001-01-01T00:00:00.000Z", "pub_key" : {
"validators": [ "value" : "h3hk+QE8c6QLTySp8TcfzclJw/BG79ziGB/pIA+DfPE=",
{ "type" : "AC26791624DE60"
"power": 10, },
"name": "", "power" : 10,
"pub_key": [ "name" : ""
1, }
"5770B4DD55B3E08B7F5711C48B516347D8C33F47C30C226315D21AA64E0DFF2E" ],
] "app_hash" : "",
} "chain_id" : "test-chain-rDlYSN",
] "genesis_time" : "0001-01-01T00:00:00Z"
} }
And the ``priv_validator.json``: And the ``priv_validator.json``:
@@ -280,20 +277,18 @@ And the ``priv_validator.json``:
:: ::
{ {
"address": "4F4D895F882A18E1D1FC608D102601DA8D3570E5", "last_step" : 0,
"last_height": 0, "last_round" : 0,
"last_round": 0, "address" : "B788DEDE4F50AD8BC9462DE76741CCAFF87D51E2",
"last_signature": null, "pub_key" : {
"last_signbytes": "", "value" : "h3hk+QE8c6QLTySp8TcfzclJw/BG79ziGB/pIA+DfPE=",
"last_step": 0, "type" : "AC26791624DE60"
"priv_key": [ },
1, "last_height" : 0,
"F9FA3CD435BDAE54D0BCA8F1BC289D718C23D855C6DB21E8543F5E4F457E62805770B4DD55B3E08B7F5711C48B516347D8C33F47C30C226315D21AA64E0DFF2E" "priv_key" : {
], "value" : "JPivl82x+LfVkp8i3ztoTjY6c6GJ4pBxQexErOCyhwqHeGT5ATxzpAtPJKnxNx/NyUnD8Ebv3OIYH+kgD4N88Q==",
"pub_key": [ "type" : "954568A3288910"
1, }
"5770B4DD55B3E08B7F5711C48B516347D8C33F47C30C226315D21AA64E0DFF2E"
]
} }
The ``priv_validator.json`` actually contains a private key, and should The ``priv_validator.json`` actually contains a private key, and should
@@ -334,14 +329,14 @@ For instance,
:: ::
tendermint node --p2p.seeds "1.2.3.4:46656,5.6.7.8:46656" tendermint node --p2p.seeds "f9baeaa15fedf5e1ef7448dd60f46c01f1a9e9c4@1.2.3.4:46656,0491d373a8e0fcf1023aaf18c51d6a1d0d4f31bd@5.6.7.8:46656"
Alternatively, you can use the ``/dial_seeds`` endpoint of the RPC to Alternatively, you can use the ``/dial_seeds`` endpoint of the RPC to
specify seeds for a running node to connect to: specify seeds for a running node to connect to:
:: ::
curl 'localhost:46657/dial_seeds?seeds=\["1.2.3.4:46656","5.6.7.8:46656"\]' curl 'localhost:46657/dial_seeds?seeds=\["f9baeaa15fedf5e1ef7448dd60f46c01f1a9e9c4@1.2.3.4:46656","0491d373a8e0fcf1023aaf18c51d6a1d0d4f31bd@5.6.7.8:46656"\]'
Note, if the peer-exchange protocol (PEX) is enabled (default), you should not Note, if the peer-exchange protocol (PEX) is enabled (default), you should not
normally need seeds after the first start. Peers will be gossipping about known normally need seeds after the first start. Peers will be gossipping about known
@@ -355,8 +350,8 @@ core instance.
:: ::
tendermint node --p2p.persistent_peers "10.11.12.13:46656,10.11.12.14:46656" tendermint node --p2p.persistent_peers "429fcf25974313b95673f58d77eacdd434402665@10.11.12.13:46656,96663a3dd0d7b9d17d4c8211b191af259621c693@10.11.12.14:46656"
curl 'localhost:46657/dial_peers?persistent=true&peers=\["1.2.3.4:46656","5.6.7.8:46656"\]' curl 'localhost:46657/dial_peers?persistent=true&peers=\["429fcf25974313b95673f58d77eacdd434402665@10.11.12.13:46656","96663a3dd0d7b9d17d4c8211b191af259621c693@10.11.12.14:46656"\]'
Adding a Non-Validator Adding a Non-Validator
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
@@ -387,20 +382,18 @@ Now we can update our genesis file. For instance, if the new
:: ::
{ {
"address": "AC379688105901436A34A65F185C115B8BB277A1", "address" : "5AF49D2A2D4F5AD4C7C8C4CC2FB020131E9C4902",
"last_height": 0, "pub_key" : {
"last_round": 0, "value" : "l9X9+fjkeBzDfPGbUM7AMIRE6uJN78zN5+lk5OYotek=",
"last_signature": null, "type" : "AC26791624DE60"
"last_signbytes": "", },
"last_step": 0, "priv_key" : {
"priv_key": [ "value" : "EDJY9W6zlAw+su6ITgTKg2nTZcHAH1NMTW5iwlgmNDuX1f35+OR4HMN88ZtQzsAwhETq4k3vzM3n6WTk5ii16Q==",
1, "type" : "954568A3288910"
"0D2ED337D748ADF79BE28559B9E59EBE1ABBA0BAFE6D65FCB9797985329B950C8F2B5AACAACC9FCE41881349743B0CFDE190DF0177744568D4E82A18F0B7DF94" },
], "last_step" : 0,
"pub_key": [ "last_round" : 0,
1, "last_height" : 0
"8F2B5AACAACC9FCE41881349743B0CFDE190DF0177744568D4E82A18F0B7DF94"
]
} }
then the new ``genesis.json`` will be: then the new ``genesis.json`` will be:
@@ -408,27 +401,27 @@ then the new ``genesis.json`` will be:
:: ::
{ {
"app_hash": "", "validators" : [
"chain_id": "test-chain-HZw6TB", {
"genesis_time": "0001-01-01T00:00:00.000Z", "pub_key" : {
"validators": [ "value" : "h3hk+QE8c6QLTySp8TcfzclJw/BG79ziGB/pIA+DfPE=",
{ "type" : "AC26791624DE60"
"power": 10, },
"name": "", "power" : 10,
"pub_key": [ "name" : ""
1, },
"5770B4DD55B3E08B7F5711C48B516347D8C33F47C30C226315D21AA64E0DFF2E" {
] "pub_key" : {
}, "value" : "l9X9+fjkeBzDfPGbUM7AMIRE6uJN78zN5+lk5OYotek=",
{ "type" : "AC26791624DE60"
"power": 10, },
"name": "", "power" : 10,
"pub_key": [ "name" : ""
1, }
"8F2B5AACAACC9FCE41881349743B0CFDE190DF0177744568D4E82A18F0B7DF94" ],
] "app_hash" : "",
} "chain_id" : "test-chain-rDlYSN",
] "genesis_time" : "0001-01-01T00:00:00Z"
} }
Update the ``genesis.json`` in ``~/.tendermint/config``. Copy the genesis file Update the ``genesis.json`` in ``~/.tendermint/config``. Copy the genesis file

View File

@@ -5,7 +5,7 @@ import (
"reflect" "reflect"
"time" "time"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/tmlibs/log" "github.com/tendermint/tmlibs/log"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"

View File

@@ -1,7 +1,7 @@
package evidence package evidence
import ( import (
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
) )

View File

@@ -93,7 +93,7 @@ func (p *provider) GetLatestCommit() (*ctypes.ResultCommit, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return p.node.Commit(&status.LatestBlockHeight) return p.node.Commit(&status.SyncInfo.LatestBlockHeight)
} }
// CommitFromResult ... // CommitFromResult ...

View File

@@ -1,7 +1,7 @@
package files package files
import ( import (
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
) )

View File

@@ -3,7 +3,7 @@ package proxy
import ( import (
"net/http" "net/http"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/tmlibs/log" "github.com/tendermint/tmlibs/log"
rpcclient "github.com/tendermint/tendermint/rpc/client" rpcclient "github.com/tendermint/tendermint/rpc/client"

View File

@@ -6,7 +6,7 @@ import (
"time" "time"
abci "github.com/tendermint/abci/types" abci "github.com/tendermint/abci/types"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/tmlibs/clist" "github.com/tendermint/tmlibs/clist"
"github.com/tendermint/tmlibs/log" "github.com/tendermint/tmlibs/log"

View File

@@ -1,8 +1,6 @@
package mempool package mempool
import ( import amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-amino"
)
var cdc = amino.NewCodec() var cdc = amino.NewCodec()

View File

@@ -405,7 +405,7 @@ func (n *Node) OnStart() error {
} }
n.Logger.Info("P2P Node ID", "ID", nodeKey.ID(), "file", n.config.NodeKeyFile()) n.Logger.Info("P2P Node ID", "ID", nodeKey.ID(), "file", n.config.NodeKeyFile())
nodeInfo := n.makeNodeInfo(nodeKey.PubKey()) nodeInfo := n.makeNodeInfo(nodeKey.ID())
n.sw.SetNodeInfo(nodeInfo) n.sw.SetNodeInfo(nodeInfo)
n.sw.SetNodeKey(nodeKey) n.sw.SetNodeKey(nodeKey)
@@ -579,13 +579,13 @@ func (n *Node) ProxyApp() proxy.AppConns {
return n.proxyApp return n.proxyApp
} }
func (n *Node) makeNodeInfo(pubKey crypto.PubKey) p2p.NodeInfo { func (n *Node) makeNodeInfo(nodeID p2p.ID) p2p.NodeInfo {
txIndexerStatus := "on" txIndexerStatus := "on"
if _, ok := n.txIndexer.(*null.TxIndex); ok { if _, ok := n.txIndexer.(*null.TxIndex); ok {
txIndexerStatus = "off" txIndexerStatus = "off"
} }
nodeInfo := p2p.NodeInfo{ nodeInfo := p2p.NodeInfo{
PubKey: pubKey, ID: nodeID,
Network: n.genesisDoc.ChainID, Network: n.genesisDoc.ChainID,
Version: version.Version, Version: version.Version,
Channels: []byte{ Channels: []byte{

View File

@@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/tmlibs/log" "github.com/tendermint/tmlibs/log"
) )

View File

@@ -1,7 +1,7 @@
package conn package conn
import ( import (
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
) )

View File

@@ -1,10 +1,11 @@
package p2p package p2p
import ( import (
"math/rand"
"net" "net"
"sync" "sync"
"time" "time"
cmn "github.com/tendermint/tmlibs/common"
) )
const ( const (
@@ -124,7 +125,7 @@ func (fc *FuzzedConnection) SetWriteDeadline(t time.Time) error {
func (fc *FuzzedConnection) randomDuration() time.Duration { func (fc *FuzzedConnection) randomDuration() time.Duration {
maxDelayMillis := int(fc.config.MaxDelay.Nanoseconds() / 1000) maxDelayMillis := int(fc.config.MaxDelay.Nanoseconds() / 1000)
return time.Millisecond * time.Duration(rand.Int()%maxDelayMillis) // nolint: gas return time.Millisecond * time.Duration(cmn.RandInt()%maxDelayMillis) // nolint: gas
} }
// implements the fuzz (delay, kill conn) // implements the fuzz (delay, kill conn)
@@ -137,7 +138,7 @@ func (fc *FuzzedConnection) fuzz() bool {
switch fc.config.Mode { switch fc.config.Mode {
case FuzzModeDrop: case FuzzModeDrop:
// randomly drop the r/w, drop the conn, or sleep // randomly drop the r/w, drop the conn, or sleep
r := rand.Float64() r := cmn.RandFloat64()
if r <= fc.config.ProbDropRW { if r <= fc.config.ProbDropRW {
return true return true
} else if r < fc.config.ProbDropRW+fc.config.ProbDropConn { } else if r < fc.config.ProbDropRW+fc.config.ProbDropConn {

View File

@@ -47,7 +47,7 @@ func PubKeyToID(pubKey crypto.PubKey) ID {
// If the file does not exist, it generates and saves a new NodeKey. // If the file does not exist, it generates and saves a new NodeKey.
func LoadOrGenNodeKey(filePath string) (*NodeKey, error) { func LoadOrGenNodeKey(filePath string) (*NodeKey, error) {
if cmn.FileExists(filePath) { if cmn.FileExists(filePath) {
nodeKey, err := loadNodeKey(filePath) nodeKey, err := LoadNodeKey(filePath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -56,7 +56,7 @@ func LoadOrGenNodeKey(filePath string) (*NodeKey, error) {
return genNodeKey(filePath) return genNodeKey(filePath)
} }
func loadNodeKey(filePath string) (*NodeKey, error) { func LoadNodeKey(filePath string) (*NodeKey, error) {
jsonBytes, err := ioutil.ReadFile(filePath) jsonBytes, err := ioutil.ReadFile(filePath)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -3,8 +3,6 @@ package p2p
import ( import (
"fmt" "fmt"
"strings" "strings"
crypto "github.com/tendermint/go-crypto"
) )
const ( const (
@@ -20,8 +18,8 @@ func MaxNodeInfoSize() int {
// between two peers during the Tendermint P2P handshake. // between two peers during the Tendermint P2P handshake.
type NodeInfo struct { type NodeInfo struct {
// Authenticate // Authenticate
PubKey crypto.PubKey `json:"pub_key"` // authenticated pubkey ID ID `json:"id"` // authenticated identifier
ListenAddr string `json:"listen_addr"` // accepting incoming ListenAddr string `json:"listen_addr"` // accepting incoming
// Check compatibility // Check compatibility
Network string `json:"network"` // network/chain ID Network string `json:"network"` // network/chain ID
@@ -107,19 +105,12 @@ OUTER_LOOP:
return nil return nil
} }
// ID returns node's ID.
func (info NodeInfo) ID() ID {
return PubKeyToID(info.PubKey)
}
// NetAddress returns a NetAddress derived from the NodeInfo - // NetAddress returns a NetAddress derived from the NodeInfo -
// it includes the authenticated peer ID and the self-reported // it includes the authenticated peer ID and the self-reported
// ListenAddr. Note that the ListenAddr is not authenticated and // ListenAddr. Note that the ListenAddr is not authenticated and
// may not match that address actually dialed if its an outbound peer. // may not match that address actually dialed if its an outbound peer.
func (info NodeInfo) NetAddress() *NetAddress { func (info NodeInfo) NetAddress() *NetAddress {
id := PubKeyToID(info.PubKey) netAddr, err := NewNetAddressString(IDAddressString(info.ID, info.ListenAddr))
addr := info.ListenAddr
netAddr, err := NewNetAddressString(IDAddressString(id, addr))
if err != nil { if err != nil {
panic(err) // everything should be well formed by now panic(err) // everything should be well formed by now
} }
@@ -127,7 +118,8 @@ func (info NodeInfo) NetAddress() *NetAddress {
} }
func (info NodeInfo) String() string { func (info NodeInfo) String() string {
return fmt.Sprintf("NodeInfo{pk: %v, moniker: %v, network: %v [listen %v], version: %v (%v)}", info.PubKey, info.Moniker, info.Network, info.ListenAddr, info.Version, info.Other) return fmt.Sprintf("NodeInfo{id: %v, moniker: %v, network: %v [listen %v], version: %v (%v)}",
info.ID, info.Moniker, info.Network, info.ListenAddr, info.Version, info.Other)
} }
func splitVersion(version string) (string, string, string, error) { func splitVersion(version string) (string, string, string, error) {

View File

@@ -202,7 +202,7 @@ func (p *peer) OnStop() {
// ID returns the peer's ID - the hex encoded hash of its pubkey. // ID returns the peer's ID - the hex encoded hash of its pubkey.
func (p *peer) ID() ID { func (p *peer) ID() ID {
return p.nodeInfo.ID() return p.nodeInfo.ID
} }
// IsOutbound returns true if the connection is outbound, false otherwise. // IsOutbound returns true if the connection is outbound, false otherwise.

View File

@@ -13,11 +13,11 @@ import (
// Returns an empty kvstore peer // Returns an empty kvstore peer
func randPeer() *peer { func randPeer() *peer {
pubKey := crypto.GenPrivKeyEd25519().PubKey() nodeKey := NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
return &peer{ return &peer{
nodeInfo: NodeInfo{ nodeInfo: NodeInfo{
ID: nodeKey.ID(),
ListenAddr: cmn.Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256), ListenAddr: cmn.Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256),
PubKey: pubKey,
}, },
} }
} }

View File

@@ -95,7 +95,7 @@ func createOutboundPeerAndPerformHandshake(addr *NetAddress, config *PeerConfig)
return nil, err return nil, err
} }
nodeInfo, err := pc.HandshakeTimeout(NodeInfo{ nodeInfo, err := pc.HandshakeTimeout(NodeInfo{
PubKey: pk.PubKey(), ID: addr.ID,
Moniker: "host_peer", Moniker: "host_peer",
Network: "testing", Network: "testing",
Version: "123.123.123", Version: "123.123.123",
@@ -152,7 +152,7 @@ func (p *remotePeer) accept(l net.Listener) {
golog.Fatalf("Failed to create a peer: %+v", err) golog.Fatalf("Failed to create a peer: %+v", err)
} }
_, err = pc.HandshakeTimeout(NodeInfo{ _, err = pc.HandshakeTimeout(NodeInfo{
PubKey: p.PrivKey.PubKey(), ID: p.Addr().ID,
Moniker: "remote_peer", Moniker: "remote_peer",
Network: "testing", Network: "testing",
Version: "123.123.123", Version: "123.123.123",

View File

@@ -9,7 +9,6 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"math" "math"
"math/rand"
"net" "net"
"sync" "sync"
"time" "time"
@@ -82,7 +81,7 @@ type addrBook struct {
// accessed concurrently // accessed concurrently
mtx sync.Mutex mtx sync.Mutex
rand *rand.Rand rand *cmn.Rand
ourAddrs map[string]struct{} ourAddrs map[string]struct{}
addrLookup map[p2p.ID]*knownAddress // new & old addrLookup map[p2p.ID]*knownAddress // new & old
bucketsOld []map[string]*knownAddress bucketsOld []map[string]*knownAddress
@@ -97,7 +96,7 @@ type addrBook struct {
// Use Start to begin processing asynchronous address updates. // Use Start to begin processing asynchronous address updates.
func NewAddrBook(filePath string, routabilityStrict bool) *addrBook { func NewAddrBook(filePath string, routabilityStrict bool) *addrBook {
am := &addrBook{ am := &addrBook{
rand: rand.New(rand.NewSource(time.Now().UnixNano())), // TODO: seed from outside rand: cmn.NewRand(),
ourAddrs: make(map[string]struct{}), ourAddrs: make(map[string]struct{}),
addrLookup: make(map[p2p.ID]*knownAddress), addrLookup: make(map[p2p.ID]*knownAddress),
filePath: filePath, filePath: filePath,
@@ -320,7 +319,7 @@ func (a *addrBook) GetSelection() []*p2p.NetAddress {
// XXX: What's the point of this if we already loop randomly through addrLookup ? // XXX: What's the point of this if we already loop randomly through addrLookup ?
for i := 0; i < numAddresses; i++ { for i := 0; i < numAddresses; i++ {
// pick a number between current index and the end // pick a number between current index and the end
j := rand.Intn(len(allAddr)-i) + i j := cmn.RandIntn(len(allAddr)-i) + i
allAddr[i], allAddr[j] = allAddr[j], allAddr[i] allAddr[i], allAddr[j] = allAddr[j], allAddr[i]
} }

View File

@@ -2,13 +2,12 @@ package pex
import ( import (
"fmt" "fmt"
"math/rand"
"reflect" "reflect"
"sort" "sort"
"sync" "sync"
"time" "time"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
@@ -288,7 +287,7 @@ func (r *PEXReactor) SetEnsurePeersPeriod(d time.Duration) {
// Ensures that sufficient peers are connected. (continuous) // Ensures that sufficient peers are connected. (continuous)
func (r *PEXReactor) ensurePeersRoutine() { func (r *PEXReactor) ensurePeersRoutine() {
var ( var (
seed = rand.New(rand.NewSource(time.Now().UnixNano())) seed = cmn.NewRand()
jitter = seed.Int63n(r.ensurePeersPeriod.Nanoseconds()) jitter = seed.Int63n(r.ensurePeersPeriod.Nanoseconds())
) )
@@ -375,7 +374,7 @@ func (r *PEXReactor) ensurePeers() {
peers := r.Switch.Peers().List() peers := r.Switch.Peers().List()
peersCount := len(peers) peersCount := len(peers)
if peersCount > 0 { if peersCount > 0 {
peer := peers[rand.Int()%peersCount] // nolint: gas peer := peers[cmn.RandInt()%peersCount] // nolint: gas
r.Logger.Info("We need more addresses. Sending pexRequest to random peer", "peer", peer) r.Logger.Info("We need more addresses. Sending pexRequest to random peer", "peer", peer)
r.RequestAddrs(peer) r.RequestAddrs(peer)
} }
@@ -404,7 +403,7 @@ func (r *PEXReactor) dialPeer(addr *p2p.NetAddress) {
// exponential backoff if it's not our first attempt to dial given address // exponential backoff if it's not our first attempt to dial given address
if attempts > 0 { if attempts > 0 {
jitterSeconds := time.Duration(rand.Float64() * float64(time.Second)) // 1s == (1e9 ns) jitterSeconds := time.Duration(cmn.RandFloat64() * float64(time.Second)) // 1s == (1e9 ns)
backoffDuration := jitterSeconds + ((1 << uint(attempts)) * time.Second) backoffDuration := jitterSeconds + ((1 << uint(attempts)) * time.Second)
sinceLastDialed := time.Since(lastDialed) sinceLastDialed := time.Since(lastDialed)
if sinceLastDialed < backoffDuration { if sinceLastDialed < backoffDuration {
@@ -457,7 +456,7 @@ func (r *PEXReactor) dialSeeds() {
} }
seedAddrs, _ := p2p.NewNetAddressStrings(r.config.Seeds) seedAddrs, _ := p2p.NewNetAddressStrings(r.config.Seeds)
perm := rand.Perm(lSeeds) perm := cmn.RandPerm(lSeeds)
// perm := r.Switch.rng.Perm(lSeeds) // perm := r.Switch.rng.Perm(lSeeds)
for _, i := range perm { for _, i := range perm {
// dial a random seed // dial a random seed

View File

@@ -289,7 +289,7 @@ func TestPEXReactorCrawlStatus(t *testing.T) {
func TestPEXReactorDoesNotAddPrivatePeersToAddrBook(t *testing.T) { func TestPEXReactorDoesNotAddPrivatePeersToAddrBook(t *testing.T) {
peer := p2p.CreateRandomPeer(false) peer := p2p.CreateRandomPeer(false)
pexR, book := createReactor(&PEXReactorConfig{PrivatePeerIDs: []string{string(peer.NodeInfo().ID())}}) pexR, book := createReactor(&PEXReactorConfig{PrivatePeerIDs: []string{string(peer.NodeInfo().ID)}})
defer teardownReactor(book) defer teardownReactor(book)
// we have to send a request to receive responses // we have to send a request to receive responses
@@ -356,12 +356,12 @@ func newMockPeer() mockPeer {
return mp return mp
} }
func (mp mockPeer) ID() p2p.ID { return p2p.PubKeyToID(mp.pubKey) } func (mp mockPeer) ID() p2p.ID { return mp.addr.ID }
func (mp mockPeer) IsOutbound() bool { return mp.outbound } func (mp mockPeer) IsOutbound() bool { return mp.outbound }
func (mp mockPeer) IsPersistent() bool { return mp.persistent } func (mp mockPeer) IsPersistent() bool { return mp.persistent }
func (mp mockPeer) NodeInfo() p2p.NodeInfo { func (mp mockPeer) NodeInfo() p2p.NodeInfo {
return p2p.NodeInfo{ return p2p.NodeInfo{
PubKey: mp.pubKey, ID: mp.addr.ID,
ListenAddr: mp.addr.DialString(), ListenAddr: mp.addr.DialString(),
} }
} }

View File

@@ -1,8 +1,6 @@
package pex package pex
import ( import amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-amino"
)
var cdc *amino.Codec = amino.NewCodec() var cdc *amino.Codec = amino.NewCodec()

View File

@@ -3,7 +3,6 @@ package p2p
import ( import (
"fmt" "fmt"
"math" "math"
"math/rand"
"net" "net"
"sync" "sync"
"time" "time"
@@ -67,7 +66,7 @@ type Switch struct {
filterConnByAddr func(net.Addr) error filterConnByAddr func(net.Addr) error
filterConnByID func(ID) error filterConnByID func(ID) error
rng *rand.Rand // seed for randomizing dial times and orders rng *cmn.Rand // seed for randomizing dial times and orders
} }
// NewSwitch creates a new Switch with the given config. // NewSwitch creates a new Switch with the given config.
@@ -82,9 +81,8 @@ func NewSwitch(config *cfg.P2PConfig) *Switch {
dialing: cmn.NewCMap(), dialing: cmn.NewCMap(),
} }
// Ensure we have a completely undeterministic PRNG. cmd.RandInt64() draws // Ensure we have a completely undeterministic PRNG.
// from a seed that's initialized with OS entropy on process start. sw.rng = cmn.NewRand()
sw.rng = rand.New(rand.NewSource(cmn.RandInt64()))
// TODO: collapse the peerConfig into the config ? // TODO: collapse the peerConfig into the config ?
sw.peerConfig.MConfig.FlushThrottle = time.Duration(config.FlushThrottleTimeout) * time.Millisecond sw.peerConfig.MConfig.FlushThrottle = time.Duration(config.FlushThrottleTimeout) * time.Millisecond
@@ -361,7 +359,9 @@ func (sw *Switch) DialPeersAsync(addrBook AddrBook, peers []string, persistent b
for _, netAddr := range netAddrs { for _, netAddr := range netAddrs {
// do not add our address or ID // do not add our address or ID
if !netAddr.Same(ourAddr) { if !netAddr.Same(ourAddr) {
addrBook.AddAddress(netAddr, ourAddr) if err := addrBook.AddAddress(netAddr, ourAddr); err != nil {
sw.Logger.Error("Can't add peer's address to addrbook", "err", err)
}
} }
} }
// Persist some peers to disk right away. // Persist some peers to disk right away.
@@ -515,7 +515,7 @@ func (sw *Switch) addPeer(pc peerConn) error {
return err return err
} }
peerID := peerNodeInfo.ID() peerID := peerNodeInfo.ID
// ensure connection key matches self reported key // ensure connection key matches self reported key
if pc.config.AuthEnc { if pc.config.AuthEnc {

View File

@@ -221,14 +221,14 @@ func TestConnIDFilter(t *testing.T) {
c1, c2 := conn.NetPipe() c1, c2 := conn.NetPipe()
s1.SetIDFilter(func(id ID) error { s1.SetIDFilter(func(id ID) error {
if id == PubKeyToID(s2.nodeInfo.PubKey) { if id == s2.nodeInfo.ID {
return fmt.Errorf("Error: pipe is blacklisted") return fmt.Errorf("Error: pipe is blacklisted")
} }
return nil return nil
}) })
s2.SetIDFilter(func(id ID) error { s2.SetIDFilter(func(id ID) error {
if id == PubKeyToID(s1.nodeInfo.PubKey) { if id == s1.nodeInfo.ID {
return fmt.Errorf("Error: pipe is blacklisted") return fmt.Errorf("Error: pipe is blacklisted")
} }
return nil return nil

View File

@@ -1,7 +1,6 @@
package p2p package p2p
import ( import (
"math/rand"
"net" "net"
crypto "github.com/tendermint/go-crypto" crypto "github.com/tendermint/go-crypto"
@@ -23,8 +22,8 @@ func CreateRandomPeer(outbound bool) *peer {
outbound: outbound, outbound: outbound,
}, },
nodeInfo: NodeInfo{ nodeInfo: NodeInfo{
ID: netAddr.ID,
ListenAddr: netAddr.DialString(), ListenAddr: netAddr.DialString(),
PubKey: crypto.GenPrivKeyEd25519().PubKey(),
}, },
mconn: &conn.MConnection{}, mconn: &conn.MConnection{},
} }
@@ -35,7 +34,7 @@ func CreateRandomPeer(outbound bool) *peer {
func CreateRoutableAddr() (addr string, netAddr *NetAddress) { func CreateRoutableAddr() (addr string, netAddr *NetAddress) {
for { for {
var err error var err error
addr = cmn.Fmt("%X@%v.%v.%v.%v:46656", cmn.RandBytes(20), rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256) addr = cmn.Fmt("%X@%v.%v.%v.%v:46656", cmn.RandBytes(20), cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256)
netAddr, err = NewNetAddressString(addr) netAddr, err = NewNetAddressString(addr)
if err != nil { if err != nil {
panic(err) panic(err)
@@ -137,11 +136,11 @@ func MakeSwitch(cfg *cfg.P2PConfig, i int, network, version string, initSwitch f
sw.SetLogger(log.TestingLogger()) sw.SetLogger(log.TestingLogger())
sw = initSwitch(i, sw) sw = initSwitch(i, sw)
ni := NodeInfo{ ni := NodeInfo{
PubKey: nodeKey.PubKey(), ID: nodeKey.ID(),
Moniker: cmn.Fmt("switch%d", i), Moniker: cmn.Fmt("switch%d", i),
Network: network, Network: network,
Version: version, Version: version,
ListenAddr: cmn.Fmt("%v:%v", network, rand.Intn(64512)+1023), ListenAddr: cmn.Fmt("%v:%v", network, cmn.RandIntn(64512)+1023),
} }
for ch := range sw.reactorsByCh { for ch := range sw.reactorsByCh {
ni.Channels = append(ni.Channels, ch) ni.Channels = append(ni.Channels, ch)

View File

@@ -1,7 +1,7 @@
package p2p package p2p
import ( import (
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
) )

View File

@@ -41,7 +41,7 @@ func WaitForHeight(c StatusClient, h int64, waiter Waiter) error {
if err != nil { if err != nil {
return err return err
} }
delta = h - s.LatestBlockHeight delta = h - s.SyncInfo.LatestBlockHeight
// wait for the time, or abort early // wait for the time, or abort early
if err := waiter(delta); err != nil { if err := waiter(delta); err != nil {
return err return err

View File

@@ -32,7 +32,7 @@ func TestWaitForHeight(t *testing.T) {
// now set current block height to 10 // now set current block height to 10
m.Call = mock.Call{ m.Call = mock.Call{
Response: &ctypes.ResultStatus{LatestBlockHeight: 10}, Response: &ctypes.ResultStatus{SyncInfo: ctypes.SyncInfo{LatestBlockHeight: 10}},
} }
// we will not wait for more than 10 blocks // we will not wait for more than 10 blocks
@@ -52,7 +52,7 @@ func TestWaitForHeight(t *testing.T) {
// we use the callback to update the status height // we use the callback to update the status height
myWaiter := func(delta int64) error { myWaiter := func(delta int64) error {
// update the height for the next call // update the height for the next call
m.Call.Response = &ctypes.ResultStatus{LatestBlockHeight: 15} m.Call.Response = &ctypes.ResultStatus{SyncInfo: ctypes.SyncInfo{LatestBlockHeight: 15}}
return client.DefaultWaitStrategy(delta) return client.DefaultWaitStrategy(delta)
} }
@@ -66,11 +66,11 @@ func TestWaitForHeight(t *testing.T) {
require.Nil(pre.Error) require.Nil(pre.Error)
prer, ok := pre.Response.(*ctypes.ResultStatus) prer, ok := pre.Response.(*ctypes.ResultStatus)
require.True(ok) require.True(ok)
assert.Equal(int64(10), prer.LatestBlockHeight) assert.Equal(int64(10), prer.SyncInfo.LatestBlockHeight)
post := r.Calls[4] post := r.Calls[4]
require.Nil(post.Error) require.Nil(post.Error)
postr, ok := post.Response.(*ctypes.ResultStatus) postr, ok := post.Response.(*ctypes.ResultStatus)
require.True(ok) require.True(ok)
assert.Equal(int64(15), postr.LatestBlockHeight) assert.Equal(int64(15), postr.SyncInfo.LatestBlockHeight)
} }

View File

@@ -17,9 +17,11 @@ func TestStatus(t *testing.T) {
m := &mock.StatusMock{ m := &mock.StatusMock{
Call: mock.Call{ Call: mock.Call{
Response: &ctypes.ResultStatus{ Response: &ctypes.ResultStatus{
LatestBlockHash: cmn.HexBytes("block"), SyncInfo: ctypes.SyncInfo{
LatestAppHash: cmn.HexBytes("app"), LatestBlockHash: cmn.HexBytes("block"),
LatestBlockHeight: 10, LatestAppHash: cmn.HexBytes("app"),
LatestBlockHeight: 10,
},
}}, }},
} }
@@ -29,8 +31,8 @@ func TestStatus(t *testing.T) {
// make sure response works proper // make sure response works proper
status, err := r.Status() status, err := r.Status()
require.Nil(err, "%+v", err) require.Nil(err, "%+v", err)
assert.EqualValues("block", status.LatestBlockHash) assert.EqualValues("block", status.SyncInfo.LatestBlockHash)
assert.EqualValues(10, status.LatestBlockHeight) assert.EqualValues(10, status.SyncInfo.LatestBlockHeight)
// make sure recorder works properly // make sure recorder works properly
require.Equal(1, len(r.Calls)) require.Equal(1, len(r.Calls))
@@ -41,6 +43,6 @@ func TestStatus(t *testing.T) {
require.NotNil(rs.Response) require.NotNil(rs.Response)
st, ok := rs.Response.(*ctypes.ResultStatus) st, ok := rs.Response.(*ctypes.ResultStatus)
require.True(ok) require.True(ok)
assert.EqualValues("block", st.LatestBlockHash) assert.EqualValues("block", st.SyncInfo.LatestBlockHash)
assert.EqualValues(10, st.LatestBlockHeight) assert.EqualValues(10, st.SyncInfo.LatestBlockHeight)
} }

View File

@@ -50,7 +50,7 @@ func TestInfo(t *testing.T) {
info, err := c.ABCIInfo() info, err := c.ABCIInfo()
require.Nil(t, err, "%d: %+v", i, err) require.Nil(t, err, "%d: %+v", i, err)
// TODO: this is not correct - fix merkleeyes! // TODO: this is not correct - fix merkleeyes!
// assert.EqualValues(t, status.LatestBlockHeight, info.Response.LastBlockHeight) // assert.EqualValues(t, status.SyncInfo.LatestBlockHeight, info.Response.LastBlockHeight)
assert.True(t, strings.Contains(info.Response.Data, "size")) assert.True(t, strings.Contains(info.Response.Data, "size"))
} }
} }
@@ -136,7 +136,7 @@ func TestAppCalls(t *testing.T) {
s, err := c.Status() s, err := c.Status()
require.Nil(err, "%d: %+v", i, err) require.Nil(err, "%d: %+v", i, err)
// sh is start height or status height // sh is start height or status height
sh := s.LatestBlockHeight sh := s.SyncInfo.LatestBlockHeight
// look for the future // look for the future
h := sh + 2 h := sh + 2

View File

@@ -1,8 +1,9 @@
package core package core
import ( import (
"encoding/json"
cm "github.com/tendermint/tendermint/consensus" cm "github.com/tendermint/tendermint/consensus"
cstypes "github.com/tendermint/tendermint/consensus/types"
p2p "github.com/tendermint/tendermint/p2p" p2p "github.com/tendermint/tendermint/p2p"
ctypes "github.com/tendermint/tendermint/rpc/core/types" ctypes "github.com/tendermint/tendermint/rpc/core/types"
sm "github.com/tendermint/tendermint/state" sm "github.com/tendermint/tendermint/state"
@@ -58,7 +59,7 @@ func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
return &ctypes.ResultValidators{height, validators.Validators}, nil return &ctypes.ResultValidators{height, validators.Validators}, nil
} }
// Dump consensus state. // DumpConsensusState dumps consensus state.
// //
// ```shell // ```shell
// curl 'localhost:46657/dump_consensus_state' // curl 'localhost:46657/dump_consensus_state'
@@ -83,11 +84,18 @@ func Validators(heightPtr *int64) (*ctypes.ResultValidators, error) {
// } // }
// ``` // ```
func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
peerRoundStates := make(map[p2p.ID]*cstypes.PeerRoundState) peerRoundStates := make(map[p2p.ID]json.RawMessage)
for _, peer := range p2pSwitch.Peers().List() { for _, peer := range p2pSwitch.Peers().List() {
peerState := peer.Get(types.PeerStateKey).(*cm.PeerState) peerState := peer.Get(types.PeerStateKey).(*cm.PeerState)
peerRoundState := peerState.GetRoundState() peerRoundState, err := peerState.GetRoundStateJSON()
if err != nil {
return nil, err
}
peerRoundStates[peer.ID()] = peerRoundState peerRoundStates[peer.ID()] = peerRoundState
} }
return &ctypes.ResultDumpConsensusState{consensusState.GetRoundState(), peerRoundStates}, nil roundState, err := consensusState.GetRoundStateJSON()
if err != nil {
return nil, err
}
return &ctypes.ResultDumpConsensusState{roundState, peerRoundStates}, nil
} }

View File

@@ -43,7 +43,6 @@ func NetInfo() (*ctypes.ResultNetInfo, error) {
for _, peer := range p2pSwitch.Peers().List() { for _, peer := range p2pSwitch.Peers().List() {
peers = append(peers, ctypes.Peer{ peers = append(peers, ctypes.Peer{
NodeInfo: peer.NodeInfo(), NodeInfo: peer.NodeInfo(),
ID: peer.ID(),
IsOutbound: peer.IsOutbound(), IsOutbound: peer.IsOutbound(),
ConnectionStatus: peer.Status(), ConnectionStatus: peer.Status(),
}) })

View File

@@ -3,9 +3,8 @@ package core
import ( import (
"time" "time"
"github.com/tendermint/go-crypto" crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/tendermint/consensus" "github.com/tendermint/tendermint/consensus"
cstypes "github.com/tendermint/tendermint/consensus/types"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state" sm "github.com/tendermint/tendermint/state"
@@ -23,7 +22,7 @@ var subscribeTimeout = 5 * time.Second
type Consensus interface { type Consensus interface {
GetState() sm.State GetState() sm.State
GetValidators() (int64, []*types.Validator) GetValidators() (int64, []*types.Validator)
GetRoundState() *cstypes.RoundState GetRoundStateJSON() ([]byte, error)
} }
type P2P interface { type P2P interface {

View File

@@ -27,15 +27,20 @@ import (
// ```json // ```json
// { // {
// "result": { // "result": {
// "syncing": false, // "sync_info": {
// "latest_block_time": "2017-12-07T18:19:47.617Z", // "syncing": false,
// "latest_block_height": 6, // "latest_block_time": "2017-12-07T18:19:47.617Z",
// "latest_app_hash": "", // "latest_block_height": 6,
// "latest_block_hash": "A63D0C3307DEDCCFCC82ED411AE9108B70B29E02", // "latest_app_hash": "",
// "pub_key": { // "latest_block_hash": "A63D0C3307DEDCCFCC82ED411AE9108B70B29E02",
// "data": "8C9A68070CBE33F9C445862BA1E9D96A75CEB68C0CF6ADD3652D07DCAC5D0380", // }
// "type": "ed25519" // "validator_info": {
// }, // "pub_key": {
// "data": "8C9A68070CBE33F9C445862BA1E9D96A75CEB68C0CF6ADD3652D07DCAC5D0380",
// "type": "ed25519"
// },
// "voting_power": 10
// }
// "node_info": { // "node_info": {
// "other": [ // "other": [
// "wire_version=0.7.2", // "wire_version=0.7.2",
@@ -51,9 +56,6 @@ import (
// "network": "test-chain-qhVCa2", // "network": "test-chain-qhVCa2",
// "moniker": "vagrant-ubuntu-trusty-64", // "moniker": "vagrant-ubuntu-trusty-64",
// "pub_key": "844981FE99ABB19F7816F2D5E94E8A74276AB1153760A7799E925C75401856C6", // "pub_key": "844981FE99ABB19F7816F2D5E94E8A74276AB1153760A7799E925C75401856C6",
// "validator_status": {
// "voting_power": 10
// }
// } // }
// }, // },
// "id": "", // "id": "",
@@ -78,20 +80,20 @@ func Status() (*ctypes.ResultStatus, error) {
latestBlockTime := time.Unix(0, latestBlockTimeNano) latestBlockTime := time.Unix(0, latestBlockTimeNano)
result := &ctypes.ResultStatus{ result := &ctypes.ResultStatus{
NodeInfo: p2pSwitch.NodeInfo(), NodeInfo: p2pSwitch.NodeInfo(),
PubKey: pubKey, SyncInfo: ctypes.SyncInfo{
LatestBlockHash: latestBlockHash, LatestBlockHash: latestBlockHash,
LatestAppHash: latestAppHash, LatestAppHash: latestAppHash,
LatestBlockHeight: latestHeight, LatestBlockHeight: latestHeight,
LatestBlockTime: latestBlockTime, LatestBlockTime: latestBlockTime,
Syncing: consensusReactor.FastSync(), Syncing: consensusReactor.FastSync(),
},
ValidatorInfo: ctypes.ValidatorInfo{PubKey: pubKey},
} }
// add ValidatorStatus if node is a validator // add ValidatorStatus if node is a validator
if val := validatorAtHeight(latestHeight); val != nil { if val := validatorAtHeight(latestHeight); val != nil {
result.ValidatorStatus = ctypes.ValidatorStatus{ result.ValidatorInfo.VotingPower = val.VotingPower
VotingPower: val.VotingPower,
}
} }
return result, nil return result, nil

View File

@@ -1,6 +1,7 @@
package core_types package core_types
import ( import (
"encoding/json"
"strings" "strings"
"time" "time"
@@ -8,7 +9,6 @@ import (
crypto "github.com/tendermint/go-crypto" crypto "github.com/tendermint/go-crypto"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
cstypes "github.com/tendermint/tendermint/consensus/types"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
@@ -54,19 +54,23 @@ func NewResultCommit(header *types.Header, commit *types.Commit,
} }
} }
type ValidatorStatus struct { type SyncInfo struct {
VotingPower int64 `json:"voting_power"` LatestBlockHash cmn.HexBytes `json:"latest_block_hash"`
LatestAppHash cmn.HexBytes `json:"latest_app_hash"`
LatestBlockHeight int64 `json:"latest_block_height"`
LatestBlockTime time.Time `json:"latest_block_time"`
Syncing bool `json:"syncing"`
}
type ValidatorInfo struct {
PubKey crypto.PubKey `json:"pub_key"`
VotingPower int64 `json:"voting_power"`
} }
type ResultStatus struct { type ResultStatus struct {
NodeInfo p2p.NodeInfo `json:"node_info"` NodeInfo p2p.NodeInfo `json:"node_info"`
PubKey crypto.PubKey `json:"pub_key"` SyncInfo SyncInfo `json:"sync_info"`
LatestBlockHash cmn.HexBytes `json:"latest_block_hash"` ValidatorInfo ValidatorInfo `json:"validator_info"`
LatestAppHash cmn.HexBytes `json:"latest_app_hash"`
LatestBlockHeight int64 `json:"latest_block_height"`
LatestBlockTime time.Time `json:"latest_block_time"`
Syncing bool `json:"syncing"`
ValidatorStatus ValidatorStatus `json:"validator_status,omitempty"`
} }
func (s *ResultStatus) TxIndexEnabled() bool { func (s *ResultStatus) TxIndexEnabled() bool {
@@ -98,7 +102,6 @@ type ResultDialPeers struct {
type Peer struct { type Peer struct {
p2p.NodeInfo `json:"node_info"` p2p.NodeInfo `json:"node_info"`
p2p.ID `json:"node_id"`
IsOutbound bool `json:"is_outbound"` IsOutbound bool `json:"is_outbound"`
ConnectionStatus p2p.ConnectionStatus `json:"connection_status"` ConnectionStatus p2p.ConnectionStatus `json:"connection_status"`
} }
@@ -109,8 +112,8 @@ type ResultValidators struct {
} }
type ResultDumpConsensusState struct { type ResultDumpConsensusState struct {
RoundState *cstypes.RoundState `json:"round_state"` RoundState json.RawMessage `json:"round_state"`
PeerRoundStates map[p2p.ID]*cstypes.PeerRoundState `json:"peer_round_states"` PeerRoundStates map[p2p.ID]json.RawMessage `json:"peer_round_states"`
} }
type ResultBroadcastTx struct { type ResultBroadcastTx struct {

View File

@@ -1,7 +1,7 @@
package core_types package core_types
import ( import (
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
) )

View File

@@ -5,8 +5,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-amino"
) )
type Tx []byte type Tx []byte

View File

@@ -12,8 +12,8 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tendermint/go-amino"
amino "github.com/tendermint/go-amino"
types "github.com/tendermint/tendermint/rpc/lib/types" types "github.com/tendermint/tendermint/rpc/lib/types"
) )

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand"
"net" "net"
"net/http" "net/http"
"sync" "sync"
@@ -14,7 +13,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
metrics "github.com/rcrowley/go-metrics" metrics "github.com/rcrowley/go-metrics"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
types "github.com/tendermint/tendermint/rpc/lib/types" types "github.com/tendermint/tendermint/rpc/lib/types"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
) )
@@ -266,7 +265,7 @@ func (c *WSClient) reconnect() error {
}() }()
for { for {
jitterSeconds := time.Duration(rand.Float64() * float64(time.Second)) // 1s == (1e9 ns) jitterSeconds := time.Duration(cmn.RandFloat64() * float64(time.Second)) // 1s == (1e9 ns)
backoffDuration := jitterSeconds + ((1 << uint(attempt)) * time.Second) backoffDuration := jitterSeconds + ((1 << uint(attempt)) * time.Second)
c.Logger.Info("reconnecting", "attempt", attempt+1, "backoff_duration", backoffDuration) c.Logger.Info("reconnecting", "attempt", attempt+1, "backoff_duration", backoffDuration)

View File

@@ -17,7 +17,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tmlibs/log" "github.com/tendermint/tmlibs/log"

View File

@@ -17,7 +17,7 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
types "github.com/tendermint/tendermint/rpc/lib/types" types "github.com/tendermint/tendermint/rpc/lib/types"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tmlibs/log" "github.com/tendermint/tmlibs/log"

View File

@@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
rs "github.com/tendermint/tendermint/rpc/lib/server" rs "github.com/tendermint/tendermint/rpc/lib/server"
types "github.com/tendermint/tendermint/rpc/lib/types" types "github.com/tendermint/tendermint/rpc/lib/types"
"github.com/tendermint/tmlibs/log" "github.com/tendermint/tmlibs/log"

View File

@@ -6,7 +6,7 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
) )

View File

@@ -5,7 +5,7 @@ import (
"net/http" "net/http"
"os" "os"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
rpcserver "github.com/tendermint/tendermint/rpc/lib/server" rpcserver "github.com/tendermint/tendermint/rpc/lib/server"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tmlibs/log" "github.com/tendermint/tmlibs/log"

View File

@@ -7,7 +7,7 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
tmpubsub "github.com/tendermint/tmlibs/pubsub" tmpubsub "github.com/tendermint/tmlibs/pubsub"
) )

View File

@@ -8,7 +8,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
) )
type SampleResult struct { type SampleResult struct {

View File

@@ -8,7 +8,7 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
crypto "github.com/tendermint/go-crypto" crypto "github.com/tendermint/go-crypto"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"

View File

@@ -1,8 +1,6 @@
package kv package kv
import ( import amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-amino"
)
var cdc = amino.NewCodec() var cdc = amino.NewCodec()

View File

@@ -1,7 +1,7 @@
package state package state
import ( import (
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
) )

View File

@@ -17,7 +17,7 @@ for i in $(seq 1 "$N"); do
addr=$(test/p2p/ip.sh "$i"):46657 addr=$(test/p2p/ip.sh "$i"):46657
# current state # current state
HASH1=$(curl -s "$addr/status" | jq .result.latest_app_hash) HASH1=$(curl -s "$addr/status" | jq .result.sync_info.latest_app_hash)
# - send a tx # - send a tx
TX=aadeadbeefbeefbeef0$i TX=aadeadbeefbeefbeef0$i
@@ -26,11 +26,11 @@ for i in $(seq 1 "$N"); do
echo "" echo ""
# we need to wait another block to get the new app_hash # we need to wait another block to get the new app_hash
h1=$(curl -s "$addr/status" | jq .result.latest_block_height) h1=$(curl -s "$addr/status" | jq .result.sync_info.latest_block_height)
h2=$h1 h2=$h1
while [ "$h2" == "$h1" ]; do while [ "$h2" == "$h1" ]; do
sleep 1 sleep 1
h2=$(curl -s "$addr/status" | jq .result.latest_block_height) h2=$(curl -s "$addr/status" | jq .result.sync_info.latest_block_height)
done done
# wait for all other peers to get to this height # wait for all other peers to get to this height
@@ -39,16 +39,16 @@ for i in $(seq 1 "$N"); do
if [[ "$i" != "$j" ]]; then if [[ "$i" != "$j" ]]; then
addrJ=$(test/p2p/ip.sh "$j"):46657 addrJ=$(test/p2p/ip.sh "$j"):46657
h=$(curl -s "$addrJ/status" | jq .result.latest_block_height) h=$(curl -s "$addrJ/status" | jq .result.sync_info.latest_block_height)
while [ "$h" -lt "$minHeight" ]; do while [ "$h" -lt "$minHeight" ]; do
sleep 1 sleep 1
h=$(curl -s "$addrJ/status" | jq .result.latest_block_height) h=$(curl -s "$addrJ/status" | jq .result.sync_info.latest_block_height)
done done
fi fi
done done
# check that hash was updated # check that hash was updated
HASH2=$(curl -s "$addr/status" | jq .result.latest_app_hash) HASH2=$(curl -s "$addr/status" | jq .result.sync_info.latest_app_hash)
if [[ "$HASH1" == "$HASH2" ]]; then if [[ "$HASH1" == "$HASH2" ]]; then
echo "Expected state hash to update from $HASH1. Got $HASH2" echo "Expected state hash to update from $HASH1. Got $HASH2"
exit 1 exit 1
@@ -58,7 +58,7 @@ for i in $(seq 1 "$N"); do
for j in $(seq 1 "$N"); do for j in $(seq 1 "$N"); do
if [[ "$i" != "$j" ]]; then if [[ "$i" != "$j" ]]; then
addrJ=$(test/p2p/ip.sh "$j"):46657 addrJ=$(test/p2p/ip.sh "$j"):46657
HASH3=$(curl -s "$addrJ/status" | jq .result.latest_app_hash) HASH3=$(curl -s "$addrJ/status" | jq .result.sync_info.latest_app_hash)
if [[ "$HASH2" != "$HASH3" ]]; then if [[ "$HASH2" != "$HASH3" ]]; then
echo "App hash for node $j doesn't match. Got $HASH3, expected $HASH2" echo "App hash for node $j doesn't match. Got $HASH3, expected $HASH2"

View File

@@ -54,12 +54,12 @@ for i in `seq 1 $N`; do
done done
# - assert block height is greater than 1 # - assert block height is greater than 1
BLOCK_HEIGHT=`curl -s $addr/status | jq .result.latest_block_height` BLOCK_HEIGHT=`curl -s $addr/status | jq .result.sync_info.latest_block_height`
COUNT=0 COUNT=0
while [ "$BLOCK_HEIGHT" -le 1 ]; do while [ "$BLOCK_HEIGHT" -le 1 ]; do
echo "Waiting for node $i to commit a block ..." echo "Waiting for node $i to commit a block ..."
sleep 1 sleep 1
BLOCK_HEIGHT=`curl -s $addr/status | jq .result.latest_block_height` BLOCK_HEIGHT=`curl -s $addr/status | jq .result.sync_info.latest_block_height`
COUNT=$((COUNT+1)) COUNT=$((COUNT+1))
if [ "$COUNT" -gt "$MAX_SLEEP" ]; then if [ "$COUNT" -gt "$MAX_SLEEP" ]; then
echo "Waited too long for node $i to commit a block" echo "Waited too long for node $i to commit a block"

View File

@@ -15,10 +15,10 @@ peerID=$(( $(($ID % 4)) + 1 )) # 1->2 ... 3->4 ... 4->1
peer_addr=$(test/p2p/ip.sh $peerID):46657 peer_addr=$(test/p2p/ip.sh $peerID):46657
# get another peer's height # get another peer's height
h1=`curl -s $peer_addr/status | jq .result.latest_block_height` h1=`curl -s $peer_addr/status | jq .result.sync_info.latest_block_height`
# get another peer's state # get another peer's state
root1=`curl -s $peer_addr/status | jq .result.latest_app_hash` root1=`curl -s $peer_addr/status | jq .result.sync_info.latest_app_hash`
echo "Other peer is on height $h1 with state $root1" echo "Other peer is on height $h1 with state $root1"
echo "Waiting for peer $ID to catch up" echo "Waiting for peer $ID to catch up"
@@ -29,12 +29,12 @@ set +o pipefail
h2="0" h2="0"
while [[ "$h2" -lt "$(($h1+3))" ]]; do while [[ "$h2" -lt "$(($h1+3))" ]]; do
sleep 1 sleep 1
h2=`curl -s $addr/status | jq .result.latest_block_height` h2=`curl -s $addr/status | jq .result.sync_info.latest_block_height`
echo "... $h2" echo "... $h2"
done done
# check the app hash # check the app hash
root2=`curl -s $addr/status | jq .result.latest_app_hash` root2=`curl -s $addr/status | jq .result.sync_info.latest_app_hash`
if [[ "$root1" != "$root2" ]]; then if [[ "$root1" != "$root2" ]]; then
echo "App hash after fast sync does not match. Got $root2; expected $root1" echo "App hash after fast sync does not match. Got $root2; expected $root1"

View File

@@ -23,7 +23,7 @@ set -e
# get the first peer's height # get the first peer's height
addr=$(test/p2p/ip.sh 1):46657 addr=$(test/p2p/ip.sh 1):46657
h1=$(curl -s "$addr/status" | jq .result.latest_block_height) h1=$(curl -s "$addr/status" | jq .result.sync_info.latest_block_height)
echo "1st peer is on height $h1" echo "1st peer is on height $h1"
echo "Waiting until other peers reporting a height higher than the 1st one" echo "Waiting until other peers reporting a height higher than the 1st one"
@@ -33,7 +33,7 @@ for i in $(seq 2 "$NUM_OF_PEERS"); do
while [[ $hi -le $h1 ]] ; do while [[ $hi -le $h1 ]] ; do
addr=$(test/p2p/ip.sh "$i"):46657 addr=$(test/p2p/ip.sh "$i"):46657
hi=$(curl -s "$addr/status" | jq .result.latest_block_height) hi=$(curl -s "$addr/status" | jq .result.sync_info.latest_block_height)
echo "... peer $i is on height $hi" echo "... peer $i is on height $hi"

View File

@@ -31,7 +31,7 @@ function start_procs(){
if [[ "$CIRCLECI" == true ]]; then if [[ "$CIRCLECI" == true ]]; then
$TM_CMD & $TM_CMD &
else else
$TM_CMD &> "tendermint_${name}.log" & $TM_CMD &> "tendermint_${name}.log" &
fi fi
PID_TENDERMINT=$! PID_TENDERMINT=$!
else else
@@ -60,8 +60,8 @@ function wait_for_port() {
i=0 i=0
while [ "$ERR" == 0 ]; do while [ "$ERR" == 0 ]; do
echo "... port $port is still bound. waiting ..." echo "... port $port is still bound. waiting ..."
sleep 1 sleep 1
nc -z 127.0.0.1 $port nc -z 127.0.0.1 $port
ERR=$? ERR=$?
i=$((i + 1)) i=$((i + 1))
if [[ $i == 10 ]]; then if [[ $i == 10 ]]; then
@@ -97,7 +97,7 @@ for failIndex in $(seq $failsStart $failsEnd); do
ERR=$? ERR=$?
i=0 i=0
while [ "$ERR" != 0 ]; do while [ "$ERR" != 0 ]; do
sleep 1 sleep 1
curl -s --unix-socket "$RPC_ADDR" http://localhost/status > /dev/null curl -s --unix-socket "$RPC_ADDR" http://localhost/status > /dev/null
ERR=$? ERR=$?
i=$((i + 1)) i=$((i + 1))
@@ -108,11 +108,11 @@ for failIndex in $(seq $failsStart $failsEnd); do
done done
# wait for a new block # wait for a new block
h1=$(curl -s --unix-socket "$RPC_ADDR" http://localhost/status | jq .result.latest_block_height) h1=$(curl -s --unix-socket "$RPC_ADDR" http://localhost/status | jq .result.sync_info.latest_block_height)
h2=$h1 h2=$h1
while [ "$h2" == "$h1" ]; do while [ "$h2" == "$h1" ]; do
sleep 1 sleep 1
h2=$(curl -s --unix-socket "$RPC_ADDR" http://localhost/status | jq .result.latest_block_height) h2=$(curl -s --unix-socket "$RPC_ADDR" http://localhost/status | jq .result.sync_info.latest_block_height)
done done
kill_procs kill_procs

View File

@@ -46,7 +46,7 @@ curl -s $addr/status > /dev/null
ERR=$? ERR=$?
i=0 i=0
while [ "$ERR" != 0 ]; do while [ "$ERR" != 0 ]; do
sleep 1 sleep 1
curl -s $addr/status > /dev/null curl -s $addr/status > /dev/null
ERR=$? ERR=$?
i=$(($i + 1)) i=$(($i + 1))
@@ -57,11 +57,11 @@ while [ "$ERR" != 0 ]; do
done done
# wait for a new block # wait for a new block
h1=`curl -s $addr/status | jq .result.latest_block_height` h1=`curl -s $addr/status | jq .result.sync_info.latest_block_height`
h2=$h1 h2=$h1
while [ "$h2" == "$h1" ]; do while [ "$h2" == "$h1" ]; do
sleep 1 sleep 1
h2=`curl -s $addr/status | jq .result.latest_block_height` h2=`curl -s $addr/status | jq .result.sync_info.latest_block_height`
done done
kill_procs kill_procs

View File

@@ -3,7 +3,7 @@ package types
import ( import (
"time" "time"
"github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
) )

Some files were not shown because too many files have changed in this diff Show More