From 3a3b6c9a454bdd40d81718ee6f7b18e7631f7868 Mon Sep 17 00:00:00 2001 From: Ethan Buchman <ethan@coinculture.info> Date: Fri, 12 Feb 2016 19:11:52 -0500 Subject: [PATCH] tmsp updates --- Godeps/Godeps.json | 60 - .../tendermint/go-common/service.go | 2 +- .../tendermint/go-common/test/mutate.go | 2 +- .../github.com/tendermint/go-config/config.go | 2 +- .../tendermint/go-crypto/priv_key.go | 8 +- .../tendermint/go-crypto/pub_key.go | 8 +- .../tendermint/go-crypto/signature.go | 4 +- .../tendermint/go-crypto/signature_test.go | 6 +- .../src/github.com/tendermint/go-db/config.go | 2 +- .../src/github.com/tendermint/go-db/db.go | 2 +- .../github.com/tendermint/go-db/level_db.go | 2 +- .../github.com/tendermint/go-logger/config.go | 2 +- .../github.com/tendermint/go-logger/log.go | 4 +- .../tendermint/go-merkle/iavl_node.go | 4 +- .../tendermint/go-merkle/iavl_proof.go | 4 +- .../tendermint/go-merkle/iavl_test.go | 8 +- .../tendermint/go-merkle/iavl_tree.go | 6 +- .../tendermint/go-merkle/simple_tree.go | 4 +- .../tendermint/go-merkle/simple_tree_test.go | 4 +- .../github.com/tendermint/go-p2p/addrbook.go | 2 +- .../tendermint/go-p2p/connection.go | 6 +- .../github.com/tendermint/go-p2p/listener.go | 4 +- .../src/github.com/tendermint/go-p2p/log.go | 2 +- .../tendermint/go-p2p/netaddress.go | 2 +- .../src/github.com/tendermint/go-p2p/peer.go | 4 +- .../tendermint/go-p2p/peer_set_test.go | 2 +- .../tendermint/go-p2p/pex_reactor.go | 4 +- .../tendermint/go-p2p/secret_connection.go | 6 +- .../go-p2p/secret_connection_test.go | 4 +- .../github.com/tendermint/go-p2p/switch.go | 6 +- .../tendermint/go-p2p/switch_test.go | 6 +- .../src/github.com/tendermint/go-p2p/types.go | 2 +- .../github.com/tendermint/go-p2p/upnp/log.go | 2 +- .../tendermint/go-p2p/upnp/probe.go | 2 +- .../tendermint/go-wire/byteslice.go | 2 +- .../github.com/tendermint/go-wire/codec.go | 2 +- .../src/github.com/tendermint/go-wire/log.go | 2 +- .../github.com/tendermint/go-wire/reflect.go | 2 +- .../tendermint/go-wire/reflect_test.go | 2 +- .../github.com/tendermint/go-wire/string.go | 2 +- .../src/github.com/tendermint/go-wire/time.go | 2 +- .../src/github.com/tendermint/go-wire/util.go | 2 +- .../src/github.com/tendermint/go-wire/wire.go | 2 +- .../tendermint/tendermint/alert/alert.go | 64 - .../tendermint/tendermint/alert/config.go | 13 - .../tendermint/tendermint/alert/email.go | 176 --- .../tendermint/tendermint/alert/log.go | 7 - .../tendermint/tendermint/blockchain/log.go | 7 - .../tendermint/tendermint/blockchain/pool.go | 512 ------- .../tendermint/blockchain/pool_test.go | 132 -- .../tendermint/blockchain/reactor.go | 339 ----- .../tendermint/tendermint/blockchain/store.go | 231 ---- .../tendermint/config/tendermint/config.go | 89 -- .../tendermint/config/tendermint/genesis.json | 75 -- .../config/tendermint/logrotate.config | 22 - .../config/tendermint_test/config.go | 142 -- .../tendermint/tendermint/consensus/README.md | 4 - .../tendermint/consensus/common_test.go | 335 ----- .../tendermint/tendermint/consensus/config.go | 13 - .../tendermint/consensus/height_vote_set.go | 182 --- .../tendermint/tendermint/consensus/log.go | 7 - .../tendermint/consensus/reactor.go | 1007 -------------- .../tendermint/tendermint/consensus/state.go | 1189 ----------------- .../tendermint/consensus/state_test.go | 1186 ---------------- .../tendermint/events/event_cache.go | 45 - .../tendermint/tendermint/events/events.go | 205 --- .../tendermint/tendermint/events/log.go | 7 - .../tendermint/tendermint/mempool/config.go | 13 - .../tendermint/tendermint/mempool/log.go | 7 - .../tendermint/tendermint/mempool/mempool.go | 226 ---- .../tendermint/mempool/mempool_test.go | 118 -- .../tendermint/tendermint/mempool/reactor.go | 172 --- .../tendermint/tendermint/node/config.go | 13 - .../tendermint/tendermint/node/id.go | 34 - .../tendermint/tendermint/node/log.go | 7 - .../tendermint/tendermint/node/node.go | 339 ----- .../tendermint/tendermint/node/node_test.go | 44 - .../tendermint/tendermint/node/version.go | 6 - .../tendermint/proxy/app_context.go | 28 - .../tendermint/proxy/local_app_context.go | 123 -- .../tendermint/tendermint/proxy/log.go | 7 - .../tendermint/proxy/remote_app_context.go | 310 ----- .../proxy/remote_app_context_test.go | 98 -- .../tendermint/rpc/client/client.go | 51 - .../tendermint/tendermint/rpc/client/log.go | 7 - .../tendermint/tendermint/rpc/core/blocks.go | 45 - .../tendermint/tendermint/rpc/core/config.go | 13 - .../tendermint/rpc/core/consensus.go | 35 - .../tendermint/tendermint/rpc/core/log.go | 7 - .../tendermint/tendermint/rpc/core/mempool.go | 23 - .../tendermint/tendermint/rpc/core/net.go | 58 - .../tendermint/tendermint/rpc/core/pipe.go | 45 - .../tendermint/tendermint/rpc/core/routes.go | 19 - .../tendermint/rpc/core/types/responses.go | 104 -- .../tendermint/rpc/server/handlers.go | 516 ------- .../tendermint/rpc/server/http_params.go | 89 -- .../tendermint/rpc/server/http_server.go | 121 -- .../tendermint/tendermint/rpc/server/log.go | 7 - .../tendermint/tendermint/rpc/types/types.go | 24 - .../tendermint/tendermint/rpc/version.go | 3 - .../tendermint/tendermint/state/execution.go | 181 --- .../tendermint/tendermint/state/log.go | 7 - .../tendermint/tendermint/state/state.go | 139 -- .../tendermint/tendermint/state/wtf | 68 - .../tendermint/tendermint/types/README.md | 61 - .../tendermint/tendermint/types/block.go | 355 ----- .../tendermint/tendermint/types/block_meta.go | 15 - .../tendermint/tendermint/types/config.go | 13 - .../tendermint/tendermint/types/events.go | 102 -- .../tendermint/tendermint/types/genesis.go | 48 - .../tendermint/tendermint/types/keys.go | 6 - .../tendermint/tendermint/types/log.go | 7 - .../tendermint/tendermint/types/myfile | Bin 598 -> 0 bytes .../tendermint/tendermint/types/part_set.go | 241 ---- .../tendermint/types/part_set_test.go | 86 -- .../tendermint/types/priv_validator.go | 197 --- .../tendermint/tendermint/types/proposal.go | 47 - .../tendermint/types/proposal_test.go | 25 - .../tendermint/tendermint/types/signable.go | 30 - .../tendermint/tendermint/types/stats.go | 46 - .../tendermint/tendermint/types/tx.go | 3 - .../tendermint/tendermint/types/validator.go | 85 -- .../tendermint/types/validator_set.go | 311 ----- .../tendermint/types/validator_set_test.go | 163 --- .../tendermint/tendermint/types/vote.go | 85 -- .../tendermint/tendermint/types/vote_set | 0 .../tendermint/tendermint/types/vote_set.go | 323 ----- .../tendermint/types/vote_set_test.go | 278 ---- .../tendermint/tmsp/server/server.go | 6 +- .../tendermint/tmsp/types/messages.go | 2 +- account/account.go | 34 +- account/priv_account.go | 29 +- account/priv_key.go | 70 - account/pub_key.go | 90 -- account/signature.go | 34 - account/signature_test.go | 70 - erisdb/codec.go | 2 +- erisdb/config.go | 2 +- erisdb/erisdbss/http.go | 6 +- erisdb/erisdbss/log.go | 2 +- erisdb/erisdbss/server_manager.go | 4 +- erisdb/event_cache.go | 4 +- erisdb/event_cache_test.go | 10 +- erisdb/pipe/accounts.go | 14 +- erisdb/pipe/blockchain.go | 4 +- erisdb/pipe/config.go | 4 +- erisdb/pipe/consensus.go | 2 +- erisdb/pipe/events.go | 5 +- erisdb/pipe/namereg.go | 5 +- erisdb/pipe/pipe.go | 6 +- erisdb/pipe/transactor.go | 14 +- erisdb/pipe/types.go | 6 +- erisdb/serve.go | 30 +- erisdb/wsService.go | 4 +- evm/log.go | 2 +- evm/native.go | 2 +- evm/snative.go | 2 +- evm/stack.go | 2 +- evm/test/fake_app_state.go | 2 +- evm/test/log_event_test.go | 6 +- evm/test/vm_test.go | 6 +- evm/types.go | 2 +- evm/vm.go | 4 +- files/log.go | 2 +- permission/types/permissions.go | 2 +- permission/types/snatives.go | 2 +- server/log.go | 2 +- server/logging.go | 2 +- state/block_cache.go | 18 +- state/common.go | 2 +- state/execution.go | 4 +- state/genesis_test.go | 2 +- state/log.go | 2 +- state/permissions_test.go | 8 +- state/state.go | 57 +- state/state_test.go | 4 +- state/test.go | 9 +- state/tx_cache.go | 9 +- state/tx_cache_test.go | 2 +- state/types/genesis.go | 6 +- test/mock/mock_web_api_test.go | 6 +- test/mock/pipe.go | 4 +- test/server/scumbag.go | 2 +- test/transacting/transacting_tes.go | 2 +- test/web_api/shared.go | 2 +- tmsp/erisdb.go | 112 +- txs/config.go | 2 +- txs/events.go | 6 +- txs/log.go | 2 +- txs/tx.go | 37 +- txs/tx_test.go | 4 +- txs/tx_utils.go | 42 +- 192 files changed, 355 insertions(+), 12315 deletions(-) delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/alert/email.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/config.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/logrotate.config delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test/config.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/README.md delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/common_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/config.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/height_vote_set.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/reactor.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/events/event_cache.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/reactor.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/node/node.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/node/node_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/node/version.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/app_context.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/local_app_context.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/client.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/blocks.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/config.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/consensus.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/mempool.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/net.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/pipe.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/routes.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types/responses.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/handlers.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_params.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_server.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types/types.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/version.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/README.md delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/block_meta.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/genesis.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/keys.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/myfile delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/priv_validator.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/stats.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set_test.go delete mode 100644 account/priv_key.go delete mode 100644 account/pub_key.go delete mode 100644 account/signature.go delete mode 100644 account/signature_test.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index b3a9d001..3d4efb72 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -125,66 +125,6 @@ "Comment": "v2.3-36-gc65281b", "Rev": "c65281bb703b7612f60558e75b07c434c06e2636" }, - { - "ImportPath": "github.com/tendermint/tendermint/alert", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/blockchain", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/config/tendermint", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/config/tendermint_test", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/consensus", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/events", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/mempool", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/node", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/proxy", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/rpc", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/state", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/types", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, { "ImportPath": "github.com/tendermint/tmsp/server", "Rev": "1b7ca808beb0d1be7bc9a606f6aa46cc1f65fd93" diff --git a/Godeps/_workspace/src/github.com/tendermint/go-common/service.go b/Godeps/_workspace/src/github.com/tendermint/go-common/service.go index d2d8f2c1..ca923b1d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-common/service.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/service.go @@ -41,7 +41,7 @@ package common import ( "sync/atomic" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" ) type Service interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go b/Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go index 2c5a0156..629e9f86 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go @@ -1,7 +1,7 @@ package test import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) // Contract: !bytes.Equal(input, output) && len(input) >= len(output) diff --git a/Godeps/_workspace/src/github.com/tendermint/go-config/config.go b/Godeps/_workspace/src/github.com/tendermint/go-config/config.go index d0f2ccb3..342fb128 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-config/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-config/config.go @@ -5,7 +5,7 @@ import ( "sync" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type Config interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go index d81d5320..f548172e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go @@ -1,10 +1,10 @@ package crypto import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/ed25519" + "github.com/tendermint/ed25519/extra25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) // PrivKey is part of PrivAccount and state.PrivValidator. diff --git a/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go index cb9d368e..c4b981c2 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go @@ -3,10 +3,10 @@ package crypto import ( "bytes" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/ed25519" + "github.com/tendermint/ed25519/extra25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/ripemd160" ) diff --git a/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go index efa05793..95925809 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go @@ -3,8 +3,8 @@ package crypto import ( "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) // Signature is a part of Txs and consensus Votes. diff --git a/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go index daf6c1b3..1dbc5809 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go @@ -4,9 +4,9 @@ import ( "bytes" "testing" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/ed25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) func TestSignAndValidate(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-db/config.go b/Godeps/_workspace/src/github.com/tendermint/go-db/config.go index fcd46e65..da66c215 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-db/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/config.go @@ -1,7 +1,7 @@ package db import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" + cfg "github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/go-db/db.go b/Godeps/_workspace/src/github.com/tendermint/go-db/db.go index e60ac59a..2d9c3d2b 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-db/db.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/db.go @@ -3,7 +3,7 @@ package db import ( "path" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type DB interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go b/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go index f0409b16..66df8e27 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go @@ -8,7 +8,7 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type LevelDB struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go b/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go index 0c390168..4083152a 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go @@ -1,7 +1,7 @@ package logger import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" + cfg "github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go b/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go index 663e4729..e616d0ac 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go @@ -3,8 +3,8 @@ package logger import ( "os" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + . "github.com/tendermint/go-common" + "github.com/tendermint/log15" ) var rootHandler log15.Handler diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go index 365b33b0..7c6ea1f0 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go @@ -5,8 +5,8 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" "io" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) // Node diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go index b8a1b960..9fbf2d6b 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go @@ -5,8 +5,8 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) type IAVLProof struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go index 28679d7e..ecf496e7 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go @@ -4,10 +4,10 @@ import ( "bytes" "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common/test" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + . "github.com/tendermint/go-common/test" + "github.com/tendermint/go-db" + "github.com/tendermint/go-wire" "runtime" "testing" diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go index 7b9a2281..2fafdc74 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go @@ -5,9 +5,9 @@ import ( "container/list" "sync" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-wire" ) /* diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go index 7fd51a87..74da2eab 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go @@ -31,8 +31,8 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) func SimpleHashFromTwoHashes(left []byte, right []byte) []byte { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go index 5a1b0957..016d179d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go @@ -3,8 +3,8 @@ package merkle import ( "bytes" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common/test" + . "github.com/tendermint/go-common" + . "github.com/tendermint/go-common/test" "fmt" "testing" diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go index b827ae2c..14b39b57 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go @@ -14,7 +14,7 @@ import ( "sync" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) const ( diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go index adc64a10..494fdd75 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go @@ -10,9 +10,9 @@ import ( "sync/atomic" "time" - flow "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/flowcontrol" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" //"github.com/tendermint/log15" + flow "github.com/tendermint/flowcontrol" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" //"github.com/tendermint/log15" ) const ( diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go index 9bb7c62d..1d7fb956 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go @@ -6,8 +6,8 @@ import ( "strconv" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-p2p/upnp" ) type Listener interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go index 06f360e8..ac1ff22a 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go @@ -1,7 +1,7 @@ package p2p import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "p2p") diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go index 06615cd5..bdb42a00 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go @@ -10,7 +10,7 @@ import ( "strconv" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type NetAddress struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go index 13f5d2a7..a0f153fe 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go @@ -5,8 +5,8 @@ import ( "io" "net" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) type Peer struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go index 50454369..ceb10eee 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go @@ -4,7 +4,7 @@ import ( "math/rand" "testing" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) // Returns an empty dummy peer diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go index 0e28156b..f6dacdb1 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go @@ -8,8 +8,8 @@ import ( "reflect" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) var pexErrInvalidMessage = errors.New("Invalid PEX message") diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go index fe319ace..385a7dab 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go @@ -20,9 +20,9 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-wire" ) // 2 + 1024 == 1026 total frame size diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go index 9f40250b..9bf1a7b1 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go @@ -5,8 +5,8 @@ import ( "io" "testing" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" ) type dummyConn struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go index 486b8999..d118d95e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go @@ -6,9 +6,9 @@ import ( "net" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/log15" ) type Reactor interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go index 93e3a7df..04664979 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go @@ -6,9 +6,9 @@ import ( "testing" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-wire" ) type PeerMessage struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go index 5a0e8b35..0db2c957 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go @@ -6,7 +6,7 @@ import ( "strconv" "strings" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto" ) const maxNodeInfoSize = 10240 // 10Kb diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go index 1b02cb12..edc5b498 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go @@ -1,7 +1,7 @@ package upnp import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "upnp") diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go index 9532729d..5ba9b237 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go @@ -6,7 +6,7 @@ import ( "net" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type UPNPCapabilities struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go index 71348817..fda9f340 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go @@ -3,7 +3,7 @@ package wire import ( "io" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) func WriteByteSlice(bz []byte, w io.Writer, n *int, err *error) { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go index bfd19652..35d1a74b 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go @@ -4,7 +4,7 @@ import ( "bytes" "errors" "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" "io" "reflect" "time" diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go index 66e9e733..5aeca07a 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go @@ -1,7 +1,7 @@ package wire import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "binary") diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go index cc4185e8..1e25548e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go @@ -9,7 +9,7 @@ import ( "sync" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type TypeInfo struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go index 8050ba5e..c8cdd665 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type SimpleStruct struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go index e762221a..83c8fb1b 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go @@ -3,7 +3,7 @@ package wire import ( "io" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) // String diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go index 1d6f7e46..746b299e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go @@ -4,7 +4,7 @@ import ( "io" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) /* diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go index bde328d9..db9fa41f 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go @@ -7,7 +7,7 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) func BinaryBytes(o interface{}) []byte { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go index b983ff0e..5bff4ced 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go @@ -6,7 +6,7 @@ import ( "io" "reflect" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) var ErrBinaryReadSizeOverflow = errors.New("Error: binary read size overflow") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go deleted file mode 100644 index 497be012..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go +++ /dev/null @@ -1,64 +0,0 @@ -package alert - -import ( - "fmt" - "time" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/sfreiberg/gotwilio" -) - -var lastAlertUnix int64 = 0 -var alertCountSince int = 0 - -// Sends a critical alert message to administrators. -func Alert(message string) { - log.Error("<!> ALERT <!>\n" + message) - now := time.Now().Unix() - if now-lastAlertUnix > int64(config.GetInt("alert_min_interval")) { - message = fmt.Sprintf("%v:%v", config.GetString("chain_id"), message) - if alertCountSince > 0 { - message = fmt.Sprintf("%v (+%v more since)", message, alertCountSince) - alertCountSince = 0 - } - if len(config.GetString("alert_twilio_sid")) > 0 { - go sendTwilio(message) - } - if len(config.GetString("alert_email_recipients")) > 0 { - go sendEmail(message) - } - } else { - alertCountSince++ - } -} - -func sendTwilio(message string) { - defer func() { - if err := recover(); err != nil { - log.Error("sendTwilio error", "error", err) - } - }() - if len(message) > 50 { - message = message[:50] - } - twilio := gotwilio.NewTwilioClient(config.GetString("alert_twilio_sid"), config.GetString("alert_twilio_token")) - res, exp, err := twilio.SendSMS(config.GetString("alert_twilio_from"), config.GetString("alert_twilio_to"), message, "", "") - if exp != nil || err != nil { - log.Error("sendTwilio error", "res", res, "exp", exp, "error", err) - } -} - -func sendEmail(message string) { - defer func() { - if err := recover(); err != nil { - log.Error("sendEmail error", "error", err) - } - }() - subject := message - if len(subject) > 80 { - subject = subject[:80] - } - err := SendEmail(subject, message, config.GetStringSlice("alert_email_recipients")) - if err != nil { - log.Error("sendEmail error", "error", err, "message", message) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go deleted file mode 100644 index b42f6167..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package alert - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/email.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/email.go deleted file mode 100644 index c183f1d5..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/email.go +++ /dev/null @@ -1,176 +0,0 @@ -// Forked from github.com/SlyMarbo/gmail -package alert - -import ( - "bytes" - "crypto/tls" - "encoding/base64" - "errors" - "fmt" - "io/ioutil" - "net/smtp" - "path/filepath" - "regexp" - "strings" -) - -// Convenience function -func SendEmail(subject, body string, tos []string) error { - email := Compose(subject, body) - email.From = config.GetString("smtp_user") - email.ContentType = "text/html; charset=utf-8" - email.AddRecipients(tos...) - err := email.Send() - return err -} - -// Email represents a single message, which may contain -// attachments. -type Email struct { - From string - To []string - Subject string - ContentType string - Body string - Attachments map[string][]byte -} - -// Compose begins a new email, filling the subject and body, -// and allocating memory for the list of recipients and the -// attachments. -func Compose(Subject, Body string) *Email { - out := new(Email) - out.To = make([]string, 0, 1) - out.Subject = Subject - out.Body = Body - out.Attachments = make(map[string][]byte) - return out -} - -// Attach takes a filename and adds this to the message. -// Note that since only the filename is stored (and not -// its path, for privacy reasons), multiple files in -// different directories but with the same filename and -// extension cannot be sent. -func (e *Email) Attach(Filename string) error { - b, err := ioutil.ReadFile(Filename) - if err != nil { - return err - } - - _, fname := filepath.Split(Filename) - e.Attachments[fname] = b - return nil -} - -// AddRecipient adds a single recipient. -func (e *Email) AddRecipient(Recipient string) { - e.To = append(e.To, Recipient) -} - -// AddRecipients adds one or more recipients. -func (e *Email) AddRecipients(Recipients ...string) { - e.To = append(e.To, Recipients...) -} - -// Send sends the email, returning any error encountered. -func (e *Email) Send() error { - if e.From == "" { - return errors.New("Error: No sender specified. Please set the Email.From field.") - } - if e.To == nil || len(e.To) == 0 { - return errors.New("Error: No recipient specified. Please set the Email.To field.") - } - - auth := smtp.PlainAuth( - "", - config.GetString("smtp_user"), - config.GetString("smtp_password"), - config.GetString("smtp_host"), - ) - - conn, err := smtp.Dial(fmt.Sprintf("%v:%v", config.GetString("smtp_host"), config.GetString("smtp_port"))) - if err != nil { - return err - } - - err = conn.StartTLS(&tls.Config{}) - if err != nil { - return err - } - - err = conn.Auth(auth) - if err != nil { - return err - } - - err = conn.Mail(e.From) - if err != nil { - if strings.Contains(err.Error(), "530 5.5.1") { - return errors.New("Error: Authentication failure. Your username or password is incorrect.") - } - return err - } - - for _, recipient := range e.To { - err = conn.Rcpt(recipient) - if err != nil { - return err - } - } - - wc, err := conn.Data() - if err != nil { - return err - } - defer wc.Close() - _, err = wc.Write(e.Bytes()) - if err != nil { - return err - } - - return nil -} - -func (e *Email) Bytes() []byte { - buf := bytes.NewBuffer(nil) - - var subject = e.Subject - subject = regexp.MustCompile("\n+").ReplaceAllString(subject, " ") - subject = regexp.MustCompile(" +").ReplaceAllString(subject, " ") - buf.WriteString("Subject: " + subject + "\n") - buf.WriteString("To: <" + strings.Join(e.To, ">,<") + ">\n") - buf.WriteString("MIME-Version: 1.0\n") - - // Boundary is used by MIME to separate files. - boundary := "f46d043c813270fc6b04c2d223da" - - if len(e.Attachments) > 0 { - buf.WriteString("Content-Type: multipart/mixed; boundary=" + boundary + "\n") - buf.WriteString("--" + boundary + "\n") - } - - if e.ContentType == "" { - e.ContentType = "text/plain; charset=utf-8" - } - buf.WriteString(fmt.Sprintf("Content-Type: %s\n\n", e.ContentType)) - buf.WriteString(e.Body) - - if len(e.Attachments) > 0 { - for k, v := range e.Attachments { - buf.WriteString("\n\n--" + boundary + "\n") - buf.WriteString("Content-Type: application/octet-stream\n") - buf.WriteString("Content-Transfer-Encoding: base64\n") - buf.WriteString("Content-Disposition: attachment; filename=\"" + k + "\"\n\n") - - b := make([]byte, base64.StdEncoding.EncodedLen(len(v))) - base64.StdEncoding.Encode(b, v) - buf.Write(b) - buf.WriteString("\n--" + boundary) - } - - buf.WriteString("--") - } - - return buf.Bytes() -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go deleted file mode 100644 index 73e8c457..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package alert - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "alert") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/log.go deleted file mode 100644 index 41b90776..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package blockchain - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "blockchain") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool.go deleted file mode 100644 index db750c1d..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool.go +++ /dev/null @@ -1,512 +0,0 @@ -package blockchain - -import ( - "math" - "sync" - "time" - - flow "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/flowcontrol" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - requestIntervalMS = 250 - maxTotalRequesters = 300 - maxPendingRequests = maxTotalRequesters - maxPendingRequestsPerPeer = 75 - peerTimeoutSeconds = 15 - minRecvRate = 10240 // 10Kb/s -) - -/* - Peers self report their heights when we join the block pool. - Starting from our latest pool.height, we request blocks - in sequence from peers that reported higher heights than ours. - Every so often we ask peers what height they're on so we can keep going. - - Requests are continuously made for blocks of heigher heights until - the limits. If most of the requests have no available peers, and we - are not at peer limits, we can probably switch to consensus reactor -*/ - -type BlockPool struct { - QuitService - startTime time.Time - - // block requests - mtx sync.Mutex - requesters map[int]*bpRequester - height int // the lowest key in requesters. - numPending int32 // number of requests pending assignment or block response - - // peers - peersMtx sync.Mutex - peers map[string]*bpPeer - - requestsCh chan<- BlockRequest - timeoutsCh chan<- string -} - -func NewBlockPool(start int, requestsCh chan<- BlockRequest, timeoutsCh chan<- string) *BlockPool { - bp := &BlockPool{ - peers: make(map[string]*bpPeer), - - requesters: make(map[int]*bpRequester), - height: start, - numPending: 0, - - requestsCh: requestsCh, - timeoutsCh: timeoutsCh, - } - bp.QuitService = *NewQuitService(log, "BlockPool", bp) - return bp -} - -func (pool *BlockPool) OnStart() error { - pool.QuitService.OnStart() - go pool.makeRequestersRoutine() - pool.startTime = time.Now() - return nil -} - -func (pool *BlockPool) OnStop() { - pool.QuitService.OnStop() -} - -// Run spawns requesters as needed. -func (pool *BlockPool) makeRequestersRoutine() { - for { - if !pool.IsRunning() { - break - } - _, numPending := pool.GetStatus() - if numPending >= maxPendingRequests { - // sleep for a bit. - time.Sleep(requestIntervalMS * time.Millisecond) - // check for timed out peers - pool.removeTimedoutPeers() - } else if len(pool.requesters) >= maxTotalRequesters { - // sleep for a bit. - time.Sleep(requestIntervalMS * time.Millisecond) - // check for timed out peers - pool.removeTimedoutPeers() - } else { - // request for more blocks. - pool.makeNextRequester() - } - } -} - -func (pool *BlockPool) removeTimedoutPeers() { - for _, peer := range pool.peers { - if !peer.didTimeout && peer.numPending > 0 { - curRate := peer.recvMonitor.Status().CurRate - // XXX remove curRate != 0 - if curRate != 0 && curRate < minRecvRate { - pool.sendTimeout(peer.id) - log.Warn("SendTimeout", "peer", peer.id, "reason", "curRate too low") - peer.didTimeout = true - } - } - if peer.didTimeout { - pool.peersMtx.Lock() // Lock - pool.removePeer(peer.id) - pool.peersMtx.Unlock() - } - } -} - -func (pool *BlockPool) GetStatus() (height int, numPending int32) { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - return pool.height, pool.numPending -} - -// TODO: relax conditions, prevent abuse. -func (pool *BlockPool) IsCaughtUp() bool { - pool.mtx.Lock() - height := pool.height - pool.mtx.Unlock() - - pool.peersMtx.Lock() - numPeers := len(pool.peers) - maxPeerHeight := 0 - for _, peer := range pool.peers { - maxPeerHeight = MaxInt(maxPeerHeight, peer.height) - } - pool.peersMtx.Unlock() - - return numPeers >= 3 && (height > 0 || time.Now().Sub(pool.startTime) > 30*time.Second) && (maxPeerHeight == 0 || height == maxPeerHeight) -} - -// We need to see the second block's Validation to validate the first block. -// So we peek two blocks at a time. -func (pool *BlockPool) PeekTwoBlocks() (first *types.Block, second *types.Block) { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - if r := pool.requesters[pool.height]; r != nil { - first = r.getBlock() - } - if r := pool.requesters[pool.height+1]; r != nil { - second = r.getBlock() - } - return -} - -// Pop the first block at pool.height -// It must have been validated by 'second'.Validation from PeekTwoBlocks(). -func (pool *BlockPool) PopRequest() { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - if r := pool.requesters[pool.height]; r != nil { - /* The block can disappear at any time, due to removePeer(). - if r := pool.requesters[pool.height]; r == nil || r.block == nil { - PanicSanity("PopRequest() requires a valid block") - } - */ - r.Stop() - delete(pool.requesters, pool.height) - pool.height++ - } else { - PanicSanity(Fmt("Expected requester to pop, got nothing at height %v", pool.height)) - } -} - -// Invalidates the block at pool.height, -// Remove the peer and redo request from others. -func (pool *BlockPool) RedoRequest(height int) { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - request := pool.requesters[height] - if request.block == nil { - PanicSanity("Expected block to be non-nil") - } - // RemovePeer will redo all requesters associated with this peer. - // TODO: record this malfeasance - pool.RemovePeer(request.peerID) // Lock on peersMtx. -} - -// TODO: ensure that blocks come in order for each peer. -func (pool *BlockPool) AddBlock(peerID string, block *types.Block, blockSize int) { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - requester := pool.requesters[block.Height] - if requester == nil { - return - } - - if requester.setBlock(block, peerID) { - pool.numPending-- - peer := pool.getPeer(peerID) - peer.decrPending(blockSize) - } else { - // Bad peer? - } -} - -// Sets the peer's alleged blockchain height. -func (pool *BlockPool) SetPeerHeight(peerID string, height int) { - pool.peersMtx.Lock() // Lock - defer pool.peersMtx.Unlock() - - peer := pool.peers[peerID] - if peer != nil { - peer.height = height - } else { - peer = newBPPeer(pool, peerID, height) - pool.peers[peerID] = peer - } -} - -func (pool *BlockPool) RemovePeer(peerID string) { - pool.peersMtx.Lock() // Lock - defer pool.peersMtx.Unlock() - - pool.removePeer(peerID) -} - -func (pool *BlockPool) removePeer(peerID string) { - for _, requester := range pool.requesters { - if requester.getPeerID() == peerID { - pool.numPending++ - go requester.redo() // pick another peer and ... - } - } - delete(pool.peers, peerID) -} - -func (pool *BlockPool) getPeer(peerID string) *bpPeer { - pool.peersMtx.Lock() // Lock - defer pool.peersMtx.Unlock() - - peer := pool.peers[peerID] - return peer -} - -// Pick an available peer with at least the given minHeight. -// If no peers are available, returns nil. -func (pool *BlockPool) pickIncrAvailablePeer(minHeight int) *bpPeer { - pool.peersMtx.Lock() - defer pool.peersMtx.Unlock() - - for _, peer := range pool.peers { - if peer.isBad() { - pool.removePeer(peer.id) - continue - } else { - } - if peer.numPending >= maxPendingRequestsPerPeer { - continue - } - if peer.height < minHeight { - continue - } - peer.incrPending() - return peer - } - return nil -} - -func (pool *BlockPool) makeNextRequester() { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - nextHeight := pool.height + len(pool.requesters) - request := newBPRequester(pool, nextHeight) - - pool.requesters[nextHeight] = request - pool.numPending++ - - request.Start() -} - -func (pool *BlockPool) sendRequest(height int, peerID string) { - if !pool.IsRunning() { - return - } - pool.requestsCh <- BlockRequest{height, peerID} -} - -func (pool *BlockPool) sendTimeout(peerID string) { - if !pool.IsRunning() { - return - } - pool.timeoutsCh <- peerID -} - -func (pool *BlockPool) debug() string { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - str := "" - for h := pool.height; h < pool.height+len(pool.requesters); h++ { - if pool.requesters[h] == nil { - str += Fmt("H(%v):X ", h) - } else { - str += Fmt("H(%v):", h) - str += Fmt("B?(%v) ", pool.requesters[h].block != nil) - } - } - return str -} - -//------------------------------------- - -type bpPeer struct { - pool *BlockPool - id string - height int - numPending int32 - recvMonitor *flow.Monitor - timeout *time.Timer - didTimeout bool -} - -func newBPPeer(pool *BlockPool, peerID string, height int) *bpPeer { - peer := &bpPeer{ - pool: pool, - id: peerID, - height: height, - numPending: 0, - } - return peer -} - -func (peer *bpPeer) resetMonitor() { - peer.recvMonitor = flow.New(time.Second, time.Second*40) - var initialValue = float64(minRecvRate) * math.E - peer.recvMonitor.SetREMA(initialValue) -} - -func (peer *bpPeer) resetTimeout() { - if peer.timeout == nil { - peer.timeout = time.AfterFunc(time.Second*peerTimeoutSeconds, peer.onTimeout) - } else { - peer.timeout.Reset(time.Second * peerTimeoutSeconds) - } -} - -func (peer *bpPeer) incrPending() { - if peer.numPending == 0 { - peer.resetMonitor() - peer.resetTimeout() - } - peer.numPending++ -} - -func (peer *bpPeer) decrPending(recvSize int) { - peer.numPending-- - if peer.numPending == 0 { - peer.timeout.Stop() - } else { - peer.recvMonitor.Update(recvSize) - peer.resetTimeout() - } -} - -func (peer *bpPeer) onTimeout() { - peer.pool.sendTimeout(peer.id) - log.Warn("SendTimeout", "peer", peer.id, "reason", "onTimeout") - peer.didTimeout = true -} - -func (peer *bpPeer) isBad() bool { - return peer.didTimeout -} - -//------------------------------------- - -type bpRequester struct { - QuitService - pool *BlockPool - height int - gotBlockCh chan struct{} - redoCh chan struct{} - - mtx sync.Mutex - peerID string - block *types.Block -} - -func newBPRequester(pool *BlockPool, height int) *bpRequester { - bpr := &bpRequester{ - pool: pool, - height: height, - gotBlockCh: make(chan struct{}), - redoCh: make(chan struct{}), - - peerID: "", - block: nil, - } - bpr.QuitService = *NewQuitService(nil, "bpRequester", bpr) - return bpr -} - -func (bpr *bpRequester) OnStart() error { - bpr.QuitService.OnStart() - go bpr.requestRoutine() - return nil -} - -// Returns true if the peer matches -func (bpr *bpRequester) setBlock(block *types.Block, peerID string) bool { - bpr.mtx.Lock() - if bpr.block != nil || bpr.peerID != peerID { - bpr.mtx.Unlock() - return false - } - bpr.block = block - bpr.mtx.Unlock() - - bpr.gotBlockCh <- struct{}{} - return true -} - -func (bpr *bpRequester) getBlock() *types.Block { - bpr.mtx.Lock() - defer bpr.mtx.Unlock() - return bpr.block -} - -func (bpr *bpRequester) getPeerID() string { - bpr.mtx.Lock() - defer bpr.mtx.Unlock() - return bpr.peerID -} - -func (bpr *bpRequester) reset() { - bpr.mtx.Lock() - bpr.peerID = "" - bpr.block = nil - bpr.mtx.Unlock() -} - -// Tells bpRequester to pick another peer and try again. -// NOTE: blocking -func (bpr *bpRequester) redo() { - bpr.redoCh <- struct{}{} -} - -// Responsible for making more requests as necessary -// Returns only when a block is found (e.g. AddBlock() is called) -func (bpr *bpRequester) requestRoutine() { -OUTER_LOOP: - for { - // Pick a peer to send request to. - var peer *bpPeer = nil - PICK_PEER_LOOP: - for { - if !bpr.IsRunning() || !bpr.pool.IsRunning() { - return - } - peer = bpr.pool.pickIncrAvailablePeer(bpr.height) - if peer == nil { - //log.Info("No peers available", "height", height) - time.Sleep(requestIntervalMS * time.Millisecond) - continue PICK_PEER_LOOP - } - break PICK_PEER_LOOP - } - bpr.mtx.Lock() - bpr.peerID = peer.id - bpr.mtx.Unlock() - - // Send request and wait. - bpr.pool.sendRequest(bpr.height, peer.id) - select { - case <-bpr.pool.Quit: - bpr.Stop() - return - case <-bpr.Quit: - return - case <-bpr.redoCh: - bpr.reset() - continue OUTER_LOOP // When peer is removed - case <-bpr.gotBlockCh: - // We got the block, now see if it's good. - select { - case <-bpr.pool.Quit: - bpr.Stop() - return - case <-bpr.Quit: - return - case <-bpr.redoCh: - bpr.reset() - continue OUTER_LOOP - } - } - } -} - -//------------------------------------- - -type BlockRequest struct { - Height int - PeerID string -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool_test.go deleted file mode 100644 index 4d6a3451..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package blockchain - -import ( - "math/rand" - "testing" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -type testPeer struct { - id string - height int -} - -func makePeers(numPeers int, minHeight, maxHeight int) map[string]testPeer { - peers := make(map[string]testPeer, numPeers) - for i := 0; i < numPeers; i++ { - peerID := RandStr(12) - height := minHeight + rand.Intn(maxHeight-minHeight) - peers[peerID] = testPeer{peerID, height} - } - return peers -} - -func TestBasic(t *testing.T) { - start := 42 - peers := makePeers(10, start+1, 1000) - timeoutsCh := make(chan string, 100) - requestsCh := make(chan BlockRequest, 100) - pool := NewBlockPool(start, requestsCh, timeoutsCh) - pool.Start() - - // Introduce each peer. - go func() { - for _, peer := range peers { - pool.SetPeerHeight(peer.id, peer.height) - } - }() - - // Start a goroutine to pull blocks - go func() { - for { - if !pool.IsRunning() { - return - } - first, second := pool.PeekTwoBlocks() - if first != nil && second != nil { - pool.PopRequest() - } else { - time.Sleep(1 * time.Second) - } - } - }() - - // Pull from channels - for { - select { - case peerID := <-timeoutsCh: - t.Errorf("timeout: %v", peerID) - case request := <-requestsCh: - log.Info("TEST: Pulled new BlockRequest", "request", request) - if request.Height == 300 { - return // Done! - } - // Request desired, pretend like we got the block immediately. - go func() { - block := &types.Block{Header: &types.Header{Height: request.Height}} - pool.AddBlock(request.PeerID, block, 123) - log.Info("TEST: Added block", "block", request.Height, "peer", request.PeerID) - }() - } - } - - pool.Stop() -} - -func TestTimeout(t *testing.T) { - start := 42 - peers := makePeers(10, start+1, 1000) - timeoutsCh := make(chan string, 100) - requestsCh := make(chan BlockRequest, 100) - pool := NewBlockPool(start, requestsCh, timeoutsCh) - pool.Start() - - for _, peer := range peers { - log.Info("Peer", "id", peer.id) - } - - // Introduce each peer. - go func() { - for _, peer := range peers { - pool.SetPeerHeight(peer.id, peer.height) - } - }() - - // Start a goroutine to pull blocks - go func() { - for { - if !pool.IsRunning() { - return - } - first, second := pool.PeekTwoBlocks() - if first != nil && second != nil { - pool.PopRequest() - } else { - time.Sleep(1 * time.Second) - } - } - }() - - // Pull from channels - counter := 0 - timedOut := map[string]struct{}{} - for { - select { - case peerID := <-timeoutsCh: - log.Info("Timeout", "peerID", peerID) - if _, ok := timedOut[peerID]; !ok { - counter++ - if counter == len(peers) { - return // Done! - } - } - case request := <-requestsCh: - log.Info("TEST: Pulled new BlockRequest", "request", request) - } - } - - pool.Stop() -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go deleted file mode 100644 index 0ca0e2f7..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go +++ /dev/null @@ -1,339 +0,0 @@ -package blockchain - -import ( - "bytes" - "errors" - "fmt" - "reflect" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - BlockchainChannel = byte(0x40) - defaultChannelCapacity = 100 - defaultSleepIntervalMS = 500 - trySyncIntervalMS = 100 - // stop syncing when last block's time is - // within this much of the system time. - // stopSyncingDurationMinutes = 10 - - // ask for best height every 10s - statusUpdateIntervalSeconds = 10 - // check if we should switch to consensus reactor - switchToConsensusIntervalSeconds = 1 - maxBlockchainResponseSize = types.MaxBlockSize + 2 -) - -type consensusReactor interface { - // for when we switch from blockchain reactor and fast sync to - // the consensus machine - SwitchToConsensus(*sm.State) -} - -// BlockchainReactor handles long-term catchup syncing. -type BlockchainReactor struct { - p2p.BaseReactor - - sw *p2p.Switch - state *sm.State - proxyAppCtx proxy.AppContext // same as consensus.proxyAppCtx - store *BlockStore - pool *BlockPool - sync bool - requestsCh chan BlockRequest - timeoutsCh chan string - lastBlock *types.Block - - evsw events.Fireable -} - -func NewBlockchainReactor(state *sm.State, proxyAppCtx proxy.AppContext, store *BlockStore, sync bool) *BlockchainReactor { - if state.LastBlockHeight != store.Height() && - state.LastBlockHeight != store.Height()-1 { // XXX double check this logic. - PanicSanity(Fmt("state (%v) and store (%v) height mismatch", state.LastBlockHeight, store.Height())) - } - requestsCh := make(chan BlockRequest, defaultChannelCapacity) - timeoutsCh := make(chan string, defaultChannelCapacity) - pool := NewBlockPool( - store.Height()+1, - requestsCh, - timeoutsCh, - ) - bcR := &BlockchainReactor{ - state: state, - proxyAppCtx: proxyAppCtx, - store: store, - pool: pool, - sync: sync, - requestsCh: requestsCh, - timeoutsCh: timeoutsCh, - } - bcR.BaseReactor = *p2p.NewBaseReactor(log, "BlockchainReactor", bcR) - return bcR -} - -func (bcR *BlockchainReactor) OnStart() error { - bcR.BaseReactor.OnStart() - if bcR.sync { - _, err := bcR.pool.Start() - if err != nil { - return err - } - go bcR.poolRoutine() - } - return nil -} - -func (bcR *BlockchainReactor) OnStop() { - bcR.BaseReactor.OnStop() - bcR.pool.Stop() -} - -// Implements Reactor -func (bcR *BlockchainReactor) GetChannels() []*p2p.ChannelDescriptor { - return []*p2p.ChannelDescriptor{ - &p2p.ChannelDescriptor{ - ID: BlockchainChannel, - Priority: 5, - SendQueueCapacity: 100, - }, - } -} - -// Implements Reactor -func (bcR *BlockchainReactor) AddPeer(peer *p2p.Peer) { - // Send peer our state. - peer.Send(BlockchainChannel, &bcStatusResponseMessage{bcR.store.Height()}) -} - -// Implements Reactor -func (bcR *BlockchainReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { - // Remove peer from the pool. - bcR.pool.RemovePeer(peer.Key) -} - -// Implements Reactor -func (bcR *BlockchainReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { - _, msg, err := DecodeMessage(msgBytes) - if err != nil { - log.Warn("Error decoding message", "error", err) - return - } - - log.Notice("Received message", "src", src, "chID", chID, "msg", msg) - - switch msg := msg.(type) { - case *bcBlockRequestMessage: - // Got a request for a block. Respond with block if we have it. - block := bcR.store.LoadBlock(msg.Height) - if block != nil { - msg := &bcBlockResponseMessage{Block: block} - queued := src.TrySend(BlockchainChannel, msg) - if !queued { - // queue is full, just ignore. - } - } else { - // TODO peer is asking for things we don't have. - } - case *bcBlockResponseMessage: - // Got a block. - bcR.pool.AddBlock(src.Key, msg.Block, len(msgBytes)) - case *bcStatusRequestMessage: - // Send peer our state. - queued := src.TrySend(BlockchainChannel, &bcStatusResponseMessage{bcR.store.Height()}) - if !queued { - // sorry - } - case *bcStatusResponseMessage: - // Got a peer status. Unverified. - bcR.pool.SetPeerHeight(src.Key, msg.Height) - default: - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } -} - -// Handle messages from the poolReactor telling the reactor what to do. -// NOTE: Don't sleep in the FOR_LOOP or otherwise slow it down! -// (Except for the SYNC_LOOP, which is the primary purpose and must be synchronous.) -func (bcR *BlockchainReactor) poolRoutine() { - - trySyncTicker := time.NewTicker(trySyncIntervalMS * time.Millisecond) - statusUpdateTicker := time.NewTicker(statusUpdateIntervalSeconds * time.Second) - switchToConsensusTicker := time.NewTicker(switchToConsensusIntervalSeconds * time.Second) - -FOR_LOOP: - for { - select { - case request := <-bcR.requestsCh: // chan BlockRequest - peer := bcR.Switch.Peers().Get(request.PeerID) - if peer == nil { - continue FOR_LOOP // Peer has since been disconnected. - } - msg := &bcBlockRequestMessage{request.Height} - queued := peer.TrySend(BlockchainChannel, msg) - if !queued { - // We couldn't make the request, send-queue full. - // The pool handles timeouts, just let it go. - continue FOR_LOOP - } - case peerID := <-bcR.timeoutsCh: // chan string - // Peer timed out. - peer := bcR.Switch.Peers().Get(peerID) - if peer != nil { - bcR.Switch.StopPeerForError(peer, errors.New("BlockchainReactor Timeout")) - } - case _ = <-statusUpdateTicker.C: - // ask for status updates - go bcR.BroadcastStatusRequest() - case _ = <-switchToConsensusTicker.C: - height, numPending := bcR.pool.GetStatus() - outbound, inbound, _ := bcR.Switch.NumPeers() - log.Info("Consensus ticker", "numPending", numPending, "total", len(bcR.pool.requesters), - "outbound", outbound, "inbound", inbound) - if bcR.pool.IsCaughtUp() { - log.Notice("Time to switch to consensus reactor!", "height", height) - bcR.pool.Stop() - - conR := bcR.Switch.Reactor("CONSENSUS").(consensusReactor) - conR.SwitchToConsensus(bcR.state) - - break FOR_LOOP - } - case _ = <-trySyncTicker.C: // chan time - // This loop can be slow as long as it's doing syncing work. - SYNC_LOOP: - for i := 0; i < 10; i++ { - // See if there are any blocks to sync. - first, second := bcR.pool.PeekTwoBlocks() - //log.Info("TrySync peeked", "first", first, "second", second) - if first == nil || second == nil { - // We need both to sync the first block. - break SYNC_LOOP - } - firstParts := first.MakePartSet() - firstPartsHeader := firstParts.Header() - // Finally, verify the first block using the second's validation. - err := bcR.state.Validators.VerifyValidation( - bcR.state.ChainID, first.Hash(), firstPartsHeader, first.Height, second.LastValidation) - if err != nil { - log.Info("error in validation", "error", err) - bcR.pool.RedoRequest(first.Height) - break SYNC_LOOP - } else { - bcR.pool.PopRequest() - err := bcR.state.ExecBlock(bcR.proxyAppCtx, first, firstPartsHeader) - if err != nil { - // TODO This is bad, are we zombie? - PanicQ(Fmt("Failed to process committed block: %v", err)) - } - err = bcR.state.Commit(bcR.proxyAppCtx) - if err != nil { - // TODO Handle gracefully. - PanicQ(Fmt("Failed to commit block at application: %v", err)) - } - bcR.store.SaveBlock(first, firstParts, second.LastValidation) - bcR.state.Save() - } - } - continue FOR_LOOP - case <-bcR.Quit: - break FOR_LOOP - } - } -} - -func (bcR *BlockchainReactor) BroadcastStatusResponse() error { - bcR.Switch.Broadcast(BlockchainChannel, &bcStatusResponseMessage{bcR.store.Height()}) - return nil -} - -func (bcR *BlockchainReactor) BroadcastStatusRequest() error { - bcR.Switch.Broadcast(BlockchainChannel, &bcStatusRequestMessage{bcR.store.Height()}) - return nil -} - -// implements events.Eventable -func (bcR *BlockchainReactor) SetFireable(evsw events.Fireable) { - bcR.evsw = evsw -} - -//----------------------------------------------------------------------------- -// Messages - -const ( - msgTypeBlockRequest = byte(0x10) - msgTypeBlockResponse = byte(0x11) - msgTypeStatusResponse = byte(0x20) - msgTypeStatusRequest = byte(0x21) -) - -type BlockchainMessage interface{} - -var _ = wire.RegisterInterface( - struct{ BlockchainMessage }{}, - wire.ConcreteType{&bcBlockRequestMessage{}, msgTypeBlockRequest}, - wire.ConcreteType{&bcBlockResponseMessage{}, msgTypeBlockResponse}, - wire.ConcreteType{&bcStatusResponseMessage{}, msgTypeStatusResponse}, - wire.ConcreteType{&bcStatusRequestMessage{}, msgTypeStatusRequest}, -) - -// TODO: ensure that bz is completely read. -func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) { - msgType = bz[0] - n := int(0) - r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, maxBlockchainResponseSize, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage - if err != nil && n != len(bz) { - err = errors.New("DecodeMessage() had bytes left over.") - } - return -} - -//------------------------------------- - -type bcBlockRequestMessage struct { - Height int -} - -func (m *bcBlockRequestMessage) String() string { - return fmt.Sprintf("[bcBlockRequestMessage %v]", m.Height) -} - -//------------------------------------- - -// NOTE: keep up-to-date with maxBlockchainResponseSize -type bcBlockResponseMessage struct { - Block *types.Block -} - -func (m *bcBlockResponseMessage) String() string { - return fmt.Sprintf("[bcBlockResponseMessage %v]", m.Block.Height) -} - -//------------------------------------- - -type bcStatusRequestMessage struct { - Height int -} - -func (m *bcStatusRequestMessage) String() string { - return fmt.Sprintf("[bcStatusRequestMessage %v]", m.Height) -} - -//------------------------------------- - -type bcStatusResponseMessage struct { - Height int -} - -func (m *bcStatusResponseMessage) String() string { - return fmt.Sprintf("[bcStatusResponseMessage %v]", m.Height) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go deleted file mode 100644 index de9a6571..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go +++ /dev/null @@ -1,231 +0,0 @@ -package blockchain - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -/* -Simple low level store for blocks. - -There are three types of information stored: - - BlockMeta: Meta information about each block - - Block part: Parts of each block, aggregated w/ PartSet - - Validation: The Validation part of each block, for gossiping precommit votes - -Currently the precommit signatures are duplicated in the Block parts as -well as the Validation. In the future this may change, perhaps by moving -the Validation data outside the Block. - -Panics indicate probable corruption in the data -*/ -type BlockStore struct { - height int - db dbm.DB -} - -func NewBlockStore(db dbm.DB) *BlockStore { - bsjson := LoadBlockStoreStateJSON(db) - return &BlockStore{ - height: bsjson.Height, - db: db, - } -} - -// Height() returns the last known contiguous block height. -func (bs *BlockStore) Height() int { - return bs.height -} - -func (bs *BlockStore) GetReader(key []byte) io.Reader { - bytez := bs.db.Get(key) - if bytez == nil { - return nil - } - return bytes.NewReader(bytez) -} - -func (bs *BlockStore) LoadBlock(height int) *types.Block { - var n int - var err error - r := bs.GetReader(calcBlockMetaKey(height)) - if r == nil { - return nil - } - meta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta) - if err != nil { - PanicCrisis(Fmt("Error reading block meta: %v", err)) - } - bytez := []byte{} - for i := 0; i < meta.PartsHeader.Total; i++ { - part := bs.LoadBlockPart(height, i) - bytez = append(bytez, part.Bytes...) - } - block := wire.ReadBinary(&types.Block{}, bytes.NewReader(bytez), 0, &n, &err).(*types.Block) - if err != nil { - PanicCrisis(Fmt("Error reading block: %v", err)) - } - return block -} - -func (bs *BlockStore) LoadBlockPart(height int, index int) *types.Part { - var n int - var err error - r := bs.GetReader(calcBlockPartKey(height, index)) - if r == nil { - return nil - } - part := wire.ReadBinary(&types.Part{}, r, 0, &n, &err).(*types.Part) - if err != nil { - PanicCrisis(Fmt("Error reading block part: %v", err)) - } - return part -} - -func (bs *BlockStore) LoadBlockMeta(height int) *types.BlockMeta { - var n int - var err error - r := bs.GetReader(calcBlockMetaKey(height)) - if r == nil { - return nil - } - meta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta) - if err != nil { - PanicCrisis(Fmt("Error reading block meta: %v", err)) - } - return meta -} - -// The +2/3 and other Precommit-votes for block at `height`. -// This Validation comes from block.LastValidation for `height+1`. -func (bs *BlockStore) LoadBlockValidation(height int) *types.Validation { - var n int - var err error - r := bs.GetReader(calcBlockValidationKey(height)) - if r == nil { - return nil - } - validation := wire.ReadBinary(&types.Validation{}, r, 0, &n, &err).(*types.Validation) - if err != nil { - PanicCrisis(Fmt("Error reading validation: %v", err)) - } - return validation -} - -// NOTE: the Precommit-vote heights are for the block at `height` -func (bs *BlockStore) LoadSeenValidation(height int) *types.Validation { - var n int - var err error - r := bs.GetReader(calcSeenValidationKey(height)) - if r == nil { - return nil - } - validation := wire.ReadBinary(&types.Validation{}, r, 0, &n, &err).(*types.Validation) - if err != nil { - PanicCrisis(Fmt("Error reading validation: %v", err)) - } - return validation -} - -// blockParts: Must be parts of the block -// seenValidation: The +2/3 precommits that were seen which committed at height. -// If all the nodes restart after committing a block, -// we need this to reload the precommits to catch-up nodes to the -// most recent height. Otherwise they'd stall at H-1. -func (bs *BlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenValidation *types.Validation) { - height := block.Height - if height != bs.height+1 { - PanicSanity(Fmt("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.height+1, height)) - } - if !blockParts.IsComplete() { - PanicSanity(Fmt("BlockStore can only save complete block part sets")) - } - - // Save block meta - meta := types.NewBlockMeta(block, blockParts) - metaBytes := wire.BinaryBytes(meta) - bs.db.Set(calcBlockMetaKey(height), metaBytes) - - // Save block parts - for i := 0; i < blockParts.Total(); i++ { - bs.saveBlockPart(height, i, blockParts.GetPart(i)) - } - - // Save block validation (duplicate and separate from the Block) - blockValidationBytes := wire.BinaryBytes(block.LastValidation) - bs.db.Set(calcBlockValidationKey(height-1), blockValidationBytes) - - // Save seen validation (seen +2/3 precommits for block) - seenValidationBytes := wire.BinaryBytes(seenValidation) - bs.db.Set(calcSeenValidationKey(height), seenValidationBytes) - - // Save new BlockStoreStateJSON descriptor - BlockStoreStateJSON{Height: height}.Save(bs.db) - - // Done! - bs.height = height -} - -func (bs *BlockStore) saveBlockPart(height int, index int, part *types.Part) { - if height != bs.height+1 { - PanicSanity(Fmt("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.height+1, height)) - } - partBytes := wire.BinaryBytes(part) - bs.db.Set(calcBlockPartKey(height, index), partBytes) -} - -//----------------------------------------------------------------------------- - -func calcBlockMetaKey(height int) []byte { - return []byte(fmt.Sprintf("H:%v", height)) -} - -func calcBlockPartKey(height int, partIndex int) []byte { - return []byte(fmt.Sprintf("P:%v:%v", height, partIndex)) -} - -func calcBlockValidationKey(height int) []byte { - return []byte(fmt.Sprintf("V:%v", height)) -} - -func calcSeenValidationKey(height int) []byte { - return []byte(fmt.Sprintf("SV:%v", height)) -} - -//----------------------------------------------------------------------------- - -var blockStoreKey = []byte("blockStore") - -type BlockStoreStateJSON struct { - Height int -} - -func (bsj BlockStoreStateJSON) Save(db dbm.DB) { - bytes, err := json.Marshal(bsj) - if err != nil { - PanicSanity(Fmt("Could not marshal state bytes: %v", err)) - } - db.Set(blockStoreKey, bytes) -} - -func LoadBlockStoreStateJSON(db dbm.DB) BlockStoreStateJSON { - bytes := db.Get(blockStoreKey) - if bytes == nil { - return BlockStoreStateJSON{ - Height: 0, - } - } - bsj := BlockStoreStateJSON{} - err := json.Unmarshal(bytes, &bsj) - if err != nil { - PanicCrisis(Fmt("Could not unmarshal bytes: %X", bytes)) - } - return bsj -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/config.go deleted file mode 100644 index 288cf250..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/config.go +++ /dev/null @@ -1,89 +0,0 @@ -package tendermint - -import ( - "os" - "path" - "strings" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -func getTMRoot(rootDir string) string { - if rootDir == "" { - rootDir = os.Getenv("TMROOT") - } - if rootDir == "" { - rootDir = os.Getenv("HOME") + "/.tendermint" - } - return rootDir -} - -func initTMRoot(rootDir string) { - rootDir = getTMRoot(rootDir) - EnsureDir(rootDir, 0700) - - configFilePath := path.Join(rootDir, "config.toml") - - // Write default config file if missing. - if !FileExists(configFilePath) { - // Ask user for moniker - // moniker := cfg.Prompt("Type hostname: ", "anonymous") - MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644) - } -} - -func GetConfig(rootDir string) cfg.Config { - rootDir = getTMRoot(rootDir) - initTMRoot(rootDir) - - configFilePath := path.Join(rootDir, "config.toml") - mapConfig, err := cfg.ReadMapConfigFromFile(configFilePath) - if err != nil { - Exit(Fmt("Could not read config: %v", err)) - } - - // Set defaults or panic - if mapConfig.IsSet("chain_id") { - Exit("Cannot set 'chain_id' via config.toml") - } - if mapConfig.IsSet("revision_file") { - Exit("Cannot set 'revision_file' via config.toml. It must match what's in the Makefile") - } - mapConfig.SetRequired("chain_id") // blows up if you try to use it before setting. - mapConfig.SetDefault("genesis_file", rootDir+"/genesis.json") - mapConfig.SetDefault("proxy_app", "tcp://127.0.0.1:46658") - mapConfig.SetDefault("moniker", "anonymous") - mapConfig.SetDefault("node_laddr", "0.0.0.0:46656") - // mapConfig.SetDefault("seeds", "goldenalchemist.chaintest.net:46656") - mapConfig.SetDefault("fast_sync", true) - mapConfig.SetDefault("skip_upnp", false) - mapConfig.SetDefault("addrbook_file", rootDir+"/addrbook.json") - mapConfig.SetDefault("priv_validator_file", rootDir+"/priv_validator.json") - mapConfig.SetDefault("db_backend", "leveldb") - mapConfig.SetDefault("db_dir", rootDir+"/data") - mapConfig.SetDefault("vm_log", true) - mapConfig.SetDefault("log_level", "info") - mapConfig.SetDefault("rpc_laddr", "0.0.0.0:46657") - mapConfig.SetDefault("prof_laddr", "") - mapConfig.SetDefault("revision_file", rootDir+"/revision") - return mapConfig -} - -var defaultConfigTmpl = `# This is a TOML config file. -# For more information, see https://github.com/toml-lang/toml - -proxy_app = "tcp://127.0.0.1:46658" -moniker = "__MONIKER__" -node_laddr = "0.0.0.0:46656" -seeds = "" -fast_sync = true -db_backend = "leveldb" -log_level = "notice" -rpc_laddr = "0.0.0.0:46657" -` - -func defaultConfig(moniker string) (defaultConfig string) { - defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1) - return -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json deleted file mode 100644 index eca00696..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "chain_id": "tendermint_testnet_11.c", - "accounts": [ - { - "address": "9FCBA7F840A0BFEBBE755E853C9947270A912D04", - "amount": 1991999998000000 - }, - { - "address": "964B1493BBE3312278B7DEB94C39149F7899A345", - "amount": 100000000000000 - }, - { - "address": "B9FA4AB462B9C6BF6A62DB4AE77C9E7087209A04", - "amount": 1000000000000 - }, - { - "address": "F171824590D69386F709E7B6704B369C5A370D60", - "amount": 1000000000000 - }, - { - "address": "56EFE746A13D9A6054AC89C3E2A361C2DB8B9EAE", - "amount": 1000000000000 - }, - { - "address": "7C2E032D8407EDF66A04D88CF0E1D9B15D98AE2D", - "amount": 1000000000000 - }, - { - "address": "636EF5823E082AD66EBC203FD4DFB1031F0C61CA", - "amount": 1000000000000 - }, - { - "address": "9008419E6351360A59B124E707E4CA2A5BFB9BE6", - "amount": 1000000000000 - }, - { - "address": "C78F48919B8A4030AD3E5ED643F8D2302E41953D", - "amount": 1000000000000 - }, - { - "address": "5290AC90CE2422DDC3F91F6A246F7E3C542EA51A", - "amount": 1000000000000 - }, - { - "address": "A88A61069B6660F30F65E8786AFDD4F1D8F625E9", - "amount": 1000000 - }, - { - "address": "EE2EE9247973B4AFC3867CFE5F415410AC251B61", - "amount": 1000000 - } - ], - "validators": [ - { - "pub_key": [1, "178EC6008A4364508979C70CBF100BD4BCBAA12DDE6251F5F486B4FD09014F06"], - "amount": 100000000000 - }, - { - "pub_key": [1, "2A77777CC51467DE42350D4A8F34720D527734189BE64C7A930DD169E1FED3C6"], - "amount": 100000000000 - }, - { - "pub_key": [1, "3718E69D09B11B3AD3FA31AEF07EC416D2AEED241CACE7B0F30AE9803FFB0F08"], - "amount": 100000000000 - }, - { - "pub_key": [1, "C6B0440DEACD1E4CF1C736CEB8E38E788B700BA2B2045A55CB657A455CF5F889"], - "amount": 100000000000 - }, - { - "pub_key": [1, "3BA1190D54F91EFBF8B0125F7EC116AD4BA2894B6EE38564A5D5FD3230D91F7B"], - "amount": 100000000000 - } - ] -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/logrotate.config b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/logrotate.config deleted file mode 100644 index 73eaf74e..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/logrotate.config +++ /dev/null @@ -1,22 +0,0 @@ -// If you wanted to use logrotate, I suppose this might be the config you want. -// Instead, I'll just write our own, that way we don't need sudo to install. - -$HOME/.tendermint/logs/tendermint.log { - missingok - notifempty - rotate 12 - daily - size 10M - compress - delaycompress -} - -$HOME/.barak/logs/barak.log { - missingok - notifempty - rotate 12 - weekly - size 10M - compress - delaycompress -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test/config.go deleted file mode 100644 index 01a54da1..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test/config.go +++ /dev/null @@ -1,142 +0,0 @@ -// Import this in all *_test.go files to initialize ~/.tendermint_test. - -package tendermint_test - -import ( - "os" - "path" - "strings" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -func init() { - // Creates ~/.tendermint_test/* - config := GetConfig("") - cfg.ApplyConfig(config) -} - -func getTMRoot(rootDir string) string { - if rootDir == "" { - rootDir = os.Getenv("HOME") + "/.tendermint_test" - } - return rootDir -} - -func initTMRoot(rootDir string) { - rootDir = getTMRoot(rootDir) - EnsureDir(rootDir, 0700) - - configFilePath := path.Join(rootDir, "config.toml") - genesisFilePath := path.Join(rootDir, "genesis.json") - - // Write default config file if missing. - if !FileExists(configFilePath) { - // Ask user for moniker - // moniker := cfg.Prompt("Type hostname: ", "anonymous") - MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644) - } - if !FileExists(genesisFilePath) { - MustWriteFile(genesisFilePath, []byte(defaultGenesis), 0644) - } -} - -func GetConfig(rootDir string) cfg.Config { - rootDir = getTMRoot(rootDir) - initTMRoot(rootDir) - - configFilePath := path.Join(rootDir, "config.toml") - mapConfig, err := cfg.ReadMapConfigFromFile(configFilePath) - if err != nil { - Exit(Fmt("Could not read config: %v", err)) - } - - // Set defaults or panic - if mapConfig.IsSet("chain_id") { - Exit("Cannot set 'chain_id' via config.toml") - } - mapConfig.SetDefault("chain_id", "tendermint_test") - mapConfig.SetDefault("genesis_file", rootDir+"/genesis.json") - mapConfig.SetDefault("proxy_app", "tcp://127.0.0.1:36658") - mapConfig.SetDefault("moniker", "anonymous") - mapConfig.SetDefault("node_laddr", "0.0.0.0:36656") - mapConfig.SetDefault("fast_sync", false) - mapConfig.SetDefault("skip_upnp", true) - mapConfig.SetDefault("addrbook_file", rootDir+"/addrbook.json") - mapConfig.SetDefault("priv_validator_file", rootDir+"/priv_validator.json") - mapConfig.SetDefault("db_backend", "memdb") - mapConfig.SetDefault("db_dir", rootDir+"/data") - mapConfig.SetDefault("log_level", "debug") - mapConfig.SetDefault("vm_log", true) - mapConfig.SetDefault("rpc_laddr", "0.0.0.0:36657") - mapConfig.SetDefault("prof_laddr", "") - mapConfig.SetDefault("revision_file", rootDir+"/revision") - return mapConfig -} - -var defaultConfigTmpl = `# This is a TOML config file. -# For more information, see https://github.com/toml-lang/toml - -proxy_app = "tcp://127.0.0.1:36658" -moniker = "__MONIKER__" -node_laddr = "0.0.0.0:36656" -seeds = "" -fast_sync = false -db_backend = "memdb" -log_level = "debug" -rpc_laddr = "0.0.0.0:36657" -` - -func defaultConfig(moniker string) (defaultConfig string) { - defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1) - return -} - -// priv keys generated deterministically eg rpc/tests/helpers.go -var defaultGenesis = `{ - "chain_id" : "tendermint_test", - "accounts": [ - { - "address": "E9B5D87313356465FAE33C406CE2C2979DE60BCB", - "amount": 200000000 - }, - { - "address": "DFE4AFFA4CEE17CD01CB9E061D77C3ECED29BD88", - "amount": 200000000 - }, - { - "address": "F60D30722E7B497FA532FB3207C3FB29C31B1992", - "amount": 200000000 - }, - { - "address": "336CB40A5EB92E496E19B74FDFF2BA017C877FD6", - "amount": 200000000 - }, - { - "address": "D218F0F439BF0384F6F5EF8D0F8B398D941BD1DC", - "amount": 200000000 - } - ], - "validators": [ - { - "pub_key": [1, "583779C3BFA3F6C7E23C7D830A9C3D023A216B55079AD38BFED1207B94A19548"], - "amount": 1000000, - "unbond_to": [ - { - "address": "E9B5D87313356465FAE33C406CE2C2979DE60BCB", - "amount": 100000 - } - ] - } - ] -}` - -var defaultPrivValidator = `{ - "address": "1D7A91CB32F758A02EBB9BE1FB6F8DEE56F90D42", - "pub_key": [1,"06FBAC4E285285D1D91FCBC7E91C780ADA11516F67462340B3980CE2B94940E8"], - "priv_key": [1,"C453604BD6480D5538B4C6FD2E3E314B5BCE518D75ADE4DA3DA85AB8ADFD819606FBAC4E285285D1D91FCBC7E91C780ADA11516F67462340B3980CE2B94940E8"], - "last_height":0, - "last_round":0, - "last_step":0 -}` diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/README.md b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/README.md deleted file mode 100644 index 46d33032..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/README.md +++ /dev/null @@ -1,4 +0,0 @@ -The core consensus algorithm. - -* state.go - The state machine as detailed in the whitepaper -* reactor.go - A reactor that connects the state machine to the gossip network diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/common_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/common_test.go deleted file mode 100644 index f5860375..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/common_test.go +++ /dev/null @@ -1,335 +0,0 @@ -package consensus - -import ( - "bytes" - "fmt" - "sort" - "testing" - "time" - - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - mempl "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" - - "github.com/tendermint/tmsp/example" -) - -var chainID string - -func init() { - chainID = config.GetString("chain_id") -} - -type validatorStub struct { - Height int - Round int - *types.PrivValidator -} - -func NewValidatorStub(privValidator *types.PrivValidator) *validatorStub { - return &validatorStub{ - PrivValidator: privValidator, - } -} - -func (vs *validatorStub) signVote(voteType byte, hash []byte, header types.PartSetHeader) (*types.Vote, error) { - vote := &types.Vote{ - Height: vs.Height, - Round: vs.Round, - Type: voteType, - BlockHash: hash, - BlockPartsHeader: header, - } - err := vs.PrivValidator.SignVote(chainID, vote) - return vote, err -} - -// convenienve function for testing -func signVote(vs *validatorStub, voteType byte, hash []byte, header types.PartSetHeader) *types.Vote { - v, err := vs.signVote(voteType, hash, header) - if err != nil { - panic(fmt.Errorf("failed to sign vote: %v", err)) - } - return v -} - -// create proposal block from cs1 but sign it with vs -func decideProposal(cs1 *ConsensusState, cs2 *validatorStub, height, round int) (proposal *types.Proposal, block *types.Block) { - block, blockParts := cs1.createProposalBlock() - if block == nil { // on error - panic("error creating proposal block") - } - - // Make proposal - proposal = types.NewProposal(height, round, blockParts.Header(), cs1.Votes.POLRound()) - if err := cs2.SignProposal(chainID, proposal); err != nil { - panic(err) - } - return -} - -//------------------------------------------------------------------------------- -// utils - -func nilRound(t *testing.T, startRound int, cs1 *ConsensusState, vss ...*validatorStub) { - height, round := cs1.Height, cs1.Round - - waitFor(t, cs1, height, round, RoundStepPrevote) - - signAddVoteToFromMany(types.VoteTypePrevote, cs1, nil, cs1.ProposalBlockParts.Header(), vss...) - - waitFor(t, cs1, height, round, RoundStepPrecommit) - - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, cs1.ProposalBlockParts.Header(), vss...) - - waitFor(t, cs1, height, round+1, RoundStepNewRound) -} - -// NOTE: this switches the propser as far as `perspectiveOf` is concerned, -// but for simplicity we return a block it generated. -func changeProposer(t *testing.T, perspectiveOf *ConsensusState, newProposer *validatorStub) *types.Block { - _, v1 := perspectiveOf.Validators.GetByAddress(perspectiveOf.privValidator.Address) - v1.Accum, v1.VotingPower = 0, 0 - if updated := perspectiveOf.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - _, v2 := perspectiveOf.Validators.GetByAddress(newProposer.Address) - v2.Accum, v2.VotingPower = 100, 100 - if updated := perspectiveOf.Validators.Update(v2); !updated { - t.Fatal("failed to update validator") - } - - // make the proposal - propBlock, _ := perspectiveOf.createProposalBlock() - if propBlock == nil { - t.Fatal("Failed to create proposal block with cs2") - } - return propBlock -} - -func fixVotingPower(t *testing.T, cs1 *ConsensusState, addr2 []byte) { - _, v1 := cs1.Validators.GetByAddress(cs1.privValidator.Address) - _, v2 := cs1.Validators.GetByAddress(addr2) - v1.Accum, v1.VotingPower = v2.Accum, v2.VotingPower - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } -} - -func addVoteToFromMany(to *ConsensusState, votes []*types.Vote, froms ...*validatorStub) { - if len(votes) != len(froms) { - panic("len(votes) and len(froms) must match") - } - for i, from := range froms { - addVoteToFrom(to, from, votes[i]) - } -} - -func addVoteToFrom(to *ConsensusState, from *validatorStub, vote *types.Vote) { - valIndex, _ := to.Validators.GetByAddress(from.PrivValidator.Address) - added, err := to.TryAddVote(valIndex, vote, "") - if _, ok := err.(*types.ErrVoteConflictingSignature); ok { - // let it fly - } else if !added { - fmt.Println("to, from, vote:", to.Height, from.Height, vote.Height) - panic(fmt.Sprintln("Failed to add vote. Err:", err)) - } else if err != nil { - panic(fmt.Sprintln("Failed to add vote:", err)) - } -} - -func signVoteMany(voteType byte, hash []byte, header types.PartSetHeader, vss ...*validatorStub) []*types.Vote { - votes := make([]*types.Vote, len(vss)) - for i, vs := range vss { - votes[i] = signVote(vs, voteType, hash, header) - } - return votes -} - -// add vote to one cs from another -func signAddVoteToFromMany(voteType byte, to *ConsensusState, hash []byte, header types.PartSetHeader, froms ...*validatorStub) { - for _, from := range froms { - vote := signVote(from, voteType, hash, header) - addVoteToFrom(to, from, vote) - } -} - -func signAddVoteToFrom(voteType byte, to *ConsensusState, from *validatorStub, hash []byte, header types.PartSetHeader) *types.Vote { - vote := signVote(from, voteType, hash, header) - addVoteToFrom(to, from, vote) - return vote -} - -func ensureNoNewStep(t *testing.T, cs *ConsensusState) { - timeout := time.NewTicker(2 * time.Second) - select { - case <-timeout.C: - break - case <-cs.NewStepCh(): - panic("We should be stuck waiting for more votes, not moving to the next step") - } -} - -func ensureNewStep(t *testing.T, cs *ConsensusState) *RoundState { - timeout := time.NewTicker(2 * time.Second) - select { - case <-timeout.C: - panic("We should have gone to the next step, not be stuck waiting") - case rs := <-cs.NewStepCh(): - return rs - } -} - -func waitFor(t *testing.T, cs *ConsensusState, height int, round int, step RoundStepType) { - for { - rs := ensureNewStep(t, cs) - if CompareHRS(rs.Height, rs.Round, rs.Step, height, round, step) < 0 { - continue - } else { - break - } - } -} - -func validatePrevote(t *testing.T, cs *ConsensusState, round int, privVal *validatorStub, blockHash []byte) { - prevotes := cs.Votes.Prevotes(round) - var vote *types.Vote - if vote = prevotes.GetByAddress(privVal.Address); vote == nil { - panic("Failed to find prevote from validator") - } - if blockHash == nil { - if vote.BlockHash != nil { - panic(fmt.Sprintf("Expected prevote to be for nil, got %X", vote.BlockHash)) - } - } else { - if !bytes.Equal(vote.BlockHash, blockHash) { - panic(fmt.Sprintf("Expected prevote to be for %X, got %X", blockHash, vote.BlockHash)) - } - } -} - -func incrementHeight(vss ...*validatorStub) { - for _, vs := range vss { - vs.Height += 1 - } -} - -func incrementRound(vss ...*validatorStub) { - for _, vs := range vss { - vs.Round += 1 - } -} - -func validatePrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound int, privVal *validatorStub, votedBlockHash, lockedBlockHash []byte) { - precommits := cs.Votes.Precommits(thisRound) - var vote *types.Vote - if vote = precommits.GetByAddress(privVal.Address); vote == nil { - panic("Failed to find precommit from validator") - } - - if votedBlockHash == nil { - if vote.BlockHash != nil { - panic("Expected precommit to be for nil") - } - } else { - if !bytes.Equal(vote.BlockHash, votedBlockHash) { - panic("Expected precommit to be for proposal block") - } - } - - if lockedBlockHash == nil { - if cs.LockedRound != lockRound || cs.LockedBlock != nil { - panic(fmt.Sprintf("Expected to be locked on nil at round %d. Got locked at round %d with block %v", lockRound, cs.LockedRound, cs.LockedBlock)) - } - } else { - if cs.LockedRound != lockRound || !bytes.Equal(cs.LockedBlock.Hash(), lockedBlockHash) { - panic(fmt.Sprintf("Expected block to be locked on round %d, got %d. Got locked block %X, expected %X", lockRound, cs.LockedRound, cs.LockedBlock.Hash(), lockedBlockHash)) - } - } - -} - -func validatePrevoteAndPrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound int, privVal *validatorStub, votedBlockHash, lockedBlockHash []byte) { - // verify the prevote - validatePrevote(t, cs, thisRound, privVal, votedBlockHash) - // verify precommit - cs.mtx.Lock() - validatePrecommit(t, cs, thisRound, lockRound, privVal, votedBlockHash, lockedBlockHash) - cs.mtx.Unlock() -} - -func simpleConsensusState(nValidators int) (*ConsensusState, []*validatorStub) { - // Get State - state, privVals := randGenesisState(nValidators, false, 10) - - // fmt.Println(state.Validators) - - vss := make([]*validatorStub, nValidators) - - // make consensus state for lead validator - - // Get BlockStore - blockDB := dbm.NewMemDB() - blockStore := bc.NewBlockStore(blockDB) - - // one for mempool, one for consensus - app := example.NewCounterApplication() - appCMem := app.Open() - appCCon := app.Open() - proxyAppCtxMem := proxy.NewLocalAppContext(appCMem) - proxyAppCtxCon := proxy.NewLocalAppContext(appCCon) - - // Make Mempool - mempool := mempl.NewMempool(proxyAppCtxMem) - - // Make ConsensusReactor - cs := NewConsensusState(state, proxyAppCtxCon, blockStore, mempool) - cs.SetPrivValidator(privVals[0]) - - evsw := events.NewEventSwitch() - cs.SetFireable(evsw) - - // read off the NewHeightStep - <-cs.NewStepCh() - - for i := 0; i < nValidators; i++ { - vss[i] = NewValidatorStub(privVals[i]) - } - // since cs1 starts at 1 - incrementHeight(vss[1:]...) - - return cs, vss -} - -func randGenesisState(numValidators int, randPower bool, minPower int64) (*sm.State, []*types.PrivValidator) { - db := dbm.NewMemDB() - genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower) - s0 := sm.MakeGenesisState(db, genDoc) - s0.Save() - return s0, privValidators -} - -func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.GenesisDoc, []*types.PrivValidator) { - validators := make([]types.GenesisValidator, numValidators) - privValidators := make([]*types.PrivValidator, numValidators) - for i := 0; i < numValidators; i++ { - val, privVal := types.RandValidator(randPower, minPower) - validators[i] = types.GenesisValidator{ - PubKey: val.PubKey, - Amount: val.VotingPower, - } - privValidators[i] = privVal - } - sort.Sort(types.PrivValidatorsByAddress(privValidators)) - return &types.GenesisDoc{ - GenesisTime: time.Now(), - ChainID: config.GetString("chain_id"), - Validators: validators, - }, privValidators - -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/config.go deleted file mode 100644 index 63706a7f..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package consensus - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/height_vote_set.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/height_vote_set.go deleted file mode 100644 index 1fa956cd..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/height_vote_set.go +++ /dev/null @@ -1,182 +0,0 @@ -package consensus - -import ( - "strings" - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -type RoundVoteSet struct { - Prevotes *types.VoteSet - Precommits *types.VoteSet -} - -/* -Keeps track of all VoteSets from round 0 to round 'round'. - -Also keeps track of up to one RoundVoteSet greater than -'round' from each peer, to facilitate catchup syncing of commits. - -A commit is +2/3 precommits for a block at a round, -but which round is not known in advance, so when a peer -provides a precommit for a round greater than mtx.round, -we create a new entry in roundVoteSets but also remember the -peer to prevent abuse. -*/ -type HeightVoteSet struct { - height int - valSet *types.ValidatorSet - - mtx sync.Mutex - round int // max tracked round - roundVoteSets map[int]RoundVoteSet // keys: [0...round] - peerCatchupRounds map[string]int // keys: peer.Key; values: round -} - -func NewHeightVoteSet(height int, valSet *types.ValidatorSet) *HeightVoteSet { - hvs := &HeightVoteSet{ - height: height, - valSet: valSet, - roundVoteSets: make(map[int]RoundVoteSet), - peerCatchupRounds: make(map[string]int), - } - hvs.addRound(0) - hvs.round = 0 - return hvs -} - -func (hvs *HeightVoteSet) Height() int { - return hvs.height -} - -func (hvs *HeightVoteSet) Round() int { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.round -} - -// Create more RoundVoteSets up to round. -func (hvs *HeightVoteSet) SetRound(round int) { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - if hvs.round != 0 && (round < hvs.round+1) { - PanicSanity("SetRound() must increment hvs.round") - } - for r := hvs.round + 1; r <= round; r++ { - if _, ok := hvs.roundVoteSets[r]; ok { - continue // Already exists because peerCatchupRounds. - } - hvs.addRound(r) - } - hvs.round = round -} - -func (hvs *HeightVoteSet) addRound(round int) { - if _, ok := hvs.roundVoteSets[round]; ok { - PanicSanity("addRound() for an existing round") - } - log.Debug("addRound(round)", "round", round) - prevotes := types.NewVoteSet(hvs.height, round, types.VoteTypePrevote, hvs.valSet) - precommits := types.NewVoteSet(hvs.height, round, types.VoteTypePrecommit, hvs.valSet) - hvs.roundVoteSets[round] = RoundVoteSet{ - Prevotes: prevotes, - Precommits: precommits, - } -} - -// Duplicate votes return added=false, err=nil. -// By convention, peerKey is "" if origin is self. -func (hvs *HeightVoteSet) AddByIndex(valIndex int, vote *types.Vote, peerKey string) (added bool, address []byte, err error) { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - voteSet := hvs.getVoteSet(vote.Round, vote.Type) - if voteSet == nil { - if _, ok := hvs.peerCatchupRounds[peerKey]; !ok { - hvs.addRound(vote.Round) - hvs.peerCatchupRounds[peerKey] = vote.Round - } else { - // Peer has sent a vote that does not match our round, - // for more than one round. Bad peer! - // TODO punish peer. - log.Warn("Deal with peer giving votes from unwanted rounds") - } - return - } - added, address, err = voteSet.AddByIndex(valIndex, vote) - return -} - -func (hvs *HeightVoteSet) Prevotes(round int) *types.VoteSet { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.getVoteSet(round, types.VoteTypePrevote) -} - -func (hvs *HeightVoteSet) Precommits(round int) *types.VoteSet { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.getVoteSet(round, types.VoteTypePrecommit) -} - -// Last round that has +2/3 prevotes for a particular block or nil. -// Returns -1 if no such round exists. -func (hvs *HeightVoteSet) POLRound() int { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - for r := hvs.round; r >= 0; r-- { - if hvs.getVoteSet(r, types.VoteTypePrevote).HasTwoThirdsMajority() { - return r - } - } - return -1 -} - -func (hvs *HeightVoteSet) getVoteSet(round int, type_ byte) *types.VoteSet { - log.Debug("getVoteSet(round)", "round", round, "type", type_) - rvs, ok := hvs.roundVoteSets[round] - if !ok { - return nil - } - switch type_ { - case types.VoteTypePrevote: - return rvs.Prevotes - case types.VoteTypePrecommit: - return rvs.Precommits - default: - PanicSanity(Fmt("Unexpected vote type %X", type_)) - return nil - } -} - -func (hvs *HeightVoteSet) String() string { - return hvs.StringIndented("") -} - -func (hvs *HeightVoteSet) StringIndented(indent string) string { - vsStrings := make([]string, 0, (len(hvs.roundVoteSets)+1)*2) - // rounds 0 ~ hvs.round inclusive - for round := 0; round <= hvs.round; round++ { - voteSetString := hvs.roundVoteSets[round].Prevotes.StringShort() - vsStrings = append(vsStrings, voteSetString) - voteSetString = hvs.roundVoteSets[round].Precommits.StringShort() - vsStrings = append(vsStrings, voteSetString) - } - // all other peer catchup rounds - for round, roundVoteSet := range hvs.roundVoteSets { - if round <= hvs.round { - continue - } - voteSetString := roundVoteSet.Prevotes.StringShort() - vsStrings = append(vsStrings, voteSetString) - voteSetString = roundVoteSet.Precommits.StringShort() - vsStrings = append(vsStrings, voteSetString) - } - return Fmt(`HeightVoteSet{H:%v R:0~%v -%s %v -%s}`, - hvs.height, hvs.round, - indent, strings.Join(vsStrings, "\n"+indent+" "), - indent) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go deleted file mode 100644 index ba38a689..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package consensus - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "consensus") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/reactor.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/reactor.go deleted file mode 100644 index bbefb21d..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/reactor.go +++ /dev/null @@ -1,1007 +0,0 @@ -package consensus - -import ( - "bytes" - "errors" - "fmt" - "reflect" - "sync" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - StateChannel = byte(0x20) - DataChannel = byte(0x21) - VoteChannel = byte(0x22) - - peerGossipSleepDuration = 100 * time.Millisecond // Time to sleep if there's nothing to send. - maxConsensusMessageSize = 1048576 // 1MB; NOTE: keep in sync with types.PartSet sizes. -) - -//----------------------------------------------------------------------------- - -type ConsensusReactor struct { - p2p.BaseReactor - - blockStore *bc.BlockStore - conS *ConsensusState - fastSync bool - evsw events.Fireable -} - -func NewConsensusReactor(consensusState *ConsensusState, blockStore *bc.BlockStore, fastSync bool) *ConsensusReactor { - conR := &ConsensusReactor{ - blockStore: blockStore, - conS: consensusState, - fastSync: fastSync, - } - conR.BaseReactor = *p2p.NewBaseReactor(log, "ConsensusReactor", conR) - return conR -} - -func (conR *ConsensusReactor) OnStart() error { - log.Notice("ConsensusReactor ", "fastSync", conR.fastSync) - conR.BaseReactor.OnStart() - if !conR.fastSync { - _, err := conR.conS.Start() - if err != nil { - return err - } - } - go conR.broadcastNewRoundStepRoutine() - return nil -} - -func (conR *ConsensusReactor) OnStop() { - conR.BaseReactor.OnStop() - conR.conS.Stop() -} - -// Switch from the fast_sync to the consensus: -// reset the state, turn off fast_sync, start the consensus-state-machine -func (conR *ConsensusReactor) SwitchToConsensus(state *sm.State) { - log.Notice("SwitchToConsensus") - // NOTE: The line below causes broadcastNewRoundStepRoutine() to - // broadcast a NewRoundStepMessage. - conR.conS.updateToState(state) - conR.fastSync = false - conR.conS.Start() -} - -// Implements Reactor -func (conR *ConsensusReactor) GetChannels() []*p2p.ChannelDescriptor { - // TODO optimize - return []*p2p.ChannelDescriptor{ - &p2p.ChannelDescriptor{ - ID: StateChannel, - Priority: 5, - SendQueueCapacity: 100, - }, - &p2p.ChannelDescriptor{ - ID: DataChannel, - Priority: 5, - SendQueueCapacity: 2, - }, - &p2p.ChannelDescriptor{ - ID: VoteChannel, - Priority: 5, - SendQueueCapacity: 40, - }, - } -} - -// Implements Reactor -func (conR *ConsensusReactor) AddPeer(peer *p2p.Peer) { - if !conR.IsRunning() { - return - } - - // Create peerState for peer - peerState := NewPeerState(peer) - peer.Data.Set(types.PeerStateKey, peerState) - - // Begin gossip routines for this peer. - go conR.gossipDataRoutine(peer, peerState) - go conR.gossipVotesRoutine(peer, peerState) - - // Send our state to peer. - // If we're fast_syncing, broadcast a RoundStepMessage later upon SwitchToConsensus(). - if !conR.fastSync { - conR.sendNewRoundStepMessage(peer) - } -} - -// Implements Reactor -func (conR *ConsensusReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { - if !conR.IsRunning() { - return - } - // TODO - //peer.Data.Get(PeerStateKey).(*PeerState).Disconnect() -} - -// Implements Reactor -// NOTE: We process these messages even when we're fast_syncing. -func (conR *ConsensusReactor) Receive(chID byte, peer *p2p.Peer, msgBytes []byte) { - if !conR.IsRunning() { - log.Debug("Receive", "channel", chID, "peer", peer, "bytes", msgBytes) - return - } - - // Get peer states - ps := peer.Data.Get(types.PeerStateKey).(*PeerState) - _, msg, err := DecodeMessage(msgBytes) - if err != nil { - log.Warn("Error decoding message", "channel", chID, "peer", peer, "msg", msg, "error", err, "bytes", msgBytes) - // TODO punish peer? - return - } - log.Debug("Receive", "channel", chID, "peer", peer, "msg", msg) - - switch chID { - case StateChannel: - switch msg := msg.(type) { - case *NewRoundStepMessage: - ps.ApplyNewRoundStepMessage(msg) - case *CommitStepMessage: - ps.ApplyCommitStepMessage(msg) - case *HasVoteMessage: - ps.ApplyHasVoteMessage(msg) - default: - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - - case DataChannel: - if conR.fastSync { - log.Warn("Ignoring message received during fastSync", "msg", msg) - return - } - switch msg := msg.(type) { - case *ProposalMessage: - ps.SetHasProposal(msg.Proposal) - err = conR.conS.SetProposal(msg.Proposal) - case *ProposalPOLMessage: - ps.ApplyProposalPOLMessage(msg) - case *BlockPartMessage: - ps.SetHasProposalBlockPart(msg.Height, msg.Round, msg.Part.Proof.Index) - _, err = conR.conS.AddProposalBlockPart(msg.Height, msg.Part) - default: - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - - case VoteChannel: - if conR.fastSync { - log.Warn("Ignoring message received during fastSync", "msg", msg) - return - } - switch msg := msg.(type) { - case *VoteMessage: - vote, valIndex := msg.Vote, msg.ValidatorIndex - - // attempt to add the vote and dupeout the validator if its a duplicate signature - added, err := conR.conS.TryAddVote(valIndex, vote, peer.Key) - if err == ErrAddingVote { - // TODO: punish peer - } else if err != nil { - return - } - - cs := conR.conS - cs.mtx.Lock() - height, valSize, lastCommitSize := cs.Height, cs.Validators.Size(), cs.LastCommit.Size() - cs.mtx.Unlock() - ps.EnsureVoteBitArrays(height, valSize) - ps.EnsureVoteBitArrays(height-1, lastCommitSize) - ps.SetHasVote(vote, valIndex) - - if added { - // If rs.Height == vote.Height && rs.Round < vote.Round, - // the peer is sending us CatchupCommit precommits. - // We could make note of this and help filter in broadcastHasVoteMessage(). - conR.broadcastHasVoteMessage(vote, valIndex) - } - - default: - // don't punish (leave room for soft upgrades) - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - default: - log.Warn(Fmt("Unknown channel %X", chID)) - } - - if err != nil { - log.Warn("Error in Receive()", "error", err) - } -} - -// Broadcasts HasVoteMessage to peers that care. -func (conR *ConsensusReactor) broadcastHasVoteMessage(vote *types.Vote, index int) { - msg := &HasVoteMessage{ - Height: vote.Height, - Round: vote.Round, - Type: vote.Type, - Index: index, - } - conR.Switch.Broadcast(StateChannel, msg) - /* - // TODO: Make this broadcast more selective. - for _, peer := range conR.Switch.Peers().List() { - ps := peer.Data.Get(PeerStateKey).(*PeerState) - prs := ps.GetRoundState() - if prs.Height == vote.Height { - // TODO: Also filter on round? - peer.TrySend(StateChannel, msg) - } else { - // Height doesn't match - // TODO: check a field, maybe CatchupCommitRound? - // TODO: But that requires changing the struct field comment. - } - } - */ -} - -// Sets our private validator account for signing votes. -func (conR *ConsensusReactor) SetPrivValidator(priv *types.PrivValidator) { - conR.conS.SetPrivValidator(priv) -} - -// implements events.Eventable -func (conR *ConsensusReactor) SetFireable(evsw events.Fireable) { - conR.evsw = evsw - conR.conS.SetFireable(evsw) -} - -//-------------------------------------- - -func makeRoundStepMessages(rs *RoundState) (nrsMsg *NewRoundStepMessage, csMsg *CommitStepMessage) { - nrsMsg = &NewRoundStepMessage{ - Height: rs.Height, - Round: rs.Round, - Step: rs.Step, - SecondsSinceStartTime: int(time.Now().Sub(rs.StartTime).Seconds()), - LastCommitRound: rs.LastCommit.Round(), - } - if rs.Step == RoundStepCommit { - csMsg = &CommitStepMessage{ - Height: rs.Height, - BlockPartsHeader: rs.ProposalBlockParts.Header(), - BlockParts: rs.ProposalBlockParts.BitArray(), - } - } - return -} - -// Listens for changes to the ConsensusState.Step by pulling -// on conR.conS.NewStepCh(). -func (conR *ConsensusReactor) broadcastNewRoundStepRoutine() { - for { - // Get RoundState with new Step or quit. - var rs *RoundState - select { - case rs = <-conR.conS.NewStepCh(): - case <-conR.Quit: - return - } - - nrsMsg, csMsg := makeRoundStepMessages(rs) - if nrsMsg != nil { - conR.Switch.Broadcast(StateChannel, nrsMsg) - } - if csMsg != nil { - conR.Switch.Broadcast(StateChannel, csMsg) - } - } -} - -func (conR *ConsensusReactor) sendNewRoundStepMessage(peer *p2p.Peer) { - rs := conR.conS.GetRoundState() - nrsMsg, csMsg := makeRoundStepMessages(rs) - if nrsMsg != nil { - peer.Send(StateChannel, nrsMsg) - } - if csMsg != nil { - peer.Send(StateChannel, csMsg) - } -} - -func (conR *ConsensusReactor) gossipDataRoutine(peer *p2p.Peer, ps *PeerState) { - log := log.New("peer", peer.Key) - -OUTER_LOOP: - for { - // Manage disconnects from self or peer. - if !peer.IsRunning() || !conR.IsRunning() { - log.Notice(Fmt("Stopping gossipDataRoutine for %v.", peer)) - return - } - rs := conR.conS.GetRoundState() - prs := ps.GetRoundState() - - // Send proposal Block parts? - if rs.ProposalBlockParts.HasHeader(prs.ProposalBlockPartsHeader) { - //log.Info("ProposalBlockParts matched", "blockParts", prs.ProposalBlockParts) - if index, ok := rs.ProposalBlockParts.BitArray().Sub(prs.ProposalBlockParts.Copy()).PickRandom(); ok { - part := rs.ProposalBlockParts.GetPart(index) - msg := &BlockPartMessage{ - Height: rs.Height, // This tells peer that this part applies to us. - Round: rs.Round, // This tells peer that this part applies to us. - Part: part, - } - peer.Send(DataChannel, msg) - ps.SetHasProposalBlockPart(prs.Height, prs.Round, index) - continue OUTER_LOOP - } - } - - // If the peer is on a previous height, help catch up. - if (0 < prs.Height) && (prs.Height < rs.Height) { - //log.Info("Data catchup", "height", rs.Height, "peerHeight", prs.Height, "peerProposalBlockParts", prs.ProposalBlockParts) - if index, ok := prs.ProposalBlockParts.Not().PickRandom(); ok { - // Ensure that the peer's PartSetHeader is correct - blockMeta := conR.blockStore.LoadBlockMeta(prs.Height) - if !blockMeta.PartsHeader.Equals(prs.ProposalBlockPartsHeader) { - log.Info("Peer ProposalBlockPartsHeader mismatch, sleeping", - "peerHeight", prs.Height, "blockPartsHeader", blockMeta.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader) - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } - // Load the part - part := conR.blockStore.LoadBlockPart(prs.Height, index) - if part == nil { - log.Warn("Could not load part", "index", index, - "peerHeight", prs.Height, "blockPartsHeader", blockMeta.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader) - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } - // Send the part - msg := &BlockPartMessage{ - Height: prs.Height, // Not our height, so it doesn't matter. - Round: prs.Round, // Not our height, so it doesn't matter. - Part: part, - } - peer.Send(DataChannel, msg) - ps.SetHasProposalBlockPart(prs.Height, prs.Round, index) - continue OUTER_LOOP - } else { - //log.Info("No parts to send in catch-up, sleeping") - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } - } - - // If height and round don't match, sleep. - if (rs.Height != prs.Height) || (rs.Round != prs.Round) { - //log.Info("Peer Height|Round mismatch, sleeping", "peerHeight", prs.Height, "peerRound", prs.Round, "peer", peer) - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } - - // By here, height and round match. - // Proposal block parts were already matched and sent if any were wanted. - // (These can match on hash so the round doesn't matter) - // Now consider sending other things, like the Proposal itself. - - // Send Proposal && ProposalPOL BitArray? - if rs.Proposal != nil && !prs.Proposal { - // Proposal - { - msg := &ProposalMessage{Proposal: rs.Proposal} - peer.Send(DataChannel, msg) - ps.SetHasProposal(rs.Proposal) - } - // ProposalPOL. - // Peer must receive ProposalMessage first. - // rs.Proposal was validated, so rs.Proposal.POLRound <= rs.Round, - // so we definitely have rs.Votes.Prevotes(rs.Proposal.POLRound). - if 0 <= rs.Proposal.POLRound { - msg := &ProposalPOLMessage{ - Height: rs.Height, - ProposalPOLRound: rs.Proposal.POLRound, - ProposalPOL: rs.Votes.Prevotes(rs.Proposal.POLRound).BitArray(), - } - peer.Send(DataChannel, msg) - } - continue OUTER_LOOP - } - - // Nothing to do. Sleep. - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } -} - -func (conR *ConsensusReactor) gossipVotesRoutine(peer *p2p.Peer, ps *PeerState) { - log := log.New("peer", peer.Key) - - // Simple hack to throttle logs upon sleep. - var sleeping = 0 - -OUTER_LOOP: - for { - // Manage disconnects from self or peer. - if !peer.IsRunning() || !conR.IsRunning() { - log.Notice(Fmt("Stopping gossipVotesRoutine for %v.", peer)) - return - } - rs := conR.conS.GetRoundState() - prs := ps.GetRoundState() - - switch sleeping { - case 1: // First sleep - sleeping = 2 - case 2: // No more sleep - sleeping = 0 - } - - log.Debug("gossipVotesRoutine", "rsHeight", rs.Height, "rsRound", rs.Round, - "prsHeight", prs.Height, "prsRound", prs.Round, "prsStep", prs.Step) - - // If height matches, then send LastCommit, Prevotes, Precommits. - if rs.Height == prs.Height { - // If there are lastCommits to send... - if prs.Step == RoundStepNewHeight { - if ps.PickSendVote(rs.LastCommit) { - log.Info("Picked rs.LastCommit to send") - continue OUTER_LOOP - } - } - // If there are prevotes to send... - if prs.Step <= RoundStepPrevote && prs.Round != -1 && prs.Round <= rs.Round { - if ps.PickSendVote(rs.Votes.Prevotes(prs.Round)) { - log.Info("Picked rs.Prevotes(prs.Round) to send") - continue OUTER_LOOP - } - } - // If there are precommits to send... - if prs.Step <= RoundStepPrecommit && prs.Round != -1 && prs.Round <= rs.Round { - if ps.PickSendVote(rs.Votes.Precommits(prs.Round)) { - log.Info("Picked rs.Precommits(prs.Round) to send") - continue OUTER_LOOP - } - } - // If there are POLPrevotes to send... - if prs.ProposalPOLRound != -1 { - if polPrevotes := rs.Votes.Prevotes(prs.ProposalPOLRound); polPrevotes != nil { - if ps.PickSendVote(polPrevotes) { - log.Info("Picked rs.Prevotes(prs.ProposalPOLRound) to send") - continue OUTER_LOOP - } - } - } - } - - // Special catchup logic. - // If peer is lagging by height 1, send LastCommit. - if prs.Height != 0 && rs.Height == prs.Height+1 { - if ps.PickSendVote(rs.LastCommit) { - log.Info("Picked rs.LastCommit to send") - continue OUTER_LOOP - } - } - - // Catchup logic - // If peer is lagging by more than 1, send Validation. - if prs.Height != 0 && rs.Height >= prs.Height+2 { - // Load the block validation for prs.Height, - // which contains precommit signatures for prs.Height. - validation := conR.blockStore.LoadBlockValidation(prs.Height) - log.Info("Loaded BlockValidation for catch-up", "height", prs.Height, "validation", validation) - if ps.PickSendVote(validation) { - log.Info("Picked Catchup validation to send") - continue OUTER_LOOP - } - } - - if sleeping == 0 { - // We sent nothing. Sleep... - sleeping = 1 - log.Info("No votes to send, sleeping", "peer", peer, - "localPV", rs.Votes.Prevotes(rs.Round).BitArray(), "peerPV", prs.Prevotes, - "localPC", rs.Votes.Precommits(rs.Round).BitArray(), "peerPC", prs.Precommits) - } else if sleeping == 2 { - // Continued sleep... - sleeping = 1 - } - - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } -} - -//----------------------------------------------------------------------------- - -// Read only when returned by PeerState.GetRoundState(). -type PeerRoundState struct { - Height int // Height peer is at - Round int // Round peer is at, -1 if unknown. - Step RoundStepType // Step peer is at - StartTime time.Time // Estimated start of round 0 at this height - Proposal bool // True if peer has proposal for this round - ProposalBlockPartsHeader types.PartSetHeader // - ProposalBlockParts *BitArray // - ProposalPOLRound int // Proposal's POL round. -1 if none. - ProposalPOL *BitArray // nil until ProposalPOLMessage received. - Prevotes *BitArray // All votes peer has for this round - Precommits *BitArray // All precommits peer has for this round - LastCommitRound int // Round of commit for last height. -1 if none. - LastCommit *BitArray // All commit precommits of commit for last height. - CatchupCommitRound int // Round that we have commit for. Not necessarily unique. -1 if none. - CatchupCommit *BitArray // All commit precommits peer has for this height & CatchupCommitRound -} - -//----------------------------------------------------------------------------- - -var ( - ErrPeerStateHeightRegression = errors.New("Error peer state height regression") - ErrPeerStateInvalidStartTime = errors.New("Error peer state invalid startTime") -) - -type PeerState struct { - Peer *p2p.Peer - - mtx sync.Mutex - PeerRoundState -} - -func NewPeerState(peer *p2p.Peer) *PeerState { - return &PeerState{ - Peer: peer, - PeerRoundState: PeerRoundState{ - Round: -1, - ProposalPOLRound: -1, - LastCommitRound: -1, - CatchupCommitRound: -1, - }, - } -} - -// Returns an atomic snapshot of the PeerRoundState. -// There's no point in mutating it since it won't change PeerState. -func (ps *PeerState) GetRoundState() *PeerRoundState { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - prs := ps.PeerRoundState // copy - return &prs -} - -// Returns an atomic snapshot of the PeerRoundState's height -// used by the mempool to ensure peers are caught up before broadcasting new txs -func (ps *PeerState) GetHeight() int { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return ps.PeerRoundState.Height -} - -func (ps *PeerState) SetHasProposal(proposal *types.Proposal) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != proposal.Height || ps.Round != proposal.Round { - return - } - if ps.Proposal { - return - } - - ps.Proposal = true - ps.ProposalBlockPartsHeader = proposal.BlockPartsHeader - ps.ProposalBlockParts = NewBitArray(proposal.BlockPartsHeader.Total) - ps.ProposalPOLRound = proposal.POLRound - ps.ProposalPOL = nil // Nil until ProposalPOLMessage received. -} - -func (ps *PeerState) SetHasProposalBlockPart(height int, round int, index int) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != height || ps.Round != round { - return - } - - ps.ProposalBlockParts.SetIndex(index, true) -} - -// Convenience function to send vote to peer. -// Returns true if vote was sent. -func (ps *PeerState) PickSendVote(votes types.VoteSetReader) (ok bool) { - if index, vote, ok := ps.PickVoteToSend(votes); ok { - msg := &VoteMessage{index, vote} - ps.Peer.Send(VoteChannel, msg) - return true - } - return false -} - -// votes: Must be the correct Size() for the Height(). -func (ps *PeerState) PickVoteToSend(votes types.VoteSetReader) (index int, vote *types.Vote, ok bool) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if votes.Size() == 0 { - return 0, nil, false - } - - height, round, type_, size := votes.Height(), votes.Round(), votes.Type(), votes.Size() - - // Lazily set data using 'votes'. - if votes.IsCommit() { - ps.ensureCatchupCommitRound(height, round, size) - } - ps.ensureVoteBitArrays(height, size) - - psVotes := ps.getVoteBitArray(height, round, type_) - if psVotes == nil { - return 0, nil, false // Not something worth sending - } - if index, ok := votes.BitArray().Sub(psVotes).PickRandom(); ok { - ps.setHasVote(height, round, type_, index) - return index, votes.GetByIndex(index), true - } - return 0, nil, false -} - -func (ps *PeerState) getVoteBitArray(height, round int, type_ byte) *BitArray { - if ps.Height == height { - if ps.Round == round { - switch type_ { - case types.VoteTypePrevote: - return ps.Prevotes - case types.VoteTypePrecommit: - return ps.Precommits - default: - PanicSanity(Fmt("Unexpected vote type %X", type_)) - } - } - if ps.CatchupCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - return nil - case types.VoteTypePrecommit: - return ps.CatchupCommit - default: - PanicSanity(Fmt("Unexpected vote type %X", type_)) - } - } - return nil - } - if ps.Height == height+1 { - if ps.LastCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - return nil - case types.VoteTypePrecommit: - return ps.LastCommit - default: - PanicSanity(Fmt("Unexpected vote type %X", type_)) - } - } - return nil - } - return nil -} - -// 'round': A round for which we have a +2/3 commit. -func (ps *PeerState) ensureCatchupCommitRound(height, round int, numValidators int) { - if ps.Height != height { - return - } - /* - NOTE: This is wrong, 'round' could change. - e.g. if orig round is not the same as block LastValidation round. - if ps.CatchupCommitRound != -1 && ps.CatchupCommitRound != round { - PanicSanity(Fmt("Conflicting CatchupCommitRound. Height: %v, Orig: %v, New: %v", height, ps.CatchupCommitRound, round)) - } - */ - if ps.CatchupCommitRound == round { - return // Nothing to do! - } - ps.CatchupCommitRound = round - if round == ps.Round { - ps.CatchupCommit = ps.Precommits - } else { - ps.CatchupCommit = NewBitArray(numValidators) - } -} - -// NOTE: It's important to make sure that numValidators actually matches -// what the node sees as the number of validators for height. -func (ps *PeerState) EnsureVoteBitArrays(height int, numValidators int) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - ps.ensureVoteBitArrays(height, numValidators) -} - -func (ps *PeerState) ensureVoteBitArrays(height int, numValidators int) { - if ps.Height == height { - if ps.Prevotes == nil { - ps.Prevotes = NewBitArray(numValidators) - } - if ps.Precommits == nil { - ps.Precommits = NewBitArray(numValidators) - } - if ps.CatchupCommit == nil { - ps.CatchupCommit = NewBitArray(numValidators) - } - if ps.ProposalPOL == nil { - ps.ProposalPOL = NewBitArray(numValidators) - } - } else if ps.Height == height+1 { - if ps.LastCommit == nil { - ps.LastCommit = NewBitArray(numValidators) - } - } -} - -func (ps *PeerState) SetHasVote(vote *types.Vote, index int) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - ps.setHasVote(vote.Height, vote.Round, vote.Type, index) -} - -func (ps *PeerState) setHasVote(height int, round int, type_ byte, index int) { - log := log.New("peer", ps.Peer.Key, "peerRound", ps.Round, "height", height, "round", round) - if type_ != types.VoteTypePrevote && type_ != types.VoteTypePrecommit { - PanicSanity("Invalid vote type") - } - - if ps.Height == height { - if ps.Round == round { - switch type_ { - case types.VoteTypePrevote: - ps.Prevotes.SetIndex(index, true) - log.Info("SetHasVote(round-match)", "prevotes", ps.Prevotes, "index", index) - case types.VoteTypePrecommit: - ps.Precommits.SetIndex(index, true) - log.Info("SetHasVote(round-match)", "precommits", ps.Precommits, "index", index) - } - } else if ps.CatchupCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - case types.VoteTypePrecommit: - ps.CatchupCommit.SetIndex(index, true) - log.Info("SetHasVote(CatchupCommit)", "precommits", ps.Precommits, "index", index) - } - } else if ps.ProposalPOLRound == round { - switch type_ { - case types.VoteTypePrevote: - ps.ProposalPOL.SetIndex(index, true) - log.Info("SetHasVote(ProposalPOL)", "prevotes", ps.Prevotes, "index", index) - case types.VoteTypePrecommit: - } - } - } else if ps.Height == height+1 { - if ps.LastCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - case types.VoteTypePrecommit: - ps.LastCommit.SetIndex(index, true) - log.Info("setHasVote(LastCommit)", "lastCommit", ps.LastCommit, "index", index) - } - } - } else { - // Does not apply. - } -} - -func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - // Ignore duplicate messages. - if ps.Height == msg.Height && ps.Round == msg.Round && ps.Step == msg.Step { - return - } - - // Just remember these values. - psHeight := ps.Height - psRound := ps.Round - //psStep := ps.Step - psCatchupCommitRound := ps.CatchupCommitRound - psCatchupCommit := ps.CatchupCommit - - startTime := time.Now().Add(-1 * time.Duration(msg.SecondsSinceStartTime) * time.Second) - ps.Height = msg.Height - ps.Round = msg.Round - ps.Step = msg.Step - ps.StartTime = startTime - if psHeight != msg.Height || psRound != msg.Round { - ps.Proposal = false - ps.ProposalBlockPartsHeader = types.PartSetHeader{} - ps.ProposalBlockParts = nil - ps.ProposalPOLRound = -1 - ps.ProposalPOL = nil - // We'll update the BitArray capacity later. - ps.Prevotes = nil - ps.Precommits = nil - } - if psHeight == msg.Height && psRound != msg.Round && msg.Round == psCatchupCommitRound { - // Peer caught up to CatchupCommitRound. - // Preserve psCatchupCommit! - // NOTE: We prefer to use prs.Precommits if - // pr.Round matches pr.CatchupCommitRound. - ps.Precommits = psCatchupCommit - } - if psHeight != msg.Height { - // Shift Precommits to LastCommit. - if psHeight+1 == msg.Height && psRound == msg.LastCommitRound { - ps.LastCommitRound = msg.LastCommitRound - ps.LastCommit = ps.Precommits - } else { - ps.LastCommitRound = msg.LastCommitRound - ps.LastCommit = nil - } - // We'll update the BitArray capacity later. - ps.CatchupCommitRound = -1 - ps.CatchupCommit = nil - } -} - -func (ps *PeerState) ApplyCommitStepMessage(msg *CommitStepMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != msg.Height { - return - } - - ps.ProposalBlockPartsHeader = msg.BlockPartsHeader - ps.ProposalBlockParts = msg.BlockParts -} - -func (ps *PeerState) ApplyHasVoteMessage(msg *HasVoteMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != msg.Height { - return - } - - ps.setHasVote(msg.Height, msg.Round, msg.Type, msg.Index) -} - -func (ps *PeerState) ApplyProposalPOLMessage(msg *ProposalPOLMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != msg.Height { - return - } - if ps.ProposalPOLRound != msg.ProposalPOLRound { - return - } - - // TODO: Merge onto existing ps.ProposalPOL? - // We might have sent some prevotes in the meantime. - ps.ProposalPOL = msg.ProposalPOL -} - -//----------------------------------------------------------------------------- -// Messages - -const ( - msgTypeNewRoundStep = byte(0x01) - msgTypeCommitStep = byte(0x02) - msgTypeProposal = byte(0x11) - msgTypeProposalPOL = byte(0x12) - msgTypeBlockPart = byte(0x13) // both block & POL - msgTypeVote = byte(0x14) - msgTypeHasVote = byte(0x15) -) - -type ConsensusMessage interface{} - -var _ = wire.RegisterInterface( - struct{ ConsensusMessage }{}, - wire.ConcreteType{&NewRoundStepMessage{}, msgTypeNewRoundStep}, - wire.ConcreteType{&CommitStepMessage{}, msgTypeCommitStep}, - wire.ConcreteType{&ProposalMessage{}, msgTypeProposal}, - wire.ConcreteType{&ProposalPOLMessage{}, msgTypeProposalPOL}, - wire.ConcreteType{&BlockPartMessage{}, msgTypeBlockPart}, - wire.ConcreteType{&VoteMessage{}, msgTypeVote}, - wire.ConcreteType{&HasVoteMessage{}, msgTypeHasVote}, -) - -// TODO: check for unnecessary extra bytes at the end. -func DecodeMessage(bz []byte) (msgType byte, msg ConsensusMessage, err error) { - msgType = bz[0] - n := new(int) - r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ ConsensusMessage }{}, r, maxConsensusMessageSize, n, &err).(struct{ ConsensusMessage }).ConsensusMessage - return -} - -//------------------------------------- - -// For every height/round/step transition -type NewRoundStepMessage struct { - Height int - Round int - Step RoundStepType - SecondsSinceStartTime int - LastCommitRound int -} - -func (m *NewRoundStepMessage) String() string { - return fmt.Sprintf("[NewRoundStep H:%v R:%v S:%v LCR:%v]", - m.Height, m.Round, m.Step, m.LastCommitRound) -} - -//------------------------------------- - -type CommitStepMessage struct { - Height int - BlockPartsHeader types.PartSetHeader - BlockParts *BitArray -} - -func (m *CommitStepMessage) String() string { - return fmt.Sprintf("[CommitStep H:%v BP:%v BA:%v]", m.Height, m.BlockPartsHeader, m.BlockParts) -} - -//------------------------------------- - -type ProposalMessage struct { - Proposal *types.Proposal -} - -func (m *ProposalMessage) String() string { - return fmt.Sprintf("[Proposal %v]", m.Proposal) -} - -//------------------------------------- - -type ProposalPOLMessage struct { - Height int - ProposalPOLRound int - ProposalPOL *BitArray -} - -func (m *ProposalPOLMessage) String() string { - return fmt.Sprintf("[ProposalPOL H:%v POLR:%v POL:%v]", m.Height, m.ProposalPOLRound, m.ProposalPOL) -} - -//------------------------------------- - -type BlockPartMessage struct { - Height int - Round int - Part *types.Part -} - -func (m *BlockPartMessage) String() string { - return fmt.Sprintf("[BlockPart H:%v R:%v P:%v]", m.Height, m.Round, m.Part) -} - -//------------------------------------- - -type VoteMessage struct { - ValidatorIndex int - Vote *types.Vote -} - -func (m *VoteMessage) String() string { - return fmt.Sprintf("[Vote VI:%v V:%v VI:%v]", m.ValidatorIndex, m.Vote, m.ValidatorIndex) -} - -//------------------------------------- - -type HasVoteMessage struct { - Height int - Round int - Type byte - Index int -} - -func (m *HasVoteMessage) String() string { - return fmt.Sprintf("[HasVote VI:%v V:{%v/%02d/%v} VI:%v]", m.Index, m.Height, m.Round, m.Type, m.Index) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go deleted file mode 100644 index 7e4b6879..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go +++ /dev/null @@ -1,1189 +0,0 @@ -package consensus - -import ( - "bytes" - "errors" - "fmt" - "sync" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - mempl "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -var ( - timeoutPropose = 3000 * time.Millisecond // Maximum duration of RoundStepPropose - timeoutPrevote0 = 1000 * time.Millisecond // After any +2/3 prevotes received, wait this long for stragglers. - timeoutPrevoteDelta = 0500 * time.Millisecond // timeoutPrevoteN is timeoutPrevote0 + timeoutPrevoteDelta*N - timeoutPrecommit0 = 1000 * time.Millisecond // After any +2/3 precommits received, wait this long for stragglers. - timeoutPrecommitDelta = 0500 * time.Millisecond // timeoutPrecommitN is timeoutPrecommit0 + timeoutPrecommitDelta*N - timeoutCommit = 2000 * time.Millisecond // After +2/3 commits received for committed block, wait this long for stragglers in the next height's RoundStepNewHeight. -) - -var ( - ErrInvalidProposalSignature = errors.New("Error invalid proposal signature") - ErrInvalidProposalPOLRound = errors.New("Error invalid proposal POL round") - ErrAddingVote = errors.New("Error adding vote") - ErrVoteHeightMismatch = errors.New("Error vote height mismatch") -) - -//----------------------------------------------------------------------------- -// RoundStepType enum type - -type RoundStepType uint8 // These must be numeric, ordered. - -const ( - RoundStepNewHeight = RoundStepType(0x01) // Wait til CommitTime + timeoutCommit - RoundStepNewRound = RoundStepType(0x02) // Setup new round and go to RoundStepPropose - RoundStepPropose = RoundStepType(0x03) // Did propose, gossip proposal - RoundStepPrevote = RoundStepType(0x04) // Did prevote, gossip prevotes - RoundStepPrevoteWait = RoundStepType(0x05) // Did receive any +2/3 prevotes, start timeout - RoundStepPrecommit = RoundStepType(0x06) // Did precommit, gossip precommits - RoundStepPrecommitWait = RoundStepType(0x07) // Did receive any +2/3 precommits, start timeout - RoundStepCommit = RoundStepType(0x08) // Entered commit state machine - // NOTE: RoundStepNewHeight acts as RoundStepCommitWait. -) - -func (rs RoundStepType) String() string { - switch rs { - case RoundStepNewHeight: - return "RoundStepNewHeight" - case RoundStepNewRound: - return "RoundStepNewRound" - case RoundStepPropose: - return "RoundStepPropose" - case RoundStepPrevote: - return "RoundStepPrevote" - case RoundStepPrevoteWait: - return "RoundStepPrevoteWait" - case RoundStepPrecommit: - return "RoundStepPrecommit" - case RoundStepPrecommitWait: - return "RoundStepPrecommitWait" - case RoundStepCommit: - return "RoundStepCommit" - default: - return "RoundStepUnknown" // Cannot panic. - } -} - -//----------------------------------------------------------------------------- - -// Immutable when returned from ConsensusState.GetRoundState() -type RoundState struct { - Height int // Height we are working on - Round int - Step RoundStepType - StartTime time.Time - CommitTime time.Time // Subjective time when +2/3 precommits for Block at Round were found - Validators *types.ValidatorSet - Proposal *types.Proposal - ProposalBlock *types.Block - ProposalBlockParts *types.PartSet - LockedRound int - LockedBlock *types.Block - LockedBlockParts *types.PartSet - Votes *HeightVoteSet - CommitRound int // - LastCommit *types.VoteSet // Last precommits at Height-1 - LastValidators *types.ValidatorSet -} - -func (rs *RoundState) RoundStateEvent() *types.EventDataRoundState { - return &types.EventDataRoundState{ - CurrentTime: time.Now(), - Height: rs.Height, - Round: rs.Round, - Step: rs.Step.String(), - StartTime: rs.StartTime, - CommitTime: rs.CommitTime, - Proposal: rs.Proposal, - ProposalBlock: rs.ProposalBlock, - LockedRound: rs.LockedRound, - LockedBlock: rs.LockedBlock, - POLRound: rs.Votes.POLRound(), - } -} - -func (rs *RoundState) String() string { - return rs.StringIndented("") -} - -func (rs *RoundState) StringIndented(indent string) string { - return fmt.Sprintf(`RoundState{ -%s H:%v R:%v S:%v -%s StartTime: %v -%s CommitTime: %v -%s Validators: %v -%s Proposal: %v -%s ProposalBlock: %v %v -%s LockedRound: %v -%s LockedBlock: %v %v -%s Votes: %v -%s LastCommit: %v -%s LastValidators: %v -%s}`, - indent, rs.Height, rs.Round, rs.Step, - indent, rs.StartTime, - indent, rs.CommitTime, - indent, rs.Validators.StringIndented(indent+" "), - indent, rs.Proposal, - indent, rs.ProposalBlockParts.StringShort(), rs.ProposalBlock.StringShort(), - indent, rs.LockedRound, - indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort(), - indent, rs.Votes.StringIndented(indent+" "), - indent, rs.LastCommit.StringShort(), - indent, rs.LastValidators.StringIndented(indent+" "), - indent) -} - -func (rs *RoundState) StringShort() string { - return fmt.Sprintf(`RoundState{H:%v R:%v S:%v ST:%v}`, - rs.Height, rs.Round, rs.Step, rs.StartTime) -} - -//----------------------------------------------------------------------------- - -// Tracks consensus state across block heights and rounds. -type ConsensusState struct { - BaseService - - proxyAppCtx proxy.AppContext - blockStore *bc.BlockStore - mempool *mempl.Mempool - privValidator *types.PrivValidator - newStepCh chan *RoundState - - mtx sync.Mutex - RoundState - state *sm.State // State until height-1. - stagedBlock *types.Block // Cache last staged block. - stagedState *sm.State // Cache result of staged block. - - evsw events.Fireable - evc *events.EventCache // set in stageBlock and passed into state -} - -func NewConsensusState(state *sm.State, proxyAppCtx proxy.AppContext, blockStore *bc.BlockStore, mempool *mempl.Mempool) *ConsensusState { - cs := &ConsensusState{ - proxyAppCtx: proxyAppCtx, - blockStore: blockStore, - mempool: mempool, - newStepCh: make(chan *RoundState, 10), - } - cs.updateToState(state) - // Don't call scheduleRound0 yet. - // We do that upon Start(). - cs.reconstructLastCommit(state) - cs.BaseService = *NewBaseService(log, "ConsensusState", cs) - return cs -} - -// Reconstruct LastCommit from SeenValidation, which we saved along with the block, -// (which happens even before saving the state) -func (cs *ConsensusState) reconstructLastCommit(state *sm.State) { - if state.LastBlockHeight == 0 { - return - } - lastPrecommits := types.NewVoteSet(state.LastBlockHeight, 0, types.VoteTypePrecommit, state.LastValidators) - seenValidation := cs.blockStore.LoadSeenValidation(state.LastBlockHeight) - for idx, precommit := range seenValidation.Precommits { - if precommit == nil { - continue - } - added, _, err := lastPrecommits.AddByIndex(idx, precommit) - if !added || err != nil { - PanicCrisis(Fmt("Failed to reconstruct LastCommit: %v", err)) - } - } - if !lastPrecommits.HasTwoThirdsMajority() { - PanicSanity("Failed to reconstruct LastCommit: Does not have +2/3 maj") - } - cs.LastCommit = lastPrecommits -} - -func (cs *ConsensusState) GetState() *sm.State { - cs.mtx.Lock() - defer cs.mtx.Unlock() - return cs.state.Copy() -} - -func (cs *ConsensusState) GetRoundState() *RoundState { - cs.mtx.Lock() - defer cs.mtx.Unlock() - return cs.getRoundState() -} - -func (cs *ConsensusState) getRoundState() *RoundState { - rs := cs.RoundState // copy - return &rs -} - -func (cs *ConsensusState) NewStepCh() chan *RoundState { - return cs.newStepCh -} - -func (cs *ConsensusState) OnStart() error { - cs.BaseService.OnStart() - cs.scheduleRound0(cs.Height) - return nil -} - -func (cs *ConsensusState) OnStop() { - // It's asynchronous so, there's not much to stop. - cs.BaseService.OnStop() -} - -// EnterNewRound(height, 0) at cs.StartTime. -func (cs *ConsensusState) scheduleRound0(height int) { - //log.Info("scheduleRound0", "now", time.Now(), "startTime", cs.StartTime) - sleepDuration := cs.StartTime.Sub(time.Now()) - go func() { - if 0 < sleepDuration { - time.Sleep(sleepDuration) - // TODO: event? - } - cs.EnterNewRound(height, 0, false) - }() -} - -// Updates ConsensusState and increments height to match that of state. -// The round becomes 0 and cs.Step becomes RoundStepNewHeight. -func (cs *ConsensusState) updateToState(state *sm.State) { - if cs.CommitRound > -1 && 0 < cs.Height && cs.Height != state.LastBlockHeight { - PanicSanity(Fmt("updateToState() expected state height of %v but found %v", - cs.Height, state.LastBlockHeight)) - } - if cs.state != nil && cs.state.LastBlockHeight+1 != cs.Height { - // This might happen when someone else is mutating cs.state. - // Someone forgot to pass in state.Copy() somewhere?! - PanicSanity(Fmt("Inconsistent cs.state.LastBlockHeight+1 %v vs cs.Height %v", - cs.state.LastBlockHeight+1, cs.Height)) - } - - // If state isn't further out than cs.state, just ignore. - // This happens when SwitchToConsensus() is called in the reactor. - // We don't want to reset e.g. the Votes. - if cs.state != nil && (state.LastBlockHeight <= cs.state.LastBlockHeight) { - log.Notice("Ignoring updateToState()", "newHeight", state.LastBlockHeight+1, "oldHeight", cs.state.LastBlockHeight+1) - return - } - - // Reset fields based on state. - validators := state.Validators - height := state.LastBlockHeight + 1 // next desired block height - lastPrecommits := (*types.VoteSet)(nil) - if cs.CommitRound > -1 && cs.Votes != nil { - if !cs.Votes.Precommits(cs.CommitRound).HasTwoThirdsMajority() { - PanicSanity("updateToState(state) called but last Precommit round didn't have +2/3") - } - lastPrecommits = cs.Votes.Precommits(cs.CommitRound) - } - - // RoundState fields - cs.Height = height - cs.Round = 0 - cs.Step = RoundStepNewHeight - if cs.CommitTime.IsZero() { - // "Now" makes it easier to sync up dev nodes. - // We add timeoutCommit to allow transactions - // to be gathered for the first block. - // And alternative solution that relies on clocks: - // cs.StartTime = state.LastBlockTime.Add(timeoutCommit) - cs.StartTime = time.Now().Add(timeoutCommit) - } else { - cs.StartTime = cs.CommitTime.Add(timeoutCommit) - } - cs.CommitTime = time.Time{} - cs.Validators = validators - cs.Proposal = nil - cs.ProposalBlock = nil - cs.ProposalBlockParts = nil - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - cs.Votes = NewHeightVoteSet(height, validators) - cs.CommitRound = -1 - cs.LastCommit = lastPrecommits - cs.LastValidators = state.LastValidators - - cs.state = state - cs.stagedBlock = nil - cs.stagedState = nil - - // Finally, broadcast RoundState - cs.newStepCh <- cs.getRoundState() -} - -func (cs *ConsensusState) SetPrivValidator(priv *types.PrivValidator) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - cs.privValidator = priv -} - -//----------------------------------------------------------------------------- - -// Enter: +2/3 precommits for nil at (height,round-1) -// Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1) -// Enter: `startTime = commitTime+timeoutCommit` from NewHeight(height) -// NOTE: cs.StartTime was already set for height. -func (cs *ConsensusState) EnterNewRound(height int, round int, timedOut bool) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != RoundStepNewHeight) { - log.Debug(Fmt("EnterNewRound(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - - if timedOut { - cs.evsw.FireEvent(types.EventStringTimeoutWait(), cs.RoundStateEvent()) - } - - if now := time.Now(); cs.StartTime.After(now) { - log.Warn("Need to set a buffer and log.Warn() here for sanity.", "startTime", cs.StartTime, "now", now) - } - log.Notice(Fmt("EnterNewRound(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Increment validators if necessary - validators := cs.Validators - if cs.Round < round { - validators = validators.Copy() - validators.IncrementAccum(round - cs.Round) - } - - // Setup new round - cs.Round = round - cs.Step = RoundStepNewRound - cs.Validators = validators - if round == 0 { - // We've already reset these upon new height, - // and meanwhile we might have received a proposal - // for round 0. - } else { - cs.Proposal = nil - cs.ProposalBlock = nil - cs.ProposalBlockParts = nil - } - cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping - - cs.evsw.FireEvent(types.EventStringNewRound(), cs.RoundStateEvent()) - - // Immediately go to EnterPropose. - go cs.EnterPropose(height, round) -} - -// Enter: from NewRound(height,round). -func (cs *ConsensusState) EnterPropose(height int, round int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPropose <= cs.Step) { - log.Debug(Fmt("EnterPropose(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - log.Info(Fmt("EnterPropose(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done EnterPropose: - cs.Round = round - cs.Step = RoundStepPropose - cs.newStepCh <- cs.getRoundState() - - // If we have the whole proposal + POL, then goto Prevote now. - // else, we'll EnterPrevote when the rest of the proposal is received (in AddProposalBlockPart), - // or else after timeoutPropose - if cs.isProposalComplete() { - go cs.EnterPrevote(height, cs.Round, false) - } - }() - - // This step times out after `timeoutPropose` - go func() { - time.Sleep(timeoutPropose) - cs.EnterPrevote(height, round, true) - }() - - // Nothing more to do if we're not a validator - if cs.privValidator == nil { - return - } - - if !bytes.Equal(cs.Validators.Proposer().Address, cs.privValidator.Address) { - log.Info("EnterPropose: Not our turn to propose", "proposer", cs.Validators.Proposer().Address, "privValidator", cs.privValidator) - } else { - log.Info("EnterPropose: Our turn to propose", "proposer", cs.Validators.Proposer().Address, "privValidator", cs.privValidator) - cs.decideProposal(height, round) - } -} - -func (cs *ConsensusState) decideProposal(height, round int) { - var block *types.Block - var blockParts *types.PartSet - - // Decide on block - if cs.LockedBlock != nil { - // If we're locked onto a block, just choose that. - block, blockParts = cs.LockedBlock, cs.LockedBlockParts - } else { - // Create a new proposal block from state/txs from the mempool. - block, blockParts = cs.createProposalBlock() - if block == nil { // on error - return - } - } - - // Make proposal - proposal := types.NewProposal(height, round, blockParts.Header(), cs.Votes.POLRound()) - err := cs.privValidator.SignProposal(cs.state.ChainID, proposal) - if err == nil { - log.Notice("Signed and set proposal", "height", height, "round", round, "proposal", proposal) - log.Debug(Fmt("Signed and set proposal block: %v", block)) - // Set fields - cs.Proposal = proposal - cs.ProposalBlock = block - cs.ProposalBlockParts = blockParts - } else { - log.Warn("EnterPropose: Error signing proposal", "height", height, "round", round, "error", err) - } - -} - -// Returns true if the proposal block is complete && -// (if POLRound was proposed, we have +2/3 prevotes from there). -func (cs *ConsensusState) isProposalComplete() bool { - if cs.Proposal == nil || cs.ProposalBlock == nil { - return false - } - // we have the proposal. if there's a POLRound, - // make sure we have the prevotes from it too - if cs.Proposal.POLRound < 0 { - return true - } else { - // if this is false the proposer is lying or we haven't received the POL yet - return cs.Votes.Prevotes(cs.Proposal.POLRound).HasTwoThirdsMajority() - } -} - -// Create the next block to propose and return it. -// Returns nil block upon error. -// NOTE: keep it side-effect free for clarity. -func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts *types.PartSet) { - var validation *types.Validation - if cs.Height == 1 { - // We're creating a proposal for the first block. - // The validation is empty, but not nil. - validation = &types.Validation{} - } else if cs.LastCommit.HasTwoThirdsMajority() { - // Make the validation from LastCommit - validation = cs.LastCommit.MakeValidation() - } else { - // This shouldn't happen. - log.Error("EnterPropose: Cannot propose anything: No validation for the previous block.") - return - } - - // Mempool run transactions and the resulting hash - txs, hash, err := cs.mempool.Reap() - if err != nil { - log.Warn("createProposalBlock: Error getting proposal txs", "error", err) - return nil, nil - } - - block = &types.Block{ - Header: &types.Header{ - ChainID: cs.state.ChainID, - Height: cs.Height, - Time: time.Now(), - Fees: 0, // TODO fees - NumTxs: len(txs), - LastBlockHash: cs.state.LastBlockHash, - LastBlockParts: cs.state.LastBlockParts, - ValidatorsHash: cs.state.Validators.Hash(), - AppHash: hash, - }, - LastValidation: validation, - Data: &types.Data{ - Txs: txs, - }, - } - block.FillHeader() - blockParts = block.MakePartSet() - - return block, blockParts -} - -// Enter: `timeoutPropose` after entering Propose. -// Enter: proposal block and POL is ready. -// Enter: any +2/3 prevotes for future round. -// Prevote for LockedBlock if we're locked, or ProposalBlock if valid. -// Otherwise vote nil. -func (cs *ConsensusState) EnterPrevote(height int, round int, timedOut bool) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPrevote <= cs.Step) { - log.Debug(Fmt("EnterPrevote(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - - // fire event for how we got here - if timedOut { - cs.evsw.FireEvent(types.EventStringTimeoutPropose(), cs.RoundStateEvent()) - } else if cs.isProposalComplete() { - cs.evsw.FireEvent(types.EventStringCompleteProposal(), cs.RoundStateEvent()) - } else { - // we received +2/3 prevotes for a future round - // TODO: catchup event? - } - - log.Info(Fmt("EnterPrevote(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Sign and broadcast vote as necessary - cs.doPrevote(height, round) - - // Done EnterPrevote: - cs.Round = round - cs.Step = RoundStepPrevote - cs.newStepCh <- cs.getRoundState() - - // Once `addVote` hits any +2/3 prevotes, we will go to PrevoteWait - // (so we have more time to try and collect +2/3 prevotes for a single block) -} - -func (cs *ConsensusState) doPrevote(height int, round int) { - // If a block is locked, prevote that. - if cs.LockedBlock != nil { - log.Info("EnterPrevote: Block was locked") - cs.signAddVote(types.VoteTypePrevote, cs.LockedBlock.Hash(), cs.LockedBlockParts.Header()) - return - } - - // If ProposalBlock is nil, prevote nil. - if cs.ProposalBlock == nil { - log.Warn("EnterPrevote: ProposalBlock is nil") - cs.signAddVote(types.VoteTypePrevote, nil, types.PartSetHeader{}) - return - } - - // Try staging cs.ProposalBlock - err := cs.stageBlock(cs.ProposalBlock, cs.ProposalBlockParts) - if err != nil { - // ProposalBlock is invalid, prevote nil. - log.Warn("EnterPrevote: ProposalBlock is invalid", "error", err) - cs.signAddVote(types.VoteTypePrevote, nil, types.PartSetHeader{}) - return - } - - // Prevote cs.ProposalBlock - // NOTE: the proposal signature is validated when it is received, - // and the proposal block parts are validated as they are received (against the merkle hash in the proposal) - cs.signAddVote(types.VoteTypePrevote, cs.ProposalBlock.Hash(), cs.ProposalBlockParts.Header()) - return -} - -// Enter: any +2/3 prevotes at next round. -func (cs *ConsensusState) EnterPrevoteWait(height int, round int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPrevoteWait <= cs.Step) { - log.Debug(Fmt("EnterPrevoteWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - if !cs.Votes.Prevotes(round).HasTwoThirdsAny() { - PanicSanity(Fmt("EnterPrevoteWait(%v/%v), but Prevotes does not have any +2/3 votes", height, round)) - } - log.Info(Fmt("EnterPrevoteWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Done EnterPrevoteWait: - cs.Round = round - cs.Step = RoundStepPrevoteWait - cs.newStepCh <- cs.getRoundState() - - // After `timeoutPrevote0+timeoutPrevoteDelta*round`, EnterPrecommit() - go func() { - time.Sleep(timeoutPrevote0 + timeoutPrevoteDelta*time.Duration(round)) - cs.EnterPrecommit(height, round, true) - }() -} - -// Enter: +2/3 precomits for block or nil. -// Enter: `timeoutPrevote` after any +2/3 prevotes. -// Enter: any +2/3 precommits for next round. -// Lock & precommit the ProposalBlock if we have enough prevotes for it (a POL in this round) -// else, unlock an existing lock and precommit nil if +2/3 of prevotes were nil, -// else, precommit nil otherwise. -func (cs *ConsensusState) EnterPrecommit(height int, round int, timedOut bool) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPrecommit <= cs.Step) { - log.Debug(Fmt("EnterPrecommit(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - - if timedOut { - cs.evsw.FireEvent(types.EventStringTimeoutWait(), cs.RoundStateEvent()) - } - - log.Info(Fmt("EnterPrecommit(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done EnterPrecommit: - cs.Round = round - cs.Step = RoundStepPrecommit - cs.newStepCh <- cs.getRoundState() - }() - - hash, partsHeader, ok := cs.Votes.Prevotes(round).TwoThirdsMajority() - - // If we don't have a polka, we must precommit nil - if !ok { - if cs.LockedBlock != nil { - log.Info("EnterPrecommit: No +2/3 prevotes during EnterPrecommit while we're locked. Precommitting nil") - } else { - log.Info("EnterPrecommit: No +2/3 prevotes during EnterPrecommit. Precommitting nil.") - } - cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) - return - } - - // At this point +2/3 prevoted for a particular block or nil - cs.evsw.FireEvent(types.EventStringPolka(), cs.RoundStateEvent()) - - // the latest POLRound should be this round - if cs.Votes.POLRound() < round { - PanicSanity(Fmt("This POLRound should be %v but got %", round, cs.Votes.POLRound())) - } - - // +2/3 prevoted nil. Unlock and precommit nil. - if len(hash) == 0 { - if cs.LockedBlock == nil { - log.Info("EnterPrecommit: +2/3 prevoted for nil.") - } else { - log.Info("EnterPrecommit: +2/3 prevoted for nil. Unlocking") - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - cs.evsw.FireEvent(types.EventStringUnlock(), cs.RoundStateEvent()) - } - cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) - return - } - - // At this point, +2/3 prevoted for a particular block. - - // If we're already locked on that block, precommit it, and update the LockedRound - if cs.LockedBlock.HashesTo(hash) { - log.Info("EnterPrecommit: +2/3 prevoted locked block. Relocking") - cs.LockedRound = round - cs.evsw.FireEvent(types.EventStringRelock(), cs.RoundStateEvent()) - cs.signAddVote(types.VoteTypePrecommit, hash, partsHeader) - return - } - - // If +2/3 prevoted for proposal block, stage and precommit it - if cs.ProposalBlock.HashesTo(hash) { - log.Info("EnterPrecommit: +2/3 prevoted proposal block. Locking", "hash", hash) - // Validate the block. - if err := cs.stageBlock(cs.ProposalBlock, cs.ProposalBlockParts); err != nil { - PanicConsensus(Fmt("EnterPrecommit: +2/3 prevoted for an invalid block: %v", err)) - } - cs.LockedRound = round - cs.LockedBlock = cs.ProposalBlock - cs.LockedBlockParts = cs.ProposalBlockParts - cs.evsw.FireEvent(types.EventStringLock(), cs.RoundStateEvent()) - cs.signAddVote(types.VoteTypePrecommit, hash, partsHeader) - return - } - - // There was a polka in this round for a block we don't have. - // Fetch that block, unlock, and precommit nil. - // The +2/3 prevotes for this round is the POL for our unlock. - // TODO: In the future save the POL prevotes for justification. - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - if !cs.ProposalBlockParts.HasHeader(partsHeader) { - cs.ProposalBlock = nil - cs.ProposalBlockParts = types.NewPartSetFromHeader(partsHeader) - } - cs.evsw.FireEvent(types.EventStringUnlock(), cs.RoundStateEvent()) - cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) - return -} - -// Enter: any +2/3 precommits for next round. -func (cs *ConsensusState) EnterPrecommitWait(height int, round int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPrecommitWait <= cs.Step) { - log.Debug(Fmt("EnterPrecommitWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - if !cs.Votes.Precommits(round).HasTwoThirdsAny() { - PanicSanity(Fmt("EnterPrecommitWait(%v/%v), but Precommits does not have any +2/3 votes", height, round)) - } - log.Info(Fmt("EnterPrecommitWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Done EnterPrecommitWait: - cs.Round = round - cs.Step = RoundStepPrecommitWait - cs.newStepCh <- cs.getRoundState() - - // After `timeoutPrecommit0+timeoutPrecommitDelta*round`, EnterNewRound() - go func() { - time.Sleep(timeoutPrecommit0 + timeoutPrecommitDelta*time.Duration(round)) - // If we have +2/3 of precommits for a particular block (or nil), - // we already entered commit (or the next round). - // So just try to transition to the next round, - // which is what we'd do otherwise. - cs.EnterNewRound(height, round+1, true) - }() -} - -// Enter: +2/3 precommits for block -func (cs *ConsensusState) EnterCommit(height int, commitRound int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || RoundStepCommit <= cs.Step { - log.Debug(Fmt("EnterCommit(%v/%v): Invalid args. Current step: %v/%v/%v", height, commitRound, cs.Height, cs.Round, cs.Step)) - return - } - log.Info(Fmt("EnterCommit(%v/%v). Current: %v/%v/%v", height, commitRound, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done Entercommit: - // keep ca.Round the same, it points to the right Precommits set. - cs.Step = RoundStepCommit - cs.CommitRound = commitRound - cs.newStepCh <- cs.getRoundState() - - // Maybe finalize immediately. - cs.tryFinalizeCommit(height) - }() - - hash, partsHeader, ok := cs.Votes.Precommits(commitRound).TwoThirdsMajority() - if !ok { - PanicSanity("RunActionCommit() expects +2/3 precommits") - } - - // The Locked* fields no longer matter. - // Move them over to ProposalBlock if they match the commit hash, - // otherwise they'll be cleared in updateToState. - if cs.LockedBlock.HashesTo(hash) { - cs.ProposalBlock = cs.LockedBlock - cs.ProposalBlockParts = cs.LockedBlockParts - } - - // If we don't have the block being committed, set up to get it. - if !cs.ProposalBlock.HashesTo(hash) { - if !cs.ProposalBlockParts.HasHeader(partsHeader) { - // We're getting the wrong block. - // Set up ProposalBlockParts and keep waiting. - cs.ProposalBlock = nil - cs.ProposalBlockParts = types.NewPartSetFromHeader(partsHeader) - } else { - // We just need to keep waiting. - } - } -} - -// If we have the block AND +2/3 commits for it, finalize. -func (cs *ConsensusState) tryFinalizeCommit(height int) { - if cs.Height != height { - PanicSanity(Fmt("tryFinalizeCommit() cs.Height: %v vs height: %v", cs.Height, height)) - } - - hash, _, ok := cs.Votes.Precommits(cs.CommitRound).TwoThirdsMajority() - if !ok || len(hash) == 0 { - log.Warn("Attempt to finalize failed. There was no +2/3 majority, or +2/3 was for <nil>.") - return - } - if !cs.ProposalBlock.HashesTo(hash) { - log.Warn("Attempt to finalize failed. We don't have the commit block.") - return - } - go cs.FinalizeCommit(height) -} - -// Increment height and goto RoundStepNewHeight -func (cs *ConsensusState) FinalizeCommit(height int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - if cs.Height != height || cs.Step != RoundStepCommit { - log.Debug(Fmt("FinalizeCommit(%v): Invalid args. Current step: %v/%v/%v", height, cs.Height, cs.Round, cs.Step)) - return - } - - hash, header, ok := cs.Votes.Precommits(cs.CommitRound).TwoThirdsMajority() - - if !ok { - PanicSanity(Fmt("Cannot FinalizeCommit, commit does not have two thirds majority")) - } - if !cs.ProposalBlockParts.HasHeader(header) { - PanicSanity(Fmt("Expected ProposalBlockParts header to be commit header")) - } - if !cs.ProposalBlock.HashesTo(hash) { - PanicSanity(Fmt("Cannot FinalizeCommit, ProposalBlock does not hash to commit hash")) - } - if err := cs.stageBlock(cs.ProposalBlock, cs.ProposalBlockParts); err != nil { - PanicConsensus(Fmt("+2/3 committed an invalid block: %v", err)) - } - - log.Info(Fmt("Finalizing commit of block: %v", cs.ProposalBlock)) - // We have the block, so stage/save/commit-vote. - cs.saveBlock(cs.ProposalBlock, cs.ProposalBlockParts, cs.Votes.Precommits(cs.CommitRound)) - // Increment height. - cs.updateToState(cs.stagedState) - // cs.StartTime is already set. - // Schedule Round0 to start soon. - go cs.scheduleRound0(height + 1) - - // By here, - // * cs.Height has been increment to height+1 - // * cs.Step is now RoundStepNewHeight - // * cs.StartTime is set to when we will start round0. - return -} - -//----------------------------------------------------------------------------- - -func (cs *ConsensusState) SetProposal(proposal *types.Proposal) error { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - // Already have one - if cs.Proposal != nil { - return nil - } - - // Does not apply - if proposal.Height != cs.Height || proposal.Round != cs.Round { - return nil - } - - // We don't care about the proposal if we're already in RoundStepCommit. - if RoundStepCommit <= cs.Step { - return nil - } - - // Verify POLRound, which must be -1 or between 0 and proposal.Round exclusive. - if proposal.POLRound != -1 && - (proposal.POLRound < 0 || proposal.Round <= proposal.POLRound) { - return ErrInvalidProposalPOLRound - } - - // Verify signature - if !cs.Validators.Proposer().PubKey.VerifyBytes(types.SignBytes(cs.state.ChainID, proposal), proposal.Signature) { - return ErrInvalidProposalSignature - } - - cs.Proposal = proposal - cs.ProposalBlockParts = types.NewPartSetFromHeader(proposal.BlockPartsHeader) - return nil -} - -// NOTE: block is not necessarily valid. -// This can trigger us to go into EnterPrevote asynchronously (before we timeout of propose) or to attempt to commit -func (cs *ConsensusState) AddProposalBlockPart(height int, part *types.Part) (added bool, err error) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - // Blocks might be reused, so round mismatch is OK - if cs.Height != height { - return false, nil - } - - // We're not expecting a block part. - if cs.ProposalBlockParts == nil { - return false, nil // TODO: bad peer? Return error? - } - - added, err = cs.ProposalBlockParts.AddPart(part) - if err != nil { - return added, err - } - if added && cs.ProposalBlockParts.IsComplete() { - // Added and completed! - var n int - var err error - cs.ProposalBlock = wire.ReadBinary(&types.Block{}, cs.ProposalBlockParts.GetReader(), types.MaxBlockSize, &n, &err).(*types.Block) - log.Info("Received complete proposal", "hash", cs.ProposalBlock.Hash()) - if cs.Step == RoundStepPropose && cs.isProposalComplete() { - // Move onto the next step - go cs.EnterPrevote(height, cs.Round, false) - } else if cs.Step == RoundStepCommit { - // If we're waiting on the proposal block... - cs.tryFinalizeCommit(height) - } - return true, err - } - return added, nil -} - -// Attempt to add the vote. if its a duplicate signature, dupeout the validator -func (cs *ConsensusState) TryAddVote(valIndex int, vote *types.Vote, peerKey string) (bool, error) { - added, _, err := cs.AddVote(valIndex, vote, peerKey) - if err != nil { - // If the vote height is off, we'll just ignore it, - // But if it's a conflicting sig, broadcast evidence tx for slashing. - // If it's otherwise invalid, punish peer. - if err == ErrVoteHeightMismatch { - return added, err - } else if _, ok := err.(*types.ErrVoteConflictingSignature); ok { - log.Warn("Found conflicting vote. Publish evidence") - /* TODO - evidenceTx := &types.DupeoutTx{ - Address: address, - VoteA: *errDupe.VoteA, - VoteB: *errDupe.VoteB, - } - cs.mempool.BroadcastTx(evidenceTx) // shouldn't need to check returned err - */ - return added, err - } else { - // Probably an invalid signature. Bad peer. - log.Warn("Error attempting to add vote", "error", err) - return added, ErrAddingVote - } - } - return added, nil -} - -func (cs *ConsensusState) AddVote(valIndex int, vote *types.Vote, peerKey string) (added bool, address []byte, err error) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - return cs.addVote(valIndex, vote, peerKey) -} - -//----------------------------------------------------------------------------- - -func (cs *ConsensusState) addVote(valIndex int, vote *types.Vote, peerKey string) (added bool, address []byte, err error) { - log.Debug("addVote", "voteHeight", vote.Height, "voteType", vote.Type, "csHeight", cs.Height) - - defer func() { - if added { - cs.evsw.FireEvent(types.EventStringVote(), &types.EventDataVote{valIndex, address, vote}) - } - }() - - // A precommit for the previous height? - if vote.Height+1 == cs.Height { - if !(cs.Step == RoundStepNewHeight && vote.Type == types.VoteTypePrecommit) { - // TODO: give the reason .. - // fmt.Errorf("TryAddVote: Wrong height, not a LastCommit straggler commit.") - return added, nil, ErrVoteHeightMismatch - } - added, address, err = cs.LastCommit.AddByIndex(valIndex, vote) - if added { - log.Info(Fmt("Added to lastPrecommits: %v", cs.LastCommit.StringShort())) - } - return - } - - // A prevote/precommit for this height? - if vote.Height == cs.Height { - height := cs.Height - added, address, err = cs.Votes.AddByIndex(valIndex, vote, peerKey) - if added { - switch vote.Type { - case types.VoteTypePrevote: - prevotes := cs.Votes.Prevotes(vote.Round) - log.Info("Added to prevote", "vote", vote, "prevotes", prevotes.StringShort()) - // First, unlock if prevotes is a valid POL. - // >> lockRound < POLRound <= unlockOrChangeLockRound (see spec) - // NOTE: If (lockRound < POLRound) but !(POLRound <= unlockOrChangeLockRound), - // we'll still EnterNewRound(H,vote.R) and EnterPrecommit(H,vote.R) to process it - // there. - if (cs.LockedBlock != nil) && (cs.LockedRound < vote.Round) && (vote.Round <= cs.Round) { - hash, _, ok := prevotes.TwoThirdsMajority() - if ok && !cs.LockedBlock.HashesTo(hash) { - log.Notice("Unlocking because of POL.", "lockedRound", cs.LockedRound, "POLRound", vote.Round) - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - cs.evsw.FireEvent(types.EventStringUnlock(), cs.RoundStateEvent()) - } - } - if cs.Round <= vote.Round && prevotes.HasTwoThirdsAny() { - // Round-skip over to PrevoteWait or goto Precommit. - go func() { - cs.EnterNewRound(height, vote.Round, false) - if prevotes.HasTwoThirdsMajority() { - cs.EnterPrecommit(height, vote.Round, false) - } else { - cs.EnterPrevote(height, vote.Round, false) - cs.EnterPrevoteWait(height, vote.Round) - } - }() - } else if cs.Proposal != nil && 0 <= cs.Proposal.POLRound && cs.Proposal.POLRound == vote.Round { - // If the proposal is now complete, enter prevote of cs.Round. - if cs.isProposalComplete() { - go cs.EnterPrevote(height, cs.Round, false) - } - } - case types.VoteTypePrecommit: - precommits := cs.Votes.Precommits(vote.Round) - log.Info("Added to precommit", "vote", vote, "precommits", precommits.StringShort()) - hash, _, ok := precommits.TwoThirdsMajority() - if ok { - go func() { - if len(hash) == 0 { - cs.EnterNewRound(height, vote.Round+1, false) - } else { - cs.EnterNewRound(height, vote.Round, false) - cs.EnterPrecommit(height, vote.Round, false) - cs.EnterCommit(height, vote.Round) - } - }() - } else if cs.Round <= vote.Round && precommits.HasTwoThirdsAny() { - go func() { - cs.EnterNewRound(height, vote.Round, false) - cs.EnterPrecommit(height, vote.Round, false) - cs.EnterPrecommitWait(height, vote.Round) - }() - } - default: - PanicSanity(Fmt("Unexpected vote type %X", vote.Type)) // Should not happen. - } - } - // Either duplicate, or error upon cs.Votes.AddByIndex() - return - } else { - err = ErrVoteHeightMismatch - } - - // Height mismatch, bad peer? - log.Info("Vote ignored and not added", "voteHeight", vote.Height, "csHeight", cs.Height) - return -} - -func (cs *ConsensusState) stageBlock(block *types.Block, blockParts *types.PartSet) error { - if block == nil { - PanicSanity("Cannot stage nil block") - } - - // Already staged? - blockHash := block.Hash() - if cs.stagedBlock != nil && len(blockHash) != 0 && bytes.Equal(cs.stagedBlock.Hash(), blockHash) { - return nil - } - - // Create a new event cache to cache all events. - cs.evc = events.NewEventCache(cs.evsw) - - // Create a copy of the state for staging - stateCopy := cs.state.Copy() - stateCopy.SetFireable(cs.evc) - - // Run the block on the State: - // + update validator sets - // + first rolls back proxyAppCtx - // + run txs on the proxyAppCtx or rollback - err := stateCopy.ExecBlock(cs.proxyAppCtx, block, blockParts.Header()) - if err != nil { - return err - } - - // Everything looks good! - cs.stagedBlock = block - cs.stagedState = stateCopy - return nil -} - -func (cs *ConsensusState) signVote(type_ byte, hash []byte, header types.PartSetHeader) (*types.Vote, error) { - vote := &types.Vote{ - Height: cs.Height, - Round: cs.Round, - Type: type_, - BlockHash: hash, - BlockPartsHeader: header, - } - err := cs.privValidator.SignVote(cs.state.ChainID, vote) - return vote, err -} - -func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.PartSetHeader) *types.Vote { - if cs.privValidator == nil || !cs.Validators.HasAddress(cs.privValidator.Address) { - return nil - } - vote, err := cs.signVote(type_, hash, header) - if err == nil { - // NOTE: store our index in the cs so we don't have to do this every time - valIndex, _ := cs.Validators.GetByAddress(cs.privValidator.Address) - _, _, err := cs.addVote(valIndex, vote, "") - log.Notice("Signed and added vote", "height", cs.Height, "round", cs.Round, "vote", vote, "error", err) - return vote - } else { - log.Warn("Error signing vote", "height", cs.Height, "round", cs.Round, "vote", vote, "error", err) - return nil - } -} - -// Save Block, save the +2/3 Commits we've seen -func (cs *ConsensusState) saveBlock(block *types.Block, blockParts *types.PartSet, commits *types.VoteSet) { - - // The proposal must be valid. - if err := cs.stageBlock(block, blockParts); err != nil { - PanicSanity(Fmt("saveBlock() an invalid block: %v", err)) - } - - // Save to blockStore. - if cs.blockStore.Height() < block.Height { - seenValidation := commits.MakeValidation() - cs.blockStore.SaveBlock(block, blockParts, seenValidation) - } - - // Commit to proxyAppCtx - err := cs.stagedState.Commit(cs.proxyAppCtx) - if err != nil { - // TODO: handle this gracefully. - PanicQ(Fmt("Commit failed for applicaiton")) - } - - // Save the state. - cs.stagedState.Save() - - // Update mempool. - cs.mempool.Update(block) - - // Fire off event - if cs.evsw != nil && cs.evc != nil { - cs.evsw.FireEvent(types.EventStringNewBlock(), types.EventDataNewBlock{block}) - go cs.evc.Flush() - } - -} - -// implements events.Eventable -func (cs *ConsensusState) SetFireable(evsw events.Fireable) { - cs.evsw = evsw -} - -func (cs *ConsensusState) String() string { - return Fmt("ConsensusState(H:%v R:%v S:%v", cs.Height, cs.Round, cs.Step) -} - -func CompareHRS(h1, r1 int, s1 RoundStepType, h2, r2 int, s2 RoundStepType) int { - if h1 < h2 { - return -1 - } else if h1 > h2 { - return 1 - } - if r1 < r2 { - return -1 - } else if r1 > r2 { - return 1 - } - if s1 < s2 { - return -1 - } else if s1 > s2 { - return 1 - } - return 0 -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state_test.go deleted file mode 100644 index 7ec75bb1..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state_test.go +++ /dev/null @@ -1,1186 +0,0 @@ -package consensus - -import ( - "bytes" - "fmt" - "testing" - "time" - - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - //"github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -/* - -ProposeSuite -x * TestProposerSelection0 - round robin ordering, round 0 -x * TestProposerSelection2 - round robin ordering, round 2++ -x * TestEnterProposeNoValidator - timeout into prevote round -x * TestEnterPropose - finish propose without timing out (we have the proposal) -x * TestBadProposal - 2 vals, bad proposal (bad block state hash), should prevote and precommit nil -FullRoundSuite -x * TestFullRound1 - 1 val, full successful round -x * TestFullRoundNil - 1 val, full round of nil -x * TestFullRound2 - 2 vals, both required for fuill round -LockSuite -x * TestLockNoPOL - 2 vals, 4 rounds. one val locked, precommits nil every round except first. -x * TestLockPOLRelock - 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka -x * TestLockPOLUnlock - 4 vals, one precommits, other 3 polka nil at next round, so we unlock and precomit nil -x * TestLockPOLSafety1 - 4 vals. We shouldn't change lock based on polka at earlier round -x * TestLockPOLSafety2 - 4 vals. After unlocking, we shouldn't relock based on polka at earlier round - * TestNetworkLock - once +1/3 precommits, network should be locked - * TestNetworkLockPOL - once +1/3 precommits, the block with more recent polka is committed -SlashingSuite -x * TestSlashingPrevotes - a validator prevoting twice in a round gets slashed -x * TestSlashingPrecommits - a validator precomitting twice in a round gets slashed -CatchupSuite - * TestCatchup - if we might be behind and we've seen any 2/3 prevotes, round skip to new round, precommit, or prevote -HaltSuite -x * TestHalt1 - if we see +2/3 precommits after timing out into new round, we should still commit - -*/ - -//---------------------------------------------------------------------------------------------------- -// ProposeSuite - -func init() { - fmt.Println("") - timeoutPropose = 500 * time.Millisecond -} - -func TestProposerSelection0(t *testing.T) { - cs1, vss := simpleConsensusState(3) // test needs more work for more than 3 validators - cs1.newStepCh = make(chan *RoundState) // so it blocks - height, round := cs1.Height, cs1.Round - - cs1.EnterNewRound(height, round, false) - - // lets commit a block and ensure proposer for the next height is correct - prop := cs1.Validators.Proposer() - if !bytes.Equal(prop.Address, cs1.privValidator.Address) { - t.Fatalf("expected proposer to be validator %d. Got %X", 0, prop.Address) - } - - waitFor(t, cs1, height, round, RoundStepPrevote) - - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vss[1:]...) - - waitFor(t, cs1, height, round, RoundStepPrecommit) - - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vss[1:]...) - - waitFor(t, cs1, height, round, RoundStepPrecommit) - waitFor(t, cs1, height, round+1, RoundStepPropose) - - prop = cs1.Validators.Proposer() - if !bytes.Equal(prop.Address, vss[1].Address) { - t.Fatalf("expected proposer to be validator %d. Got %X", 1, prop.Address) - } -} - -// Now let's do it all again, but starting from round 2 instead of 0 -func TestProposerSelection2(t *testing.T) { - cs1, vss := simpleConsensusState(3) // test needs more work for more than 3 validators - cs1.newStepCh = make(chan *RoundState) // so it blocks - - // this time we jump in at round 2 - incrementRound(vss[1:]...) - incrementRound(vss[1:]...) - cs1.EnterNewRound(cs1.Height, 2, false) - - // everyone just votes nil. we get a new proposer each round - for i := 0; i < len(vss); i++ { - prop := cs1.Validators.Proposer() - if !bytes.Equal(prop.Address, vss[(i+2)%len(vss)].Address) { - t.Fatalf("expected proposer to be validator %d. Got %X", (i+2)%len(vss), prop.Address) - } - nilRound(t, 2, cs1, vss[1:]...) - incrementRound(vss[1:]...) - } - -} - -// a non-validator should timeout into the prevote round -func TestEnterProposeNoPrivValidator(t *testing.T) { - cs, _ := simpleConsensusState(1) - cs.SetPrivValidator(nil) - height, round := cs.Height, cs.Round - - // Listen for propose timeout event - timeoutEventReceived := false - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutEventReceived = true - }) - cs.SetFireable(evsw) - - // starts a go routine for EnterPropose - cs.EnterNewRound(height, round, false) - - // Wait until the prevote step - waitFor(t, cs, height, round, RoundStepPrevote) - - // if we're not a validator, EnterPropose should timeout - if timeoutEventReceived == false { - t.Fatal("Expected EnterPropose to timeout") - } - if cs.GetRoundState().Proposal != nil { - t.Error("Expected to make no proposal, since no privValidator") - } -} - -// a validator should not timeout of the prevote round (TODO: unless the block is really big!) -func TestEnterPropose(t *testing.T) { - cs, _ := simpleConsensusState(1) - height, round := cs.Height, cs.Round - - // Listen for propose timeout event - timeoutEventReceived := false - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutEventReceived = true - }) - cs.SetFireable(evsw) - - // starts a go routine for EnterPropose - cs.EnterNewRound(height, round, false) - - // Wait until the prevote step - waitFor(t, cs, height, round, RoundStepPrevote) - - // Check that Proposal, ProposalBlock, ProposalBlockParts are set. - rs := cs.GetRoundState() - if rs.Proposal == nil { - t.Error("rs.Proposal should be set") - } - if rs.ProposalBlock == nil { - t.Error("rs.ProposalBlock should be set") - } - if rs.ProposalBlockParts.Total() == 0 { - t.Error("rs.ProposalBlockParts should be set") - } - - // if we're not a validator, EnterPropose should timeout - if timeoutEventReceived == true { - t.Fatal("Expected EnterPropose not to timeout") - } -} - -func TestBadProposal(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs1.newStepCh = make(chan *RoundState) // so it blocks - height, round := cs1.Height, cs1.Round - cs2 := vss[1] - - timeoutChan := make(chan struct{}) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - cs1.SetFireable(evsw) - - // make the second validator the proposer - propBlock := changeProposer(t, cs1, cs2) - - // make the block bad by tampering with statehash - stateHash := propBlock.AppHash - if len(stateHash) == 0 { - stateHash = make([]byte, 32) - } - stateHash[0] = byte((stateHash[0] + 1) % 255) - propBlock.AppHash = stateHash - propBlockParts := propBlock.MakePartSet() - proposal := types.NewProposal(cs2.Height, cs2.Round, propBlockParts.Header(), -1) - if err := cs2.SignProposal(chainID, proposal); err != nil { - t.Fatal("failed to sign bad proposal", err) - } - - // start round - cs1.EnterNewRound(height, round, false) - - // now we're on a new round and not the proposer - waitFor(t, cs1, height, round, RoundStepPropose) - // so set the proposal block (and fix voting power) - cs1.mtx.Lock() - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = proposal, propBlock, propBlockParts - fixVotingPower(t, cs1, vss[1].Address) - cs1.mtx.Unlock() - // and wait for timeout - <-timeoutChan - - // go to prevote, prevote for nil (proposal is bad) - waitFor(t, cs1, height, round, RoundStepPrevote) - - validatePrevote(t, cs1, round, vss[0], nil) - - // add bad prevote from cs2. we should precommit nil - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header()) - - waitFor(t, cs1, height, round, RoundStepPrevoteWait) - <-timeoutChan - waitFor(t, cs1, height, round, RoundStepPrecommit) - - validatePrecommit(t, cs1, round, 0, vss[0], nil, nil) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header()) -} - -//---------------------------------------------------------------------------------------------------- -// FullRoundSuite - -// propose, prevote, and precommit a block -func TestFullRound1(t *testing.T) { - cs, vss := simpleConsensusState(1) - height, round := cs.Height, cs.Round - - // starts a go routine for EnterPropose - cs.EnterNewRound(height, round, false) - - // wait to finish propose and prevote - waitFor(t, cs, height, round, RoundStepPrevote) - - // we should now be in precommit - // verify our prevote is there - cs.mtx.Lock() - propBlockHash := cs.ProposalBlock.Hash() - cs.mtx.Unlock() - - // Wait until Precommit - waitFor(t, cs, height, round, RoundStepPrecommit) - - // the proposed block should be prevoted, precommitted, and locked - validatePrevoteAndPrecommit(t, cs, round, round, vss[0], propBlockHash, propBlockHash) -} - -// nil is proposed, so prevote and precommit nil -func TestFullRoundNil(t *testing.T) { - cs, vss := simpleConsensusState(1) - height, round := cs.Height, cs.Round - - // Skip the propose step - cs.EnterPrevote(height, round, true) - - // Wait until Precommit - waitFor(t, cs, height, round, RoundStepPrecommit) - - // should prevote and precommit nil - validatePrevoteAndPrecommit(t, cs, round, 0, vss[0], nil, nil) -} - -// run through propose, prevote, precommit commit with two validators -// where the first validator has to wait for votes from the second -func TestFullRound2(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs2 := vss[1] - cs1.newStepCh = make(chan *RoundState) // so it blocks - height, round := cs1.Height, cs1.Round - - // start round and wait for propose and prevote - cs1.EnterNewRound(height, round, false) - waitFor(t, cs1, height, round, RoundStepPrevote) - - // we should now be stuck in limbo forever, waiting for more prevotes - ensureNoNewStep(t, cs1) - - propBlockHash, propPartsHeader := cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header() - - // prevote arrives from cs2: - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, propBlockHash, propPartsHeader) - - // wait to finish precommit - waitFor(t, cs1, cs1.Height, 0, RoundStepPrecommit) - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], propBlockHash, propBlockHash) - - // we should now be stuck in limbo forever, waiting for more precommits - ensureNoNewStep(t, cs1) - - // precommit arrives from cs2: - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, propBlockHash, propPartsHeader) - - // wait to finish commit, propose in next height - waitFor(t, cs1, height+1, 0, RoundStepNewHeight) -} - -//------------------------------------------------------------------------------------------ -// LockSuite - -// two validators, 4 rounds. -// val1 proposes the first 2 rounds, and is locked in the first. -// val2 proposes the next two. val1 should precommit nil on all (except first where he locks) -func TestLockNoPOL(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs2 := vss[1] - cs1.newStepCh = make(chan *RoundState) // so it blocks - height := cs1.Height - - timeoutChan := make(chan struct{}) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - cs1.SetFireable(evsw) - - /* - Round1 (cs1, B) // B B // B B2 - */ - - // start round and wait for propose and prevote - cs1.EnterNewRound(height, 0, false) - waitFor(t, cs1, height, 0, RoundStepPrevote) - - // we should now be stuck in limbo forever, waiting for more prevotes - // prevote arrives from cs2: - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - - cs1.mtx.Lock() // XXX: sigh - theBlockHash := cs1.ProposalBlock.Hash() - cs1.mtx.Unlock() - - // wait to finish precommit - waitFor(t, cs1, height, 0, RoundStepPrecommit) - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - // we should now be stuck in limbo forever, waiting for more precommits - // lets add one for a different block - // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round - hash := cs1.ProposalBlock.Hash() - hash[0] = byte((hash[0] + 1) % 255) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // (note we're entering precommit for a second time this round) - // but with invalid args. then we EnterPrecommitWait, and the timeout to new round - waitFor(t, cs1, height, 0, RoundStepPrecommitWait) - <-timeoutChan - - log.Info("#### ONTO ROUND 2") - /* - Round2 (cs1, B) // B B2 - */ - - incrementRound(cs2) - - // now we're on a new round and not the proposer, so wait for timeout - waitFor(t, cs1, height, 1, RoundStepPropose) - <-timeoutChan - - if cs1.ProposalBlock != nil { - t.Fatal("Expected proposal block to be nil") - } - - // wait to finish prevote - waitFor(t, cs1, height, 1, RoundStepPrevote) - - // we should have prevoted our locked block - validatePrevote(t, cs1, 1, vss[0], cs1.LockedBlock.Hash()) - - // add a conflicting prevote from the other validator - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // now we're going to enter prevote again, but with invalid args - // and then prevote wait, which should timeout. then wait for precommit - waitFor(t, cs1, height, 1, RoundStepPrevoteWait) - <-timeoutChan - waitFor(t, cs1, height, 1, RoundStepPrecommit) - - // the proposed block should still be locked and our precommit added - // we should precommit nil and be locked on the proposal - validatePrecommit(t, cs1, 1, 0, vss[0], nil, theBlockHash) - - // add conflicting precommit from cs2 - // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // (note we're entering precommit for a second time this round, but with invalid args - // then we EnterPrecommitWait and timeout into NewRound - waitFor(t, cs1, height, 1, RoundStepPrecommitWait) - <-timeoutChan - - log.Info("#### ONTO ROUND 3") - /* - Round3 (cs2, _) // B, B2 - */ - - incrementRound(cs2) - - waitFor(t, cs1, height, 2, RoundStepPropose) - - // now we're on a new round and are the proposer - if cs1.ProposalBlock != cs1.LockedBlock { - t.Fatalf("Expected proposal block to be locked block. Got %v, Expected %v", cs1.ProposalBlock, cs1.LockedBlock) - } - - // go to prevote, prevote for locked block - waitFor(t, cs1, height, 2, RoundStepPrevote) - - validatePrevote(t, cs1, 0, vss[0], cs1.LockedBlock.Hash()) - - // TODO: quick fastforward to new round, set proposer - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - waitFor(t, cs1, height, 2, RoundStepPrevoteWait) - <-timeoutChan - waitFor(t, cs1, height, 2, RoundStepPrecommit) - - validatePrecommit(t, cs1, 2, 0, vss[0], nil, theBlockHash) // precommit nil but be locked on proposal - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) // NOTE: conflicting precommits at same height - - waitFor(t, cs1, height, 2, RoundStepPrecommitWait) - - // before we time out into new round, set next proposal block - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - if prop == nil || propBlock == nil { - t.Fatal("Failed to create proposal block with cs2") - } - - incrementRound(cs2) - - <-timeoutChan - - log.Info("#### ONTO ROUND 4") - /* - Round4 (cs2, C) // B C // B C - */ - - // now we're on a new round and not the proposer - waitFor(t, cs1, height, 3, RoundStepPropose) - - // so set the proposal block - cs1.mtx.Lock() - cs1.Proposal, cs1.ProposalBlock = prop, propBlock - cs1.mtx.Unlock() - - // and wait for timeout - <-timeoutChan - // go to prevote, prevote for locked block (not proposal) - waitFor(t, cs1, height, 3, RoundStepPrevote) - - validatePrevote(t, cs1, 0, vss[0], cs1.LockedBlock.Hash()) - - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header()) - - waitFor(t, cs1, height, 3, RoundStepPrevoteWait) - <-timeoutChan - waitFor(t, cs1, height, 3, RoundStepPrecommit) - - validatePrecommit(t, cs1, 2, 0, vss[0], nil, theBlockHash) // precommit nil but locked on proposal - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header()) // NOTE: conflicting precommits at same height -} - -// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka -func TestLockPOLRelock(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan *types.EventDataRoundState) - voteChan := make(chan *types.EventDataVote) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) { - vote := data.(*types.EventDataVote) - // we only fire for our own votes - if bytes.Equal(cs1.privValidator.Address, vote.Address) { - voteChan <- vote - } - }) - cs1.SetFireable(evsw) - - // everything done from perspective of cs1 - - /* - Round1 (cs1, B) // B B B B// B nil B nil - - eg. cs2 and cs4 didn't see the 2/3 prevotes - */ - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh() - - theBlockHash := cs1.ProposalBlock.Hash() - - // wait to finish precommit after prevotes done - // we do this in a go routine with another channel since otherwise - // we may get deadlock with EnterPrecommit waiting to send on newStepCh and the final - // signAddVoteToFrom waiting for the cs.mtx.Lock - donePrecommit := make(chan struct{}) - go func() { - <-voteChan - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - donePrecommitWait := make(chan struct{}) - go func() { - // (note we're entering precommit for a second time this round) - // but with invalid args. then we EnterPrecommitWait, twice (?) - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - // add precommits from the rest - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - <-donePrecommitWait - - // before we time out into new round, set next proposer - // and next proposal block - _, v1 := cs1.Validators.GetByAddress(vss[0].Address) - v1.VotingPower = 1 - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - - incrementRound(cs2, cs3, cs4) - - // timeout to new round - te := <-timeoutChan - if te.Step != RoundStepPrecommitWait.String() { - t.Fatalf("expected to timeout of precommit into new round. got %v", te.Step) - } - - log.Info("### ONTO ROUND 2") - - /* - Round2 (cs2, C) // B C C C // C C C _) - - cs1 changes lock! - */ - - // now we're on a new round and not the proposer - <-cs1.NewStepCh() - cs1.mtx.Lock() - // so set the proposal block - propBlockHash, propBlockParts := propBlock.Hash(), propBlock.MakePartSet() - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlockParts - cs1.mtx.Unlock() - // and wait for timeout - te = <-timeoutChan - if te.Step != RoundStepPropose.String() { - t.Fatalf("expected to timeout of propose. got %v", te.Step) - } - // go to prevote, prevote for locked block (not proposal), move on - _, _ = <-voteChan, <-cs1.NewStepCh() - validatePrevote(t, cs1, 0, vss[0], theBlockHash) - - donePrecommit = make(chan struct{}) - go func() { - // we need this go routine because if we go into PrevoteWait it has to pull on newStepCh - // before the final vote will get added (because it holds the mutex). - select { - case <-cs1.NewStepCh(): // we're in PrevoteWait, go to Precommit - <-voteChan - case <-voteChan: // we went straight to Precommit - } - donePrecommit <- struct{}{} - }() - // now lets add prevotes from everyone else for the new block - signAddVoteToFromMany(types.VoteTypePrevote, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // we should have unlocked and locked on the new block - validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash) - - donePrecommitWait = make(chan struct{}) - go func() { - // (note we're entering precommit for a second time this round) - // but with invalid args. then we EnterPrecommitWait, - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3) - <-donePrecommitWait - - <-cs1.NewStepCh() - rs := <-cs1.NewStepCh() - if rs.Height != 2 { - t.Fatal("Expected height to increment") - } - - if hash, _, ok := rs.LastCommit.TwoThirdsMajority(); !ok || !bytes.Equal(hash, propBlockHash) { - t.Fatal("Expected block to get committed") - } -} - -// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka -func TestLockPOLUnlock(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan *types.EventDataRoundState) - voteChan := make(chan *types.EventDataVote) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) { - vote := data.(*types.EventDataVote) - // we only fire for our own votes - if bytes.Equal(cs1.privValidator.Address, vote.Address) { - voteChan <- vote - } - }) - cs1.SetFireable(evsw) - - // everything done from perspective of cs1 - - /* - Round1 (cs1, B) // B B B B // B nil B nil - - eg. didn't see the 2/3 prevotes - */ - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh() - - theBlockHash := cs1.ProposalBlock.Hash() - - donePrecommit := make(chan struct{}) - go func() { - <-voteChan - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - donePrecommitWait := make(chan struct{}) - go func() { - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - // add precommits from the rest - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - <-donePrecommitWait - - // before we time out into new round, set next proposer - // and next proposal block - _, v1 := cs1.Validators.GetByAddress(vss[0].Address) - v1.VotingPower = 1 - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - - incrementRound(cs2, cs3, cs4) - - // timeout to new round - <-timeoutChan - - log.Info("#### ONTO ROUND 2") - /* - Round2 (cs2, C) // B nil nil nil // nil nil nil _ - - cs1 unlocks! - */ - - // now we're on a new round and not the proposer, - <-cs1.NewStepCh() - cs1.mtx.Lock() - // so set the proposal block - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlock.MakePartSet() - lockedBlockHash := cs1.LockedBlock.Hash() - cs1.mtx.Unlock() - // and wait for timeout - <-timeoutChan - - // go to prevote, prevote for locked block (not proposal) - _, _ = <-voteChan, <-cs1.NewStepCh() - validatePrevote(t, cs1, 0, vss[0], lockedBlockHash) - - donePrecommit = make(chan struct{}) - go func() { - select { - case <-cs1.NewStepCh(): // we're in PrevoteWait, go to Precommit - <-voteChan - case <-voteChan: // we went straight to Precommit - } - donePrecommit <- struct{}{} - }() - // now lets add prevotes from everyone else for the new block - signAddVoteToFromMany(types.VoteTypePrevote, cs1, nil, types.PartSetHeader{}, cs2, cs3, cs4) - <-donePrecommit - - // we should have unlocked - // NOTE: we don't lock on nil, so LockedRound is still 0 - validatePrecommit(t, cs1, 1, 0, vss[0], nil, nil) - - donePrecommitWait = make(chan struct{}) - go func() { - // the votes will bring us to new round right away - // we should timeout of it - _, _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh(), <-timeoutChan - donePrecommitWait <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3) - <-donePrecommitWait -} - -// 4 vals -// a polka at round 1 but we miss it -// then a polka at round 2 that we lock on -// then we see the polka from round 1 but shouldn't unlock -func TestLockPOLSafety1(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan *types.EventDataRoundState) - voteChan := make(chan *types.EventDataVote) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) { - vote := data.(*types.EventDataVote) - // we only fire for our own votes - if bytes.Equal(cs1.privValidator.Address, vote.Address) { - voteChan <- vote - } - }) - cs1.SetFireable(evsw) - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh() - - propBlock := cs1.ProposalBlock - - validatePrevote(t, cs1, 0, vss[0], cs1.ProposalBlock.Hash()) - - // the others sign a polka but we don't see it - prevotes := signVoteMany(types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet().Header(), cs2, cs3, cs4) - - // before we time out into new round, set next proposer - // and next proposal block - _, v1 := cs1.Validators.GetByAddress(vss[0].Address) - v1.VotingPower = 1 - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - - log.Warn("old prop", "hash", fmt.Sprintf("%X", propBlock.Hash())) - - // we do see them precommit nil - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3, cs4) - - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - - incrementRound(cs2, cs3, cs4) - - log.Info("### ONTO ROUND 2") - /*Round2 - // we timeout and prevote our lock - // a polka happened but we didn't see it! - */ - - // now we're on a new round and not the proposer, - <-cs1.NewStepCh() - // so set proposal - cs1.mtx.Lock() - propBlockHash, propBlockParts := propBlock.Hash(), propBlock.MakePartSet() - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlockParts - cs1.mtx.Unlock() - // and wait for timeout - <-timeoutChan - if cs1.LockedBlock != nil { - t.Fatal("we should not be locked!") - } - log.Warn("new prop", "hash", fmt.Sprintf("%X", propBlockHash)) - // go to prevote, prevote for proposal block - _, _ = <-voteChan, <-cs1.NewStepCh() - validatePrevote(t, cs1, 1, vss[0], propBlockHash) - - // now we see the others prevote for it, so we should lock on it - donePrecommit := make(chan struct{}) - go func() { - select { - case <-cs1.NewStepCh(): // we're in PrevoteWait, go to Precommit - <-voteChan - case <-voteChan: // we went straight to Precommit - } - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - // now lets add prevotes from everyone else for nil - signAddVoteToFromMany(types.VoteTypePrevote, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // we should have precommitted - validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash) - - // now we see precommits for nil - donePrecommitWait := make(chan struct{}) - go func() { - // the votes will bring us to new round - // we should timeut of it and go to prevote - <-cs1.NewStepCh() - <-timeoutChan - donePrecommitWait <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3) - <-donePrecommitWait - - incrementRound(cs2, cs3, cs4) - - log.Info("### ONTO ROUND 3") - /*Round3 - we see the polka from round 1 but we shouldn't unlock! - */ - - // timeout of propose - _, _ = <-cs1.NewStepCh(), <-timeoutChan - - // finish prevote - _, _ = <-voteChan, <-cs1.NewStepCh() - - // we should prevote what we're locked on - validatePrevote(t, cs1, 2, vss[0], propBlockHash) - - // add prevotes from the earlier round - addVoteToFromMany(cs1, prevotes, cs2, cs3, cs4) - - log.Warn("Done adding prevotes!") - - ensureNoNewStep(t, cs1) -} - -// 4 vals. -// polka P1 at R1, P2 at R2, and P3 at R3, -// we lock on P1 at R1, don't see P2, and unlock using P3 at R3 -// then we should make sure we don't lock using P2 -func TestLockPOLSafety2(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan *types.EventDataRoundState) - voteChan := make(chan *types.EventDataVote) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) { - vote := data.(*types.EventDataVote) - // we only fire for our own votes - if bytes.Equal(cs1.privValidator.Address, vote.Address) { - voteChan <- vote - } - }) - cs1.SetFireable(evsw) - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh() - - theBlockHash := cs1.ProposalBlock.Hash() - - donePrecommit := make(chan struct{}) - go func() { - <-voteChan - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - donePrecommitWait := make(chan struct{}) - go func() { - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - // add precommits from the rest - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - <-donePrecommitWait - - // before we time out into new round, set next proposer - // and next proposal block - _, v1 := cs1.Validators.GetByAddress(vss[0].Address) - v1.VotingPower = 1 - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - - incrementRound(cs2, cs3, cs4) - - // timeout to new round - <-timeoutChan - - log.Info("### ONTO Round 2") - /*Round2 - // we timeout and prevote our lock - // a polka happened but we didn't see it! - */ - - // now we're on a new round and not the proposer, so wait for timeout - _, _ = <-cs1.NewStepCh(), <-timeoutChan - // go to prevote, prevote for locked block - _, _ = <-voteChan, <-cs1.NewStepCh() - validatePrevote(t, cs1, 0, vss[0], cs1.LockedBlock.Hash()) - - // the others sign a polka but we don't see it - prevotes := signVoteMany(types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet().Header(), cs2, cs3, cs4) - - // once we see prevotes for the next round we'll skip ahead - - incrementRound(cs2, cs3, cs4) - - log.Info("### ONTO Round 3") - /*Round3 - a polka for nil causes us to unlock - */ - - // these prevotes will send us straight to precommit at the higher round - donePrecommit = make(chan struct{}) - go func() { - select { - case <-cs1.NewStepCh(): // we're in PrevoteWait, go to Precommit - <-voteChan - case <-voteChan: // we went straight to Precommit - } - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - // now lets add prevotes from everyone else for nil - signAddVoteToFromMany(types.VoteTypePrevote, cs1, nil, types.PartSetHeader{}, cs2, cs3, cs4) - <-donePrecommit - - // we should have unlocked - // NOTE: we don't lock on nil, so LockedRound is still 0 - validatePrecommit(t, cs1, 2, 0, vss[0], nil, nil) - - donePrecommitWait = make(chan struct{}) - go func() { - // the votes will bring us to new round right away - // we should timeut of it and go to prevote - <-cs1.NewStepCh() - // set the proposal block to be that which got a polka in R2 - cs1.mtx.Lock() - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlock.MakePartSet() - cs1.mtx.Unlock() - // timeout into prevote, finish prevote - _, _, _ = <-timeoutChan, <-voteChan, <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3) - <-donePrecommitWait - - log.Info("### ONTO ROUND 4") - /*Round4 - we see the polka from R2 - make sure we don't lock because of it! - */ - // new round and not proposer - // (we already timed out and stepped into prevote) - - log.Warn("adding prevotes from round 2") - - addVoteToFromMany(cs1, prevotes, cs2, cs3, cs4) - - log.Warn("Done adding prevotes!") - - // we should prevote it now - validatePrevote(t, cs1, 3, vss[0], cs1.ProposalBlock.Hash()) - - // but we shouldn't precommit it - precommits := cs1.Votes.Precommits(3) - vote := precommits.GetByIndex(0) - if vote != nil { - t.Fatal("validator precommitted at round 4 based on an old polka") - } -} - -//------------------------------------------------------------------------------------------ -// SlashingSuite - -func TestSlashingPrevotes(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs2 := vss[1] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh() - - // we should now be stuck in limbo forever, waiting for more prevotes - // add one for a different block should cause us to go into prevote wait - hash := cs1.ProposalBlock.Hash() - hash[0] = byte(hash[0]+1) % 255 - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // pass prevote wait - <-cs1.NewStepCh() - - // NOTE: we have to send the vote for different block first so we don't just go into precommit round right - // away and ignore more prevotes (and thus fail to slash!) - - // add the conflicting vote - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - - // XXX: Check for existence of Dupeout info -} - -func TestSlashingPrecommits(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs2 := vss[1] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh() - - // add prevote from cs2 - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - - // wait to finish precommit - <-cs1.NewStepCh() - - // we should now be stuck in limbo forever, waiting for more prevotes - // add one for a different block should cause us to go into prevote wait - hash := cs1.ProposalBlock.Hash() - hash[0] = byte(hash[0]+1) % 255 - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // pass prevote wait - <-cs1.NewStepCh() - - // NOTE: we have to send the vote for different block first so we don't just go into precommit round right - // away and ignore more prevotes (and thus fail to slash!) - - // add precommit from cs2 - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - - // XXX: Check for existence of Dupeout info -} - -//------------------------------------------------------------------------------------------ -// CatchupSuite - -//------------------------------------------------------------------------------------------ -// HaltSuite - -// 4 vals. -// we receive a final precommit after going into next round, but others might have gone to commit already! -func TestHalt1(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan struct{}) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - cs1.SetFireable(evsw) - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh() - - theBlockHash := cs1.ProposalBlock.Hash() - - donePrecommit := make(chan struct{}) - go func() { - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs3, cs4) - <-donePrecommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - donePrecommitWait := make(chan struct{}) - go func() { - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - // add precommits from the rest - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, nil, types.PartSetHeader{}) // didnt receive proposal - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - // we receive this later, but cs3 might receive it earlier and with ours will go to commit! - precommit4 := signVote(cs4, types.VoteTypePrecommit, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - <-donePrecommitWait - - incrementRound(cs2, cs3, cs4) - - // timeout to new round - <-timeoutChan - - log.Info("### ONTO ROUND 2") - /*Round2 - // we timeout and prevote our lock - // a polka happened but we didn't see it! - */ - - // go to prevote, prevote for locked block - _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh() - validatePrevote(t, cs1, 0, vss[0], cs1.LockedBlock.Hash()) - - // now we receive the precommit from the previous round - addVoteToFrom(cs1, cs4, precommit4) - - // receiving that precommit should take us straight to commit - ensureNewStep(t, cs1) - log.Warn("done enter commit!") - - // update to state - ensureNewStep(t, cs1) - - if cs1.Height != 2 { - t.Fatal("expected height to increment") - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/event_cache.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/event_cache.go deleted file mode 100644 index c37793f9..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/event_cache.go +++ /dev/null @@ -1,45 +0,0 @@ -package events - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - eventsBufferSize = 1000 -) - -// An EventCache buffers events for a Fireable -// All events are cached. Filtering happens on Flush -type EventCache struct { - evsw Fireable - events []eventInfo -} - -// Create a new EventCache with an EventSwitch as backend -func NewEventCache(evsw Fireable) *EventCache { - return &EventCache{ - evsw: evsw, - events: make([]eventInfo, eventsBufferSize), - } -} - -// a cached event -type eventInfo struct { - event string - data types.EventData -} - -// Cache an event to be fired upon finality. -func (evc *EventCache) FireEvent(event string, data types.EventData) { - // append to list - evc.events = append(evc.events, eventInfo{event, data}) -} - -// Fire events by running evsw.FireEvent on all cached events. Blocks. -// Clears cached events -func (evc *EventCache) Flush() { - for _, ei := range evc.events { - evc.evsw.FireEvent(ei.event, ei.data) - } - evc.events = make([]eventInfo, eventsBufferSize) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go deleted file mode 100644 index 0ee25b18..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go +++ /dev/null @@ -1,205 +0,0 @@ -package events - -import ( - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -// reactors and other modules should export -// this interface to become eventable -type Eventable interface { - SetFireable(Fireable) -} - -// an event switch or cache implements fireable -type Fireable interface { - FireEvent(event string, data types.EventData) -} - -type EventSwitch struct { - BaseService - - mtx sync.RWMutex - eventCells map[string]*eventCell - listeners map[string]*eventListener -} - -func NewEventSwitch() *EventSwitch { - evsw := &EventSwitch{} - evsw.BaseService = *NewBaseService(log, "EventSwitch", evsw) - return evsw -} - -func (evsw *EventSwitch) OnStart() error { - evsw.BaseService.OnStart() - evsw.eventCells = make(map[string]*eventCell) - evsw.listeners = make(map[string]*eventListener) - return nil -} - -func (evsw *EventSwitch) OnStop() { - evsw.BaseService.OnStop() - evsw.eventCells = nil - evsw.listeners = nil -} - -func (evsw *EventSwitch) AddListenerForEvent(listenerID, event string, cb eventCallback) { - // Get/Create eventCell and listener - evsw.mtx.Lock() - eventCell := evsw.eventCells[event] - if eventCell == nil { - eventCell = newEventCell() - evsw.eventCells[event] = eventCell - } - listener := evsw.listeners[listenerID] - if listener == nil { - listener = newEventListener(listenerID) - evsw.listeners[listenerID] = listener - } - evsw.mtx.Unlock() - - // Add event and listener - eventCell.AddListener(listenerID, cb) - listener.AddEvent(event) -} - -func (evsw *EventSwitch) RemoveListener(listenerID string) { - // Get and remove listener - evsw.mtx.RLock() - listener := evsw.listeners[listenerID] - delete(evsw.listeners, listenerID) - evsw.mtx.RUnlock() - - if listener == nil { - return - } - - // Remove callback for each event. - listener.SetRemoved() - for _, event := range listener.GetEvents() { - evsw.RemoveListenerForEvent(event, listenerID) - } -} - -func (evsw *EventSwitch) RemoveListenerForEvent(event string, listenerID string) { - // Get eventCell - evsw.mtx.Lock() - eventCell := evsw.eventCells[event] - evsw.mtx.Unlock() - - if eventCell == nil { - return - } - - // Remove listenerID from eventCell - numListeners := eventCell.RemoveListener(listenerID) - - // Maybe garbage collect eventCell. - if numListeners == 0 { - // Lock again and double check. - evsw.mtx.Lock() // OUTER LOCK - eventCell.mtx.Lock() // INNER LOCK - if len(eventCell.listeners) == 0 { - delete(evsw.eventCells, event) - } - eventCell.mtx.Unlock() // INNER LOCK - evsw.mtx.Unlock() // OUTER LOCK - } -} - -func (evsw *EventSwitch) FireEvent(event string, data types.EventData) { - // Get the eventCell - evsw.mtx.RLock() - eventCell := evsw.eventCells[event] - evsw.mtx.RUnlock() - - if eventCell == nil { - return - } - - // Fire event for all listeners in eventCell - eventCell.FireEvent(data) -} - -//----------------------------------------------------------------------------- - -// eventCell handles keeping track of listener callbacks for a given event. -type eventCell struct { - mtx sync.RWMutex - listeners map[string]eventCallback -} - -func newEventCell() *eventCell { - return &eventCell{ - listeners: make(map[string]eventCallback), - } -} - -func (cell *eventCell) AddListener(listenerID string, cb eventCallback) { - cell.mtx.Lock() - cell.listeners[listenerID] = cb - cell.mtx.Unlock() -} - -func (cell *eventCell) RemoveListener(listenerID string) int { - cell.mtx.Lock() - delete(cell.listeners, listenerID) - numListeners := len(cell.listeners) - cell.mtx.Unlock() - return numListeners -} - -func (cell *eventCell) FireEvent(data types.EventData) { - cell.mtx.RLock() - for _, listener := range cell.listeners { - listener(data) - } - cell.mtx.RUnlock() -} - -//----------------------------------------------------------------------------- - -type eventCallback func(data types.EventData) - -type eventListener struct { - id string - - mtx sync.RWMutex - removed bool - events []string -} - -func newEventListener(id string) *eventListener { - return &eventListener{ - id: id, - removed: false, - events: nil, - } -} - -func (evl *eventListener) AddEvent(event string) { - evl.mtx.Lock() - defer evl.mtx.Unlock() - - if evl.removed { - return - } - evl.events = append(evl.events, event) -} - -func (evl *eventListener) GetEvents() []string { - evl.mtx.RLock() - defer evl.mtx.RUnlock() - - events := make([]string, len(evl.events)) - copy(events, evl.events) - return events -} - -func (evl *eventListener) SetRemoved() { - evl.mtx.Lock() - defer evl.mtx.Unlock() - evl.removed = true -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go deleted file mode 100644 index 8226fc66..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package events - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "events") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go deleted file mode 100644 index e6248998..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package mempool - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go deleted file mode 100644 index 8fdf5aa2..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package mempool - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "mempool") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool.go deleted file mode 100644 index 5a6d5cf7..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool.go +++ /dev/null @@ -1,226 +0,0 @@ -package mempool - -import ( - "bytes" - "sync" - "sync/atomic" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-clist" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -/* - -The mempool pushes new txs onto the proxyAppCtx. -It gets a stream of (req, res) tuples from the proxy. -The memool stores good txs in a concurrent linked-list. - -Multiple concurrent go-routines can traverse this linked-list -safely by calling .NextWait() on each element. - -So we have several go-routines: -1. Consensus calling Update() and Reap() synchronously -2. Many mempool reactor's peer routines calling AppendTx() -3. Many mempool reactor's peer routines traversing the txs linked list -4. Another goroutine calling GarbageCollectTxs() periodically - -To manage these goroutines, there are three methods of locking. -1. Mutations to the linked-list is protected by an internal mtx (CList is goroutine-safe) -2. Mutations to the linked-list elements are atomic -3. AppendTx() calls can be paused upon Update() and Reap(), protected by .proxyMtx - -Garbage collection of old elements from mempool.txs is handlde via -the DetachPrev() call, which makes old elements not reachable by -peer broadcastTxRoutine() automatically garbage collected. - - - -*/ - -type Mempool struct { - proxyMtx sync.Mutex - proxyAppCtx proxy.AppContext - txs *clist.CList // concurrent linked-list of good txs - counter int64 // simple incrementing counter - height int // the last block Update()'d to - expected *clist.CElement // pointer to .txs for next response -} - -func NewMempool(proxyAppCtx proxy.AppContext) *Mempool { - mempool := &Mempool{ - proxyAppCtx: proxyAppCtx, - txs: clist.New(), - counter: 0, - height: 0, - expected: nil, - } - proxyAppCtx.SetResponseCallback(mempool.resCb) - return mempool -} - -// Return the first element of mem.txs for peer goroutines to call .NextWait() on. -// Blocks until txs has elements. -func (mem *Mempool) TxsFrontWait() *clist.CElement { - return mem.txs.FrontWait() -} - -// Try a new transaction in the mempool. -// Potentially blocking if we're blocking on Update() or Reap(). -func (mem *Mempool) AppendTx(tx types.Tx) (err error) { - mem.proxyMtx.Lock() - defer mem.proxyMtx.Unlock() - - if err = mem.proxyAppCtx.Error(); err != nil { - return err - } - mem.proxyAppCtx.AppendTxAsync(tx) - return nil -} - -// TMSP callback function -// CONTRACT: No other goroutines mutate mem.expected concurrently. -func (mem *Mempool) resCb(req tmsp.Request, res tmsp.Response) { - switch res := res.(type) { - case tmsp.ResponseAppendTx: - reqAppendTx := req.(tmsp.RequestAppendTx) - if mem.expected == nil { // Normal operation - if res.RetCode == tmsp.RetCodeOK { - mem.counter++ - memTx := &mempoolTx{ - counter: mem.counter, - height: int64(mem.height), - tx: reqAppendTx.TxBytes, - } - mem.txs.PushBack(memTx) - } else { - // ignore bad transaction - // TODO: handle other retcodes - } - } else { // During Update() - // TODO Log sane warning if mem.expected is nil. - memTx := mem.expected.Value.(*mempoolTx) - if !bytes.Equal(reqAppendTx.TxBytes, memTx.tx) { - PanicSanity("Unexpected tx response from proxy") - } - if res.RetCode == tmsp.RetCodeOK { - // Good, nothing to do. - } else { - // TODO: handle other retcodes - // Tx became invalidated due to newly committed block. - // NOTE: Concurrent traversal of mem.txs via CElement.Next() still works. - mem.txs.Remove(mem.expected) - mem.expected.DetachPrev() - } - mem.expected = mem.expected.Next() - } - default: - // ignore other messages - } -} - -// Get the valid transactions run so far, and the hash of -// the application state that results from those transactions. -func (mem *Mempool) Reap() ([]types.Tx, []byte, error) { - mem.proxyMtx.Lock() - defer mem.proxyMtx.Unlock() - - // First, get the hash of txs run so far - hash, err := mem.proxyAppCtx.GetHashSync() - if err != nil { - return nil, nil, err - } - - // And collect all the transactions. - txs := mem.collectTxs() - - return txs, hash, nil -} - -func (mem *Mempool) collectTxs() []types.Tx { - txs := make([]types.Tx, 0, mem.txs.Len()) - for e := mem.txs.Front(); e != nil; e = e.Next() { - memTx := e.Value.(*mempoolTx) - txs = append(txs, memTx.tx) - } - return txs -} - -// "block" is the new block that was committed. -// Txs that are present in "block" are discarded from mempool. -// NOTE: this should be called *after* block is committed by consensus. -// CONTRACT: block is valid and next in sequence. -func (mem *Mempool) Update(block *types.Block) error { - mem.proxyMtx.Lock() - defer mem.proxyMtx.Unlock() - - // Rollback mempool synchronously - // TODO: test that proxyAppCtx's state matches the block's - err := mem.proxyAppCtx.RollbackSync() - if err != nil { - return err - } - - // First, create a lookup map of txns in new block. - blockTxsMap := make(map[string]struct{}) - for _, tx := range block.Data.Txs { - blockTxsMap[string(tx)] = struct{}{} - } - - // Remove transactions that are already in block. - // Return the remaining potentially good txs. - goodTxs := mem.filterTxs(block.Height, blockTxsMap) - - // Set height and expected - mem.height = block.Height - mem.expected = mem.txs.Front() - - // Push good txs to proxyAppCtx - // NOTE: resCb() may be called concurrently. - for _, tx := range goodTxs { - mem.proxyAppCtx.AppendTxAsync(tx) - if err := mem.proxyAppCtx.Error(); err != nil { - return err - } - } - - // NOTE: Even though we return immediately without e.g. - // calling mem.proxyAppCtx.FlushSync(), - // New mempool txs will still have to wait until - // all goodTxs are re-processed. - // So we could make synchronous calls here to proxyAppCtx. - - return nil -} - -func (mem *Mempool) filterTxs(height int, blockTxsMap map[string]struct{}) []types.Tx { - goodTxs := make([]types.Tx, 0, mem.txs.Len()) - for e := mem.txs.Front(); e != nil; e = e.Next() { - memTx := e.Value.(*mempoolTx) - if _, ok := blockTxsMap[string(memTx.tx)]; ok { - // Remove the tx since already in block. - mem.txs.Remove(e) - e.DetachPrev() - continue - } - // Good tx! - atomic.StoreInt64(&memTx.height, int64(height)) - goodTxs = append(goodTxs, memTx.tx) - } - return goodTxs -} - -//-------------------------------------------------------------------------------- - -// A transaction that successfully ran -type mempoolTx struct { - counter int64 // a simple incrementing counter - height int64 // height that this tx had been validated in - tx types.Tx // -} - -func (memTx *mempoolTx) Height() int { - return int(atomic.LoadInt64(&memTx.height)) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool_test.go deleted file mode 100644 index b01fd685..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package mempool - -import ( - "encoding/binary" - "testing" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" - "github.com/tendermint/tmsp/example" -) - -func TestSerialReap(t *testing.T) { - - app := example.NewCounterApplication() - appCtxMempool := app.Open() - appCtxMempool.SetOption("serial", "on") - proxyAppCtx := proxy.NewLocalAppContext(appCtxMempool) - mempool := NewMempool(proxyAppCtx) - - // Create another AppContext for committing. - appCtxConsensus := app.Open() - appCtxConsensus.SetOption("serial", "on") - - appendTxsRange := func(start, end int) { - // Append some txs. - for i := start; i < end; i++ { - - // This will succeed - txBytes := make([]byte, 32) - _ = binary.PutVarint(txBytes, int64(i)) - err := mempool.AppendTx(txBytes) - if err != nil { - t.Fatal("Error after AppendTx: %v", err) - } - - // This will fail because not serial (incrementing) - // However, error should still be nil. - // It just won't show up on Reap(). - err = mempool.AppendTx(txBytes) - if err != nil { - t.Fatal("Error after AppendTx: %v", err) - } - - } - } - - reapCheck := func(exp int) { - txs, _, err := mempool.Reap() - if err != nil { - t.Error("Error in mempool.Reap()", err) - } - if len(txs) != exp { - t.Fatalf("Expected to reap %v txs but got %v", exp, len(txs)) - } - } - - updateRange := func(start, end int) { - txs := make([]types.Tx, 0) - for i := start; i < end; i++ { - txBytes := make([]byte, 32) - _ = binary.PutVarint(txBytes, int64(i)) - txs = append(txs, txBytes) - } - blockHeader := &types.Header{Height: 0} - blockData := &types.Data{Txs: txs} - block := &types.Block{Header: blockHeader, Data: blockData} - err := mempool.Update(block) - if err != nil { - t.Error("Error in mempool.Update()", err) - } - } - - commitRange := func(start, end int) { - // Append some txs. - for i := start; i < end; i++ { - txBytes := make([]byte, 32) - _ = binary.PutVarint(txBytes, int64(i)) - _, retCode := appCtxConsensus.AppendTx(txBytes) - if retCode != tmsp.RetCodeOK { - t.Error("Error committing tx", retCode) - } - } - retCode := appCtxConsensus.Commit() - if retCode != tmsp.RetCodeOK { - t.Error("Error committing range", retCode) - } - } - - //---------------------------------------- - - // Append some txs. - appendTxsRange(0, 100) - - // Reap the txs. - reapCheck(100) - - // Reap again. We should get the same amount - reapCheck(100) - - // Append 0 to 999, we should reap 900 txs - // because 100 were already counted. - appendTxsRange(0, 1000) - - // Reap the txs. - reapCheck(1000) - - // Reap again. We should get the same amount - reapCheck(1000) - - // Commit from the conensus AppContext - commitRange(0, 500) - updateRange(0, 500) - - // We should have 500 left. - reapCheck(500) - -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/reactor.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/reactor.go deleted file mode 100644 index 5b41c117..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/reactor.go +++ /dev/null @@ -1,172 +0,0 @@ -package mempool - -import ( - "bytes" - "fmt" - "reflect" - "time" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-clist" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - MempoolChannel = byte(0x30) - - maxMempoolMessageSize = 1048576 // 1MB TODO make it configurable - peerCatchupSleepIntervalMS = 100 // If peer is behind, sleep this amount -) - -// MempoolReactor handles mempool tx broadcasting amongst peers. -type MempoolReactor struct { - p2p.BaseReactor - Mempool *Mempool // TODO: un-expose - evsw events.Fireable -} - -func NewMempoolReactor(mempool *Mempool) *MempoolReactor { - memR := &MempoolReactor{ - Mempool: mempool, - } - memR.BaseReactor = *p2p.NewBaseReactor(log, "MempoolReactor", memR) - return memR -} - -// Implements Reactor -func (memR *MempoolReactor) GetChannels() []*p2p.ChannelDescriptor { - return []*p2p.ChannelDescriptor{ - &p2p.ChannelDescriptor{ - ID: MempoolChannel, - Priority: 5, - }, - } -} - -// Implements Reactor -func (memR *MempoolReactor) AddPeer(peer *p2p.Peer) { - go memR.broadcastTxRoutine(peer) -} - -// Implements Reactor -func (memR *MempoolReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { - // broadcast routine checks if peer is gone and returns -} - -// Implements Reactor -func (memR *MempoolReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { - _, msg, err := DecodeMessage(msgBytes) - if err != nil { - log.Warn("Error decoding message", "error", err) - return - } - log.Notice("MempoolReactor received message", "msg", msg) - - switch msg := msg.(type) { - case *TxMessage: - err := memR.Mempool.AppendTx(msg.Tx) - if err != nil { - // Bad, seen, or conflicting tx. - log.Info("Could not add tx", "tx", msg.Tx) - return - } else { - log.Info("Added valid tx", "tx", msg.Tx) - } - // broadcasting happens from go routines per peer - default: - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } -} - -// Just an alias for AppendTx since broadcasting happens in peer routines -func (memR *MempoolReactor) BroadcastTx(tx types.Tx) error { - return memR.Mempool.AppendTx(tx) -} - -type PeerState interface { - GetHeight() int -} - -type Peer interface { - IsRunning() bool - Send(byte, interface{}) bool - Get(string) interface{} -} - -// Send new mempool txs to peer. -// TODO: Handle mempool or reactor shutdown? -// As is this routine may block forever if no new txs come in. -func (memR *MempoolReactor) broadcastTxRoutine(peer Peer) { - var next *clist.CElement - for { - if !memR.IsRunning() { - return // Quit! - } - if next == nil { - // This happens because the CElement we were looking at got - // garbage collected (removed). That is, .NextWait() returned nil. - // Go ahead and start from the beginning. - next = memR.Mempool.TxsFrontWait() // Wait until a tx is available - } - memTx := next.Value.(*mempoolTx) - // make sure the peer is up to date - height := memTx.Height() - if peerState_i := peer.Get(types.PeerStateKey); peerState_i != nil { - peerState := peerState_i.(PeerState) - if peerState.GetHeight() < height-1 { // Allow for a lag of 1 block - time.Sleep(peerCatchupSleepIntervalMS * time.Millisecond) - continue - } - } - // send memTx - msg := &TxMessage{Tx: memTx.tx} - success := peer.Send(MempoolChannel, msg) - if !success { - time.Sleep(peerCatchupSleepIntervalMS * time.Millisecond) - continue - } - - next = next.NextWait() - continue - } -} - -// implements events.Eventable -func (memR *MempoolReactor) SetFireable(evsw events.Fireable) { - memR.evsw = evsw -} - -//----------------------------------------------------------------------------- -// Messages - -const ( - msgTypeTx = byte(0x01) -) - -type MempoolMessage interface{} - -var _ = wire.RegisterInterface( - struct{ MempoolMessage }{}, - wire.ConcreteType{&TxMessage{}, msgTypeTx}, -) - -func DecodeMessage(bz []byte) (msgType byte, msg MempoolMessage, err error) { - msgType = bz[0] - n := new(int) - r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ MempoolMessage }{}, r, maxMempoolMessageSize, n, &err).(struct{ MempoolMessage }).MempoolMessage - return -} - -//------------------------------------- - -type TxMessage struct { - Tx types.Tx -} - -func (m *TxMessage) String() string { - return fmt.Sprintf("[TxMessage %v]", m.Tx) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go deleted file mode 100644 index b0d9fc60..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package node - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go deleted file mode 100644 index 825117b4..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go +++ /dev/null @@ -1,34 +0,0 @@ -package node - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "time" -) - -type NodeID struct { - Name string - PubKey crypto.PubKey -} - -type PrivNodeID struct { - NodeID - PrivKey crypto.PrivKey -} - -type NodeGreeting struct { - NodeID - Version string - ChainID string - Message string - Time time.Time -} - -type SignedNodeGreeting struct { - NodeGreeting - Signature crypto.Signature -} - -func (pnid *PrivNodeID) SignGreeting() *SignedNodeGreeting { - //greeting := NodeGreeting{} - return nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go deleted file mode 100644 index 768cd315..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package node - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "node") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node.go deleted file mode 100644 index 4b04f16f..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node.go +++ /dev/null @@ -1,339 +0,0 @@ -package node - -import ( - "bytes" - "io/ioutil" - "math/rand" - "net" - "net/http" - "strings" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - mempl "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -import _ "net/http/pprof" - -type Node struct { - sw *p2p.Switch - evsw *events.EventSwitch - blockStore *bc.BlockStore - bcReactor *bc.BlockchainReactor - mempoolReactor *mempl.MempoolReactor - consensusState *consensus.ConsensusState - consensusReactor *consensus.ConsensusReactor - privValidator *types.PrivValidator - genesisDoc *types.GenesisDoc - privKey crypto.PrivKeyEd25519 -} - -func NewNode() *Node { - // Get BlockStore - blockStoreDB := dbm.GetDB("blockstore") - blockStore := bc.NewBlockStore(blockStoreDB) - - // Get State - state := getState() - - // Create two proxyAppCtx connections, - // one for the consensus and one for the mempool. - proxyAddr := config.GetString("proxy_app") - proxyAppCtxMempool := getProxyApp(proxyAddr, state.LastAppHash) - proxyAppCtxConsensus := getProxyApp(proxyAddr, state.LastAppHash) - - // add the chainid to the global config - config.Set("chain_id", state.ChainID) - - // Get PrivValidator - privValidatorFile := config.GetString("priv_validator_file") - privValidator := types.LoadOrGenPrivValidator(privValidatorFile) - - // Generate node PrivKey - privKey := crypto.GenPrivKeyEd25519() - - // Make event switch - eventSwitch := events.NewEventSwitch() - _, err := eventSwitch.Start() - if err != nil { - Exit(Fmt("Failed to start switch: %v", err)) - } - - // Make BlockchainReactor - bcReactor := bc.NewBlockchainReactor(state.Copy(), proxyAppCtxConsensus, blockStore, config.GetBool("fast_sync")) - - // Make MempoolReactor - mempool := mempl.NewMempool(proxyAppCtxMempool) - mempoolReactor := mempl.NewMempoolReactor(mempool) - - // Make ConsensusReactor - consensusState := consensus.NewConsensusState(state.Copy(), proxyAppCtxConsensus, blockStore, mempool) - consensusReactor := consensus.NewConsensusReactor(consensusState, blockStore, config.GetBool("fast_sync")) - if privValidator != nil { - consensusReactor.SetPrivValidator(privValidator) - } - - // Make p2p network switch - sw := p2p.NewSwitch() - sw.AddReactor("MEMPOOL", mempoolReactor) - sw.AddReactor("BLOCKCHAIN", bcReactor) - sw.AddReactor("CONSENSUS", consensusReactor) - - // add the event switch to all services - // they should all satisfy events.Eventable - SetFireable(eventSwitch, bcReactor, mempoolReactor, consensusReactor) - - // run the profile server - profileHost := config.GetString("prof_laddr") - if profileHost != "" { - go func() { - log.Warn("Profile server", "error", http.ListenAndServe(profileHost, nil)) - }() - } - - return &Node{ - sw: sw, - evsw: eventSwitch, - blockStore: blockStore, - bcReactor: bcReactor, - mempoolReactor: mempoolReactor, - consensusState: consensusState, - consensusReactor: consensusReactor, - privValidator: privValidator, - genesisDoc: state.GenesisDoc, - privKey: privKey, - } -} - -// Call Start() after adding the listeners. -func (n *Node) Start() error { - n.sw.SetNodeInfo(makeNodeInfo(n.sw, n.privKey)) - n.sw.SetNodePrivKey(n.privKey) - _, err := n.sw.Start() - return err -} - -func (n *Node) Stop() { - log.Notice("Stopping Node") - // TODO: gracefully disconnect from peers. - n.sw.Stop() -} - -// Add the event switch to reactors, mempool, etc. -func SetFireable(evsw *events.EventSwitch, eventables ...events.Eventable) { - for _, e := range eventables { - e.SetFireable(evsw) - } -} - -// Add a Listener to accept inbound peer connections. -// Add listeners before starting the Node. -// The first listener is the primary listener (in NodeInfo) -func (n *Node) AddListener(l p2p.Listener) { - log.Notice(Fmt("Added %v", l)) - n.sw.AddListener(l) -} - -// Dial a list of seeds in random order -// Spawns a go routine for each dial -func (n *Node) DialSeed() { - // permute the list, dial them in random order. - seeds := strings.Split(config.GetString("seeds"), ",") - perm := rand.Perm(len(seeds)) - for i := 0; i < len(perm); i++ { - go func(i int) { - time.Sleep(time.Duration(rand.Int63n(3000)) * time.Millisecond) - j := perm[i] - addr := p2p.NewNetAddressString(seeds[j]) - n.dialSeed(addr) - }(i) - } -} - -func (n *Node) dialSeed(addr *p2p.NetAddress) { - peer, err := n.sw.DialPeerWithAddress(addr) - if err != nil { - log.Error("Error dialing seed", "error", err) - return - } else { - log.Notice("Connected to seed", "peer", peer) - } -} - -func (n *Node) StartRPC() (net.Listener, error) { - core.SetBlockStore(n.blockStore) - core.SetConsensusState(n.consensusState) - core.SetConsensusReactor(n.consensusReactor) - core.SetMempoolReactor(n.mempoolReactor) - core.SetSwitch(n.sw) - core.SetPrivValidator(n.privValidator) - core.SetGenesisDoc(n.genesisDoc) - - listenAddr := config.GetString("rpc_laddr") - - mux := http.NewServeMux() - wm := rpcserver.NewWebsocketManager(core.Routes, n.evsw) - mux.HandleFunc("/websocket", wm.WebsocketHandler) - rpcserver.RegisterRPCFuncs(mux, core.Routes) - return rpcserver.StartHTTPServer(listenAddr, mux) -} - -func (n *Node) Switch() *p2p.Switch { - return n.sw -} - -func (n *Node) BlockStore() *bc.BlockStore { - return n.blockStore -} - -func (n *Node) ConsensusState() *consensus.ConsensusState { - return n.consensusState -} - -func (n *Node) MempoolReactor() *mempl.MempoolReactor { - return n.mempoolReactor -} - -func (n *Node) EventSwitch() *events.EventSwitch { - return n.evsw -} - -func makeNodeInfo(sw *p2p.Switch, privKey crypto.PrivKeyEd25519) *p2p.NodeInfo { - - nodeInfo := &p2p.NodeInfo{ - PubKey: privKey.PubKey().(crypto.PubKeyEd25519), - Moniker: config.GetString("moniker"), - Network: config.GetString("chain_id"), - Version: Version, - Other: []string{ - Fmt("p2p_version=%v", p2p.Version), - Fmt("rpc_version=%v", rpc.Version), - Fmt("wire_version=%v", wire.Version), - }, - } - - // include git hash in the nodeInfo if available - if rev, err := ReadFile(config.GetString("revision_file")); err == nil { - nodeInfo.Other = append(nodeInfo.Other, Fmt("revision=%v", string(rev))) - } - - if !sw.IsListening() { - return nodeInfo - } - - p2pListener := sw.Listeners()[0] - p2pHost := p2pListener.ExternalAddress().IP.String() - p2pPort := p2pListener.ExternalAddress().Port - rpcListenAddr := config.GetString("rpc_laddr") - - // We assume that the rpcListener has the same ExternalAddress. - // This is probably true because both P2P and RPC listeners use UPnP, - // except of course if the rpc is only bound to localhost - nodeInfo.ListenAddr = Fmt("%v:%v", p2pHost, p2pPort) - nodeInfo.Other = append(nodeInfo.Other, Fmt("rpc_addr=%v", rpcListenAddr)) - return nodeInfo -} - -//------------------------------------------------------------------------------ - -func RunNode() { - - // Wait until the genesis doc becomes available - genDocFile := config.GetString("genesis_file") - if !FileExists(genDocFile) { - log.Notice(Fmt("Waiting for genesis file %v...", genDocFile)) - for { - time.Sleep(time.Second) - if !FileExists(genDocFile) { - continue - } - jsonBlob, err := ioutil.ReadFile(genDocFile) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) - } - genDoc := types.GenesisDocFromJSON(jsonBlob) - if genDoc.ChainID == "" { - PanicSanity(Fmt("Genesis doc %v must include non-empty chain_id", genDocFile)) - } - config.Set("chain_id", genDoc.ChainID) - config.Set("genesis_doc", genDoc) - } - } - - // Create & start node - n := NewNode() - l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), config.GetBool("skip_upnp")) - n.AddListener(l) - err := n.Start() - if err != nil { - Exit(Fmt("Failed to start node: %v", err)) - } - - log.Notice("Started node", "nodeInfo", n.sw.NodeInfo()) - - // If seedNode is provided by config, dial out. - if config.GetString("seeds") != "" { - n.DialSeed() - } - - // Run the RPC server. - if config.GetString("rpc_laddr") != "" { - _, err := n.StartRPC() - if err != nil { - PanicCrisis(err) - } - } - - // Sleep forever and then... - TrapSignal(func() { - n.Stop() - }) -} - -// Load the most recent state from "state" db, -// or create a new one (and save) from genesis. -func getState() *sm.State { - stateDB := dbm.GetDB("state") - state := sm.LoadState(stateDB) - if state == nil { - state = sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file")) - state.Save() - } - return state -} - -// Get a connection to the proxyAppCtx addr. -// Check the current hash, and panic if it doesn't match. -func getProxyApp(addr string, hash []byte) proxy.AppContext { - proxyConn, err := Connect(addr) - if err != nil { - Exit(Fmt("Failed to connect to proxy for mempool: %v", err)) - } - proxyAppCtx := proxy.NewRemoteAppContext(proxyConn, 1024) - - proxyAppCtx.Start() - - // Check the hash - currentHash, err := proxyAppCtx.GetHashSync() - if err != nil { - PanicCrisis(Fmt("Error in getting proxyAppCtx hash: %v", err)) - } - if !bytes.Equal(hash, currentHash) { - PanicCrisis(Fmt("ProxyApp hash does not match. Expected %X, got %X", hash, currentHash)) - } - - return proxyAppCtx -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node_test.go deleted file mode 100644 index d5234215..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package node - -import ( - "testing" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/server" - "github.com/tendermint/tmsp/example" -) - -func TestNodeStartStop(t *testing.T) { - - // Start a dummy app - go func() { - _, err := server.StartListener(config.GetString("proxy_app"), example.NewDummyApplication()) - if err != nil { - Exit(err.Error()) - } - }() - // wait for the server - time.Sleep(time.Second * 2) - - // Create & start node - n := NewNode() - l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), config.GetBool("skip_upnp")) - n.AddListener(l) - n.Start() - log.Notice("Started node", "nodeInfo", n.sw.NodeInfo()) - time.Sleep(time.Second * 2) - ch := make(chan struct{}, 1) - go func() { - n.Stop() - ch <- struct{}{} - }() - ticker := time.NewTicker(time.Second * 5) - select { - case <-ch: - case <-ticker.C: - t.Fatal("timed out waiting for shutdown") - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/version.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/version.go deleted file mode 100644 index 6b981175..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/version.go +++ /dev/null @@ -1,6 +0,0 @@ -package node - -// Major: alpha -// Minor: encrypted p2p! -// Patch: New block pool logic -const Version = "0.5.2" diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/app_context.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/app_context.go deleted file mode 100644 index 824599a0..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/app_context.go +++ /dev/null @@ -1,28 +0,0 @@ -package proxy - -import ( - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -type Callback func(tmsp.Request, tmsp.Response) - -type AppContext interface { - SetResponseCallback(Callback) - Error() error - - EchoAsync(msg string) - FlushAsync() - AppendTxAsync(tx []byte) - GetHashAsync() - CommitAsync() - RollbackAsync() - SetOptionAsync(key string, value string) - AddListenerAsync(key string) - RemListenerAsync(key string) - - InfoSync() (info []string, err error) - FlushSync() error - GetHashSync() (hash []byte, err error) - CommitSync() error - RollbackSync() error -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/local_app_context.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/local_app_context.go deleted file mode 100644 index 049bec04..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/local_app_context.go +++ /dev/null @@ -1,123 +0,0 @@ -package proxy - -import ( - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -type localAppContext struct { - tmsp.AppContext - Callback -} - -func NewLocalAppContext(app tmsp.AppContext) *localAppContext { - return &localAppContext{ - AppContext: app, - } -} - -func (app *localAppContext) SetResponseCallback(cb Callback) { - app.Callback = cb -} - -// TODO: change tmsp.AppContext to include Error()? -func (app *localAppContext) Error() error { - return nil -} - -func (app *localAppContext) EchoAsync(msg string) { - msg2 := app.AppContext.Echo(msg) - app.Callback( - tmsp.RequestEcho{msg}, - tmsp.ResponseEcho{msg2}, - ) -} - -func (app *localAppContext) FlushAsync() { - // Do nothing -} - -func (app *localAppContext) SetOptionAsync(key string, value string) { - retCode := app.AppContext.SetOption(key, value) - app.Callback( - tmsp.RequestSetOption{key, value}, - tmsp.ResponseSetOption{retCode}, - ) -} - -func (app *localAppContext) AppendTxAsync(tx []byte) { - events, retCode := app.AppContext.AppendTx(tx) - app.Callback( - tmsp.RequestAppendTx{tx}, - tmsp.ResponseAppendTx{retCode}, - ) - for _, event := range events { - app.Callback( - nil, - tmsp.ResponseEvent{event}, - ) - } -} - -func (app *localAppContext) GetHashAsync() { - hash, retCode := app.AppContext.GetHash() - app.Callback( - tmsp.RequestGetHash{}, - tmsp.ResponseGetHash{retCode, hash}, - ) -} - -func (app *localAppContext) CommitAsync() { - retCode := app.AppContext.Commit() - app.Callback( - tmsp.RequestCommit{}, - tmsp.ResponseCommit{retCode}, - ) -} - -func (app *localAppContext) RollbackAsync() { - retCode := app.AppContext.Rollback() - app.Callback( - tmsp.RequestRollback{}, - tmsp.ResponseRollback{retCode}, - ) -} - -func (app *localAppContext) AddListenerAsync(key string) { - retCode := app.AppContext.AddListener(key) - app.Callback( - tmsp.RequestAddListener{key}, - tmsp.ResponseAddListener{retCode}, - ) -} - -func (app *localAppContext) RemListenerAsync(key string) { - retCode := app.AppContext.RemListener(key) - app.Callback( - tmsp.RequestRemListener{key}, - tmsp.ResponseRemListener{retCode}, - ) -} - -func (app *localAppContext) InfoSync() (info []string, err error) { - info = app.AppContext.Info() - return info, nil -} - -func (app *localAppContext) FlushSync() error { - return nil -} - -func (app *localAppContext) GetHashSync() (hash []byte, err error) { - hash, retCode := app.AppContext.GetHash() - return hash, retCode.Error() -} - -func (app *localAppContext) CommitSync() (err error) { - retCode := app.AppContext.Commit() - return retCode.Error() -} - -func (app *localAppContext) RollbackSync() (err error) { - retCode := app.AppContext.Rollback() - return retCode.Error() -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/log.go deleted file mode 100644 index 5459d49b..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package proxy - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "proxy") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context.go deleted file mode 100644 index e3a021bd..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context.go +++ /dev/null @@ -1,310 +0,0 @@ -package proxy - -import ( - "bufio" - "container/list" - "errors" - "fmt" - "net" - "reflect" - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -const maxResponseSize = 1048576 // 1MB - -// This is goroutine-safe, but users should beware that -// the application in general is not meant to be interfaced -// with concurrent callers. -type remoteAppContext struct { - QuitService - sync.Mutex // [EB]: is this even used? - - reqQueue chan *reqRes - - mtx sync.Mutex - conn net.Conn - bufWriter *bufio.Writer - err error - reqSent *list.List - resCb func(tmsp.Request, tmsp.Response) -} - -func NewRemoteAppContext(conn net.Conn, bufferSize int) *remoteAppContext { - app := &remoteAppContext{ - reqQueue: make(chan *reqRes, bufferSize), - conn: conn, - bufWriter: bufio.NewWriter(conn), - reqSent: list.New(), - resCb: nil, - } - app.QuitService = *NewQuitService(nil, "remoteAppContext", app) - return app -} - -func (app *remoteAppContext) OnStart() error { - app.QuitService.OnStart() - go app.sendRequestsRoutine() - go app.recvResponseRoutine() - return nil -} - -func (app *remoteAppContext) OnStop() { - app.QuitService.OnStop() - app.conn.Close() -} - -func (app *remoteAppContext) SetResponseCallback(resCb Callback) { - app.mtx.Lock() - defer app.mtx.Unlock() - app.resCb = resCb -} - -func (app *remoteAppContext) StopForError(err error) { - app.mtx.Lock() - log.Error("Stopping remoteAppContext for error.", "error", err) - if app.err == nil { - app.err = err - } - app.mtx.Unlock() - app.Stop() -} - -func (app *remoteAppContext) Error() error { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.err -} - -//---------------------------------------- - -func (app *remoteAppContext) sendRequestsRoutine() { - for { - var n int - var err error - select { - case <-app.QuitService.Quit: - return - case reqres := <-app.reqQueue: - - app.willSendReq(reqres) - - wire.WriteBinary(reqres.Request, app.bufWriter, &n, &err) - if err != nil { - app.StopForError(err) - return - } - log.Debug("Sent request", "requestType", reflect.TypeOf(reqres.Request), "request", reqres.Request) - if _, ok := reqres.Request.(tmsp.RequestFlush); ok { - err = app.bufWriter.Flush() - if err != nil { - app.StopForError(err) - return - } - } - } - } -} - -func (app *remoteAppContext) recvResponseRoutine() { - r := bufio.NewReader(app.conn) // Buffer reads - for { - var res tmsp.Response - var n int - var err error - wire.ReadBinaryPtr(&res, r, maxResponseSize, &n, &err) - if err != nil { - app.StopForError(err) - return - } - switch res := res.(type) { - case tmsp.ResponseException: - app.StopForError(errors.New(res.Error)) - default: - log.Debug("Received response", "responseType", reflect.TypeOf(res), "response", res) - err := app.didRecvResponse(res) - if err != nil { - app.StopForError(err) - } - } - } -} - -func (app *remoteAppContext) willSendReq(reqres *reqRes) { - app.mtx.Lock() - defer app.mtx.Unlock() - app.reqSent.PushBack(reqres) -} - -func (app *remoteAppContext) didRecvResponse(res tmsp.Response) error { - app.mtx.Lock() - defer app.mtx.Unlock() - - // Special logic for events which have no corresponding requests. - if _, ok := res.(tmsp.ResponseEvent); ok && app.resCb != nil { - app.resCb(nil, res) - return nil - } - - // Get the first reqRes - next := app.reqSent.Front() - if next == nil { - return fmt.Errorf("Unexpected result type %v when nothing expected", reflect.TypeOf(res)) - } - reqres := next.Value.(*reqRes) - if !resMatchesReq(reqres.Request, res) { - return fmt.Errorf("Unexpected result type %v when response to %v expected", - reflect.TypeOf(res), reflect.TypeOf(reqres.Request)) - } - - reqres.Response = res // Set response - reqres.Done() // Release waiters - app.reqSent.Remove(next) // Pop first item from linked list - - // Callback if there is a listener - if app.resCb != nil { - app.resCb(reqres.Request, res) - } - - return nil -} - -//---------------------------------------- - -func (app *remoteAppContext) EchoAsync(msg string) { - app.queueRequest(tmsp.RequestEcho{msg}) -} - -func (app *remoteAppContext) FlushAsync() { - app.queueRequest(tmsp.RequestFlush{}) -} - -func (app *remoteAppContext) SetOptionAsync(key string, value string) { - app.queueRequest(tmsp.RequestSetOption{key, value}) -} - -func (app *remoteAppContext) AppendTxAsync(tx []byte) { - app.queueRequest(tmsp.RequestAppendTx{tx}) -} - -func (app *remoteAppContext) GetHashAsync() { - app.queueRequest(tmsp.RequestGetHash{}) -} - -func (app *remoteAppContext) CommitAsync() { - app.queueRequest(tmsp.RequestCommit{}) -} - -func (app *remoteAppContext) RollbackAsync() { - app.queueRequest(tmsp.RequestRollback{}) -} - -func (app *remoteAppContext) AddListenerAsync(key string) { - app.queueRequest(tmsp.RequestAddListener{key}) -} - -func (app *remoteAppContext) RemListenerAsync(key string) { - app.queueRequest(tmsp.RequestRemListener{key}) -} - -//---------------------------------------- - -func (app *remoteAppContext) InfoSync() (info []string, err error) { - reqres := app.queueRequest(tmsp.RequestInfo{}) - app.FlushSync() - if app.err != nil { - return nil, app.err - } - return reqres.Response.(tmsp.ResponseInfo).Data, nil -} - -func (app *remoteAppContext) FlushSync() error { - app.queueRequest(tmsp.RequestFlush{}).Wait() - return app.err -} - -func (app *remoteAppContext) GetHashSync() (hash []byte, err error) { - reqres := app.queueRequest(tmsp.RequestGetHash{}) - app.FlushSync() - if app.err != nil { - return nil, app.err - } - return reqres.Response.(tmsp.ResponseGetHash).Hash, nil -} - -// Commits or error -func (app *remoteAppContext) CommitSync() (err error) { - app.queueRequest(tmsp.RequestCommit{}) - app.FlushSync() - return app.err -} - -// Rollback or error -// Clears internal buffers -func (app *remoteAppContext) RollbackSync() (err error) { - app.queueRequest(tmsp.RequestRollback{}) - app.FlushSync() - return app.err -} - -//---------------------------------------- - -func (app *remoteAppContext) queueRequest(req tmsp.Request) *reqRes { - reqres := NewreqRes(req) - // TODO: set app.err if reqQueue times out - app.reqQueue <- reqres - return reqres -} - -//---------------------------------------- - -func resMatchesReq(req tmsp.Request, res tmsp.Response) (ok bool) { - switch req.(type) { - case tmsp.RequestEcho: - _, ok = res.(tmsp.ResponseEcho) - case tmsp.RequestFlush: - _, ok = res.(tmsp.ResponseFlush) - case tmsp.RequestInfo: - _, ok = res.(tmsp.ResponseInfo) - case tmsp.RequestSetOption: - _, ok = res.(tmsp.ResponseSetOption) - case tmsp.RequestAppendTx: - _, ok = res.(tmsp.ResponseAppendTx) - case tmsp.RequestGetHash: - _, ok = res.(tmsp.ResponseGetHash) - case tmsp.RequestCommit: - _, ok = res.(tmsp.ResponseCommit) - case tmsp.RequestRollback: - _, ok = res.(tmsp.ResponseRollback) - case tmsp.RequestAddListener: - _, ok = res.(tmsp.ResponseAddListener) - case tmsp.RequestRemListener: - _, ok = res.(tmsp.ResponseRemListener) - default: - return false - } - return -} - -type reqRes struct { - tmsp.Request - *sync.WaitGroup - tmsp.Response // Not set atomically, so be sure to use WaitGroup. -} - -func NewreqRes(req tmsp.Request) *reqRes { - return &reqRes{ - Request: req, - WaitGroup: waitGroup1(), - Response: nil, - } -} - -func waitGroup1() (wg *sync.WaitGroup) { - wg = &sync.WaitGroup{} - wg.Add(1) - return -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context_test.go deleted file mode 100644 index 86d388e4..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package proxy - -import ( - "bytes" - "strings" - "testing" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/server" - "github.com/tendermint/go-logio" - example "github.com/tendermint/tmsp/example" -) - -func TestEcho(t *testing.T) { - sockPath := Fmt("unix:///tmp/echo_%v.sock", RandStr(6)) - _, err := server.StartListener(sockPath, example.NewDummyApplication()) - if err != nil { - Exit(err.Error()) - } - conn, err := Connect(sockPath) - if err != nil { - Exit(err.Error()) - } else { - t.Log("Connected") - } - - logBuffer := bytes.NewBuffer(nil) - logConn := logio.NewLoggedConn(conn, logBuffer) - proxy := NewRemoteAppContext(logConn, 10) - proxy.SetResponseCallback(nil) - proxy.Start() - - for i := 0; i < 1000; i++ { - proxy.EchoAsync(Fmt("echo-%v", i)) - } - proxy.FlushSync() - - /* - if t.Failed() { - logio.PrintReader(logBuffer) - } - */ -} - -func BenchmarkEcho(b *testing.B) { - b.StopTimer() // Initialize - sockPath := Fmt("unix:///tmp/echo_%v.sock", RandStr(6)) - _, err := server.StartListener(sockPath, example.NewDummyApplication()) - if err != nil { - Exit(err.Error()) - } - conn, err := Connect(sockPath) - if err != nil { - Exit(err.Error()) - } else { - b.Log("Connected") - } - - proxy := NewRemoteAppContext(conn, 10) - proxy.Start() - echoString := strings.Repeat(" ", 200) - b.StartTimer() // Start benchmarking tests - - for i := 0; i < b.N; i++ { - proxy.EchoAsync(echoString) - } - proxy.FlushSync() - - b.StopTimer() - // info := proxy.InfoSync() - //b.Log("N: ", b.N, info) -} - -func TestInfo(t *testing.T) { - sockPath := Fmt("unix:///tmp/echo_%v.sock", RandStr(6)) - _, err := server.StartListener(sockPath, example.NewDummyApplication()) - if err != nil { - Exit(err.Error()) - } - conn, err := Connect(sockPath) - if err != nil { - Exit(err.Error()) - } else { - t.Log("Connected") - } - - logBuffer := bytes.NewBuffer(nil) - logConn := logio.NewLoggedConn(conn, logBuffer) - proxy := NewRemoteAppContext(logConn, 10) - proxy.Start() - data, err := proxy.InfoSync() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if data[0] != "size:0" { - t.Error("Expected ResponseInfo with one element 'size:0' but got something else") - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/client.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/client.go deleted file mode 100644 index 3e295549..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/client.go +++ /dev/null @@ -1,51 +0,0 @@ -package rpcclient - -import ( - "bytes" - "encoding/json" - "errors" - "io/ioutil" - "net/http" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types" -) - -func Call(remote string, method string, params []interface{}, dest interface{}) (interface{}, error) { - // Make request and get responseBytes - request := RPCRequest{ - JSONRPC: "2.0", - Method: method, - Params: params, - ID: "", - } - requestBytes := wire.JSONBytes(request) - requestBuf := bytes.NewBuffer(requestBytes) - log.Info(Fmt("RPC request to %v: %v", remote, string(requestBytes))) - httpResponse, err := http.Post(remote, "text/json", requestBuf) - if err != nil { - return dest, err - } - defer httpResponse.Body.Close() - responseBytes, err := ioutil.ReadAll(httpResponse.Body) - if err != nil { - return dest, err - } - log.Info(Fmt("RPC response: %v", string(responseBytes))) - - // Parse response into JSONResponse - response := RPCResponse{} - err = json.Unmarshal(responseBytes, &response) - if err != nil { - return dest, err - } - // Parse response into dest - resultJSONObject := response.Result - errorStr := response.Error - if errorStr != "" { - return dest, errors.New(errorStr) - } - dest = wire.ReadJSONObject(dest, resultJSONObject, &err) - return dest, err -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/log.go deleted file mode 100644 index bfebc78d..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package rpcclient - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" -) - -var log = log15.New("module", "rpcclient") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/blocks.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/blocks.go deleted file mode 100644 index ad61bac5..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/blocks.go +++ /dev/null @@ -1,45 +0,0 @@ -package core - -import ( - "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -//----------------------------------------------------------------------------- - -func BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResultBlockchainInfo, error) { - if maxHeight == 0 { - maxHeight = blockStore.Height() - } else { - maxHeight = MinInt(blockStore.Height(), maxHeight) - } - if minHeight == 0 { - minHeight = MaxInt(1, maxHeight-20) - } - log.Info("BlockchainInfoHandler", "maxHeight", maxHeight, "minHeight", minHeight) - - blockMetas := []*types.BlockMeta{} - for height := maxHeight; height >= minHeight; height-- { - blockMeta := blockStore.LoadBlockMeta(height) - blockMetas = append(blockMetas, blockMeta) - } - - return &ctypes.ResultBlockchainInfo{blockStore.Height(), blockMetas}, nil -} - -//----------------------------------------------------------------------------- - -func GetBlock(height int) (*ctypes.ResultGetBlock, error) { - if height == 0 { - return nil, fmt.Errorf("Height must be greater than 0") - } - if height > blockStore.Height() { - return nil, fmt.Errorf("Height must be less than the current blockchain height") - } - - blockMeta := blockStore.LoadBlockMeta(height) - block := blockStore.LoadBlock(height) - return &ctypes.ResultGetBlock{blockMeta, block}, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/config.go deleted file mode 100644 index bf269a70..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package core - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/consensus.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/consensus.go deleted file mode 100644 index ea621b13..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/consensus.go +++ /dev/null @@ -1,35 +0,0 @@ -package core - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - cm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -func ListValidators() (*ctypes.ResultListValidators, error) { - var blockHeight int - var validators []*types.Validator - - state := consensusState.GetState() - blockHeight = state.LastBlockHeight - state.Validators.Iterate(func(index int, val *types.Validator) bool { - validators = append(validators, val) - return false - }) - - return &ctypes.ResultListValidators{blockHeight, validators}, nil -} - -func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { - roundState := consensusState.GetRoundState() - peerRoundStates := []string{} - for _, peer := range p2pSwitch.Peers().List() { - // TODO: clean this up? - peerState := peer.Data.Get(types.PeerStateKey).(*cm.PeerState) - peerRoundState := peerState.GetRoundState() - peerRoundStateStr := peer.Key + ":" + string(wire.JSONBytes(peerRoundState)) - peerRoundStates = append(peerRoundStates, peerRoundStateStr) - } - return &ctypes.ResultDumpConsensusState{roundState.String(), peerRoundStates}, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/log.go deleted file mode 100644 index a0dfe3d8..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package core - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" -) - -var log = log15.New("module", "rpc") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/mempool.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/mempool.go deleted file mode 100644 index 00cbacf5..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/mempool.go +++ /dev/null @@ -1,23 +0,0 @@ -package core - -import ( - "fmt" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -//----------------------------------------------------------------------------- - -// Note: tx must be signed -func BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - err := mempoolReactor.BroadcastTx(tx) - if err != nil { - return nil, fmt.Errorf("Error broadcasting transaction: %v", err) - } - return &ctypes.ResultBroadcastTx{}, nil -} - -func ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) { - txs, _, err := mempoolReactor.Mempool.Reap() - return &ctypes.ResultListUnconfirmedTxs{len(txs), txs}, err -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/net.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/net.go deleted file mode 100644 index 09f8555f..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/net.go +++ /dev/null @@ -1,58 +0,0 @@ -package core - -import ( - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -//----------------------------------------------------------------------------- - -// TODO Move to status.go or node.go -func Status() (*ctypes.ResultStatus, error) { - latestHeight := blockStore.Height() - var ( - latestBlockMeta *types.BlockMeta - latestBlockHash []byte - latestBlockTime int64 - ) - if latestHeight != 0 { - latestBlockMeta = blockStore.LoadBlockMeta(latestHeight) - latestBlockHash = latestBlockMeta.Hash - latestBlockTime = latestBlockMeta.Header.Time.UnixNano() - } - - return &ctypes.ResultStatus{ - NodeInfo: p2pSwitch.NodeInfo(), - PubKey: privValidator.PubKey, - LatestBlockHash: latestBlockHash, - LatestBlockHeight: latestHeight, - LatestBlockTime: latestBlockTime}, nil -} - -//----------------------------------------------------------------------------- - -func NetInfo() (*ctypes.ResultNetInfo, error) { - listening := p2pSwitch.IsListening() - listeners := []string{} - for _, listener := range p2pSwitch.Listeners() { - listeners = append(listeners, listener.String()) - } - peers := []ctypes.Peer{} - for _, peer := range p2pSwitch.Peers().List() { - peers = append(peers, ctypes.Peer{ - NodeInfo: *peer.NodeInfo, - IsOutbound: peer.IsOutbound(), - }) - } - return &ctypes.ResultNetInfo{ - Listening: listening, - Listeners: listeners, - Peers: peers, - }, nil -} - -//----------------------------------------------------------------------------- - -func Genesis() (*ctypes.ResultGenesis, error) { - return &ctypes.ResultGenesis{genDoc}, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/pipe.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/pipe.go deleted file mode 100644 index 98ec21ec..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/pipe.go +++ /dev/null @@ -1,45 +0,0 @@ -package core - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus" - mempl "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -var blockStore *bc.BlockStore -var consensusState *consensus.ConsensusState -var consensusReactor *consensus.ConsensusReactor -var mempoolReactor *mempl.MempoolReactor -var p2pSwitch *p2p.Switch -var privValidator *types.PrivValidator -var genDoc *types.GenesisDoc // cache the genesis structure - -func SetBlockStore(bs *bc.BlockStore) { - blockStore = bs -} - -func SetConsensusState(cs *consensus.ConsensusState) { - consensusState = cs -} - -func SetConsensusReactor(cr *consensus.ConsensusReactor) { - consensusReactor = cr -} - -func SetMempoolReactor(mr *mempl.MempoolReactor) { - mempoolReactor = mr -} - -func SetSwitch(sw *p2p.Switch) { - p2pSwitch = sw -} - -func SetPrivValidator(pv *types.PrivValidator) { - privValidator = pv -} - -func SetGenesisDoc(doc *types.GenesisDoc) { - genDoc = doc -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/routes.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/routes.go deleted file mode 100644 index dcbde192..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/routes.go +++ /dev/null @@ -1,19 +0,0 @@ -package core - -import ( - rpc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server" -) - -// TODO: eliminate redundancy between here and reading code from core/ -var Routes = map[string]*rpc.RPCFunc{ - "status": rpc.NewRPCFunc(Status, []string{}), - "net_info": rpc.NewRPCFunc(NetInfo, []string{}), - "blockchain": rpc.NewRPCFunc(BlockchainInfo, []string{"minHeight", "maxHeight"}), - "genesis": rpc.NewRPCFunc(Genesis, []string{}), - "get_block": rpc.NewRPCFunc(GetBlock, []string{"height"}), - "list_validators": rpc.NewRPCFunc(ListValidators, []string{}), - "dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, []string{}), - "broadcast_tx": rpc.NewRPCFunc(BroadcastTx, []string{"tx"}), - "list_unconfirmed_txs": rpc.NewRPCFunc(ListUnconfirmedTxs, []string{}), - // subscribe/unsubscribe are reserved for websocket events. -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types/responses.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types/responses.go deleted file mode 100644 index 702b9eca..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types/responses.go +++ /dev/null @@ -1,104 +0,0 @@ -package core_types - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -type ResultBlockchainInfo struct { - LastHeight int `json:"last_height"` - BlockMetas []*types.BlockMeta `json:"block_metas"` -} - -type ResultGetBlock struct { - BlockMeta *types.BlockMeta `json:"block_meta"` - Block *types.Block `json:"block"` -} - -type ResultStatus struct { - NodeInfo *p2p.NodeInfo `json:"node_info"` - PubKey crypto.PubKey `json:"pub_key"` - LatestBlockHash []byte `json:"latest_block_hash"` - LatestBlockHeight int `json:"latest_block_height"` - LatestBlockTime int64 `json:"latest_block_time"` // nano -} - -type ResultNetInfo struct { - Listening bool `json:"listening"` - Listeners []string `json:"listeners"` - Peers []Peer `json:"peers"` -} - -type Peer struct { - p2p.NodeInfo `json:"node_info"` - IsOutbound bool `json:"is_outbound"` -} - -type ResultListValidators struct { - BlockHeight int `json:"block_height"` - Validators []*types.Validator `json:"validators"` -} - -type ResultDumpConsensusState struct { - RoundState string `json:"round_state"` - PeerRoundStates []string `json:"peer_round_states"` -} - -type ResultBroadcastTx struct { -} - -type ResultListUnconfirmedTxs struct { - N int `json:"n_txs"` - Txs []types.Tx `json:"txs"` -} - -type ResultGenesis struct { - Genesis *types.GenesisDoc `json:"genesis"` -} - -type ResultEvent struct { - Event string `json:"event"` - Data types.EventData `json:"data"` -} - -//---------------------------------------- -// response & result types - -type Response struct { - JSONRPC string `json:"jsonrpc"` - ID string `json:"id"` - Result Result `json:"result"` - Error string `json:"error"` -} - -const ( - ResultTypeBlockchainInfo = byte(0x05) - ResultTypeGetBlock = byte(0x06) - ResultTypeStatus = byte(0x07) - ResultTypeNetInfo = byte(0x08) - ResultTypeListValidators = byte(0x09) - ResultTypeDumpConsensusState = byte(0x0A) - ResultTypeBroadcastTx = byte(0x0E) - ResultTypeListUnconfirmedTxs = byte(0x0F) - ResultTypeGenesis = byte(0x11) - ResultTypeEvent = byte(0x13) // so websockets can respond to rpc functions -) - -type Result interface{} - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ Result }{}, - wire.ConcreteType{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo}, - wire.ConcreteType{&ResultGetBlock{}, ResultTypeGetBlock}, - wire.ConcreteType{&ResultStatus{}, ResultTypeStatus}, - wire.ConcreteType{&ResultNetInfo{}, ResultTypeNetInfo}, - wire.ConcreteType{&ResultListValidators{}, ResultTypeListValidators}, - wire.ConcreteType{&ResultDumpConsensusState{}, ResultTypeDumpConsensusState}, - wire.ConcreteType{&ResultBroadcastTx{}, ResultTypeBroadcastTx}, - wire.ConcreteType{&ResultListUnconfirmedTxs{}, ResultTypeListUnconfirmedTxs}, - wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis}, - wire.ConcreteType{&ResultEvent{}, ResultTypeEvent}, -) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/handlers.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/handlers.go deleted file mode 100644 index 42e59285..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/handlers.go +++ /dev/null @@ -1,516 +0,0 @@ -package rpcserver - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "net/http" - "reflect" - "sort" - "time" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gorilla/websocket" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -func RegisterRPCFuncs(mux *http.ServeMux, funcMap map[string]*RPCFunc) { - // HTTP endpoints - for funcName, rpcFunc := range funcMap { - mux.HandleFunc("/"+funcName, makeHTTPHandler(rpcFunc)) - } - - // JSONRPC endpoints - mux.HandleFunc("/", makeJSONRPCHandler(funcMap)) -} - -//------------------------------------- -// function introspection - -// holds all type information for each function -type RPCFunc struct { - f reflect.Value // underlying rpc function - args []reflect.Type // type of each function arg - returns []reflect.Type // type of each return arg - argNames []string // name of each argument -} - -// wraps a function for quicker introspection -func NewRPCFunc(f interface{}, args []string) *RPCFunc { - return &RPCFunc{ - f: reflect.ValueOf(f), - args: funcArgTypes(f), - returns: funcReturnTypes(f), - argNames: args, - } -} - -// return a function's argument types -func funcArgTypes(f interface{}) []reflect.Type { - t := reflect.TypeOf(f) - n := t.NumIn() - typez := make([]reflect.Type, n) - for i := 0; i < n; i++ { - typez[i] = t.In(i) - } - return typez -} - -// return a function's return types -func funcReturnTypes(f interface{}) []reflect.Type { - t := reflect.TypeOf(f) - n := t.NumOut() - typez := make([]reflect.Type, n) - for i := 0; i < n; i++ { - typez[i] = t.Out(i) - } - return typez -} - -// function introspection -//----------------------------------------------------------------------------- -// rpc.json - -// jsonrpc calls grab the given method's function info and runs reflect.Call -func makeJSONRPCHandler(funcMap map[string]*RPCFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - b, _ := ioutil.ReadAll(r.Body) - // if its an empty request (like from a browser), - // just display a list of functions - if len(b) == 0 { - writeListOfEndpoints(w, r, funcMap) - return - } - - var request RPCRequest - err := json.Unmarshal(b, &request) - if err != nil { - WriteRPCResponse(w, NewRPCResponse("", nil, err.Error())) - return - } - if len(r.URL.Path) > 1 { - WriteRPCResponse(w, NewRPCResponse(request.ID, nil, fmt.Sprintf("Invalid JSONRPC endpoint %s", r.URL.Path))) - return - } - rpcFunc := funcMap[request.Method] - if rpcFunc == nil { - WriteRPCResponse(w, NewRPCResponse(request.ID, nil, "RPC method unknown: "+request.Method)) - return - } - args, err := jsonParamsToArgs(rpcFunc, request.Params) - if err != nil { - WriteRPCResponse(w, NewRPCResponse(request.ID, nil, err.Error())) - return - } - returns := rpcFunc.f.Call(args) - log.Info("HTTPJSONRPC", "method", request.Method, "args", args, "returns", returns) - result, err := unreflectResult(returns) - if err != nil { - WriteRPCResponse(w, NewRPCResponse(request.ID, nil, err.Error())) - return - } - WriteRPCResponse(w, NewRPCResponse(request.ID, result, "")) - } -} - -// covert a list of interfaces to properly typed values -func jsonParamsToArgs(rpcFunc *RPCFunc, params []interface{}) ([]reflect.Value, error) { - if len(rpcFunc.argNames) != len(params) { - return nil, errors.New(fmt.Sprintf("Expected %v parameters (%v), got %v (%v)", - len(rpcFunc.argNames), rpcFunc.argNames, len(params), params)) - } - values := make([]reflect.Value, len(params)) - for i, p := range params { - ty := rpcFunc.args[i] - v, err := _jsonObjectToArg(ty, p) - if err != nil { - return nil, err - } - values[i] = v - } - return values, nil -} - -func _jsonObjectToArg(ty reflect.Type, object interface{}) (reflect.Value, error) { - var err error - v := reflect.New(ty) - wire.ReadJSONObjectPtr(v.Interface(), object, &err) - if err != nil { - return v, err - } - v = v.Elem() - return v, nil -} - -// rpc.json -//----------------------------------------------------------------------------- -// rpc.http - -// convert from a function name to the http handler -func makeHTTPHandler(rpcFunc *RPCFunc) func(http.ResponseWriter, *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - args, err := httpParamsToArgs(rpcFunc, r) - if err != nil { - WriteRPCResponse(w, NewRPCResponse("", nil, err.Error())) - return - } - returns := rpcFunc.f.Call(args) - log.Info("HTTPRestRPC", "method", r.URL.Path, "args", args, "returns", returns) - result, err := unreflectResult(returns) - if err != nil { - WriteRPCResponse(w, NewRPCResponse("", nil, err.Error())) - return - } - WriteRPCResponse(w, NewRPCResponse("", result, "")) - } -} - -// Covert an http query to a list of properly typed values. -// To be properly decoded the arg must be a concrete type from tendermint (if its an interface). -func httpParamsToArgs(rpcFunc *RPCFunc, r *http.Request) ([]reflect.Value, error) { - argTypes := rpcFunc.args - argNames := rpcFunc.argNames - - var err error - values := make([]reflect.Value, len(argNames)) - for i, name := range argNames { - ty := argTypes[i] - arg := GetParam(r, name) - values[i], err = _jsonStringToArg(ty, arg) - if err != nil { - return nil, err - } - } - return values, nil -} - -func _jsonStringToArg(ty reflect.Type, arg string) (reflect.Value, error) { - var err error - v := reflect.New(ty) - wire.ReadJSONPtr(v.Interface(), []byte(arg), &err) - if err != nil { - return v, err - } - v = v.Elem() - return v, nil -} - -// rpc.http -//----------------------------------------------------------------------------- -// rpc.websocket - -const ( - writeChanCapacity = 20 - wsWriteTimeoutSeconds = 30 // each write times out after this - wsReadTimeoutSeconds = 30 // connection times out if we haven't received *anything* in this long, not even pings. - wsPingTickerSeconds = 10 // send a ping every PingTickerSeconds. -) - -// a single websocket connection -// contains listener id, underlying ws connection, -// and the event switch for subscribing to events -type WSConnection struct { - QuitService - - id string - baseConn *websocket.Conn - writeChan chan RPCResponse - readTimeout *time.Timer - pingTicker *time.Ticker - - funcMap map[string]*RPCFunc - evsw *events.EventSwitch -} - -// new websocket connection wrapper -func NewWSConnection(baseConn *websocket.Conn, funcMap map[string]*RPCFunc, evsw *events.EventSwitch) *WSConnection { - wsc := &WSConnection{ - id: baseConn.RemoteAddr().String(), - baseConn: baseConn, - writeChan: make(chan RPCResponse, writeChanCapacity), // error when full. - funcMap: funcMap, - evsw: evsw, - } - wsc.QuitService = *NewQuitService(log, "WSConnection", wsc) - return wsc -} - -// wsc.Start() blocks until the connection closes. -func (wsc *WSConnection) OnStart() error { - wsc.QuitService.OnStart() - - // Read subscriptions/unsubscriptions to events - go wsc.readRoutine() - - // Custom Ping handler to touch readTimeout - wsc.readTimeout = time.NewTimer(time.Second * wsReadTimeoutSeconds) - wsc.pingTicker = time.NewTicker(time.Second * wsPingTickerSeconds) - wsc.baseConn.SetPingHandler(func(m string) error { - wsc.baseConn.WriteControl(websocket.PongMessage, []byte(m), time.Now().Add(time.Second*wsWriteTimeoutSeconds)) - wsc.readTimeout.Reset(time.Second * wsReadTimeoutSeconds) - return nil - }) - wsc.baseConn.SetPongHandler(func(m string) error { - wsc.readTimeout.Reset(time.Second * wsReadTimeoutSeconds) - return nil - }) - go wsc.readTimeoutRoutine() - - // Write responses, BLOCKING. - wsc.writeRoutine() - return nil -} - -func (wsc *WSConnection) OnStop() { - wsc.QuitService.OnStop() - wsc.evsw.RemoveListener(wsc.id) - wsc.readTimeout.Stop() - wsc.pingTicker.Stop() - // The write loop closes the websocket connection - // when it exits its loop, and the read loop - // closes the writeChan -} - -func (wsc *WSConnection) readTimeoutRoutine() { - select { - case <-wsc.readTimeout.C: - log.Notice("Stopping connection due to read timeout") - wsc.Stop() - case <-wsc.Quit: - return - } -} - -// Attempt to write response to writeChan and record failures -func (wsc *WSConnection) writeRPCResponse(resp RPCResponse) { - select { - case wsc.writeChan <- resp: - default: - log.Notice("Stopping connection due to writeChan overflow", "id", wsc.id) - wsc.Stop() // writeChan capacity exceeded, error. - } -} - -// Read from the socket and subscribe to or unsubscribe from events -func (wsc *WSConnection) readRoutine() { - // Do not close writeChan, to allow writeRPCResponse() to fail. - // defer close(wsc.writeChan) - - for { - select { - case <-wsc.Quit: - return - default: - var in []byte - // Do not set a deadline here like below: - // wsc.baseConn.SetReadDeadline(time.Now().Add(time.Second * wsReadTimeoutSeconds)) - // The client may not send anything for a while. - // We use `readTimeout` to handle read timeouts. - _, in, err := wsc.baseConn.ReadMessage() - if err != nil { - log.Notice("Failed to read from connection", "id", wsc.id) - // an error reading the connection, - // kill the connection - wsc.Stop() - return - } - var request RPCRequest - err = json.Unmarshal(in, &request) - if err != nil { - errStr := fmt.Sprintf("Error unmarshaling data: %s", err.Error()) - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, errStr)) - continue - } - switch request.Method { - case "subscribe": - if len(request.Params) != 1 { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "subscribe takes 1 event parameter string")) - continue - } - if event, ok := request.Params[0].(string); !ok { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "subscribe takes 1 event parameter string")) - continue - } else { - log.Notice("Subscribe to event", "id", wsc.id, "event", event) - wsc.evsw.AddListenerForEvent(wsc.id, event, func(msg types.EventData) { - // NOTE: RPCResponses of subscribed events have id suffix "#event" - wsc.writeRPCResponse(NewRPCResponse(request.ID+"#event", ctypes.ResultEvent{event, msg}, "")) - }) - continue - } - case "unsubscribe": - if len(request.Params) == 0 { - log.Notice("Unsubscribe from all events", "id", wsc.id) - wsc.evsw.RemoveListener(wsc.id) - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "")) - continue - } else if len(request.Params) == 1 { - if event, ok := request.Params[0].(string); !ok { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "unsubscribe takes 0 or 1 event parameter strings")) - continue - } else { - log.Notice("Unsubscribe from event", "id", wsc.id, "event", event) - wsc.evsw.RemoveListenerForEvent(event, wsc.id) - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "")) - continue - } - } else { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "unsubscribe takes 0 or 1 event parameter strings")) - continue - } - default: - rpcFunc := wsc.funcMap[request.Method] - if rpcFunc == nil { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "RPC method unknown: "+request.Method)) - continue - } - args, err := jsonParamsToArgs(rpcFunc, request.Params) - if err != nil { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, err.Error())) - continue - } - returns := rpcFunc.f.Call(args) - log.Info("WSJSONRPC", "method", request.Method, "args", args, "returns", returns) - result, err := unreflectResult(returns) - if err != nil { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, err.Error())) - continue - } else { - wsc.writeRPCResponse(NewRPCResponse(request.ID, result, "")) - continue - } - } - } - } -} - -// receives on a write channel and writes out on the socket -func (wsc *WSConnection) writeRoutine() { - defer wsc.baseConn.Close() - var n, err = int(0), error(nil) - for { - select { - case <-wsc.Quit: - return - case <-wsc.pingTicker.C: - err := wsc.baseConn.WriteMessage(websocket.PingMessage, []byte{}) - if err != nil { - log.Error("Failed to write ping message on websocket", "error", err) - wsc.Stop() - return - } - case msg := <-wsc.writeChan: - buf := new(bytes.Buffer) - wire.WriteJSON(msg, buf, &n, &err) - if err != nil { - log.Error("Failed to marshal RPCResponse to JSON", "error", err) - } else { - wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds)) - if err = wsc.baseConn.WriteMessage(websocket.TextMessage, buf.Bytes()); err != nil { - log.Warn("Failed to write response on websocket", "error", err) - wsc.Stop() - return - } - } - } - } -} - -//---------------------------------------- - -// Main manager for all websocket connections -// Holds the event switch -// NOTE: The websocket path is defined externally, e.g. in node/node.go -type WebsocketManager struct { - websocket.Upgrader - funcMap map[string]*RPCFunc - evsw *events.EventSwitch -} - -func NewWebsocketManager(funcMap map[string]*RPCFunc, evsw *events.EventSwitch) *WebsocketManager { - return &WebsocketManager{ - funcMap: funcMap, - evsw: evsw, - Upgrader: websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - CheckOrigin: func(r *http.Request) bool { - // TODO - return true - }, - }, - } -} - -// Upgrade the request/response (via http.Hijack) and starts the WSConnection. -func (wm *WebsocketManager) WebsocketHandler(w http.ResponseWriter, r *http.Request) { - wsConn, err := wm.Upgrade(w, r, nil) - if err != nil { - // TODO - return http error - log.Error("Failed to upgrade to websocket connection", "error", err) - return - } - - // register connection - con := NewWSConnection(wsConn, wm.funcMap, wm.evsw) - log.Notice("New websocket connection", "origin", con.id) - con.Start() // Blocking -} - -// rpc.websocket -//----------------------------------------------------------------------------- - -// returns is result struct and error. If error is not nil, return it -func unreflectResult(returns []reflect.Value) (interface{}, error) { - errV := returns[1] - if errV.Interface() != nil { - return nil, fmt.Errorf("%v", errV.Interface()) - } - return returns[0].Interface(), nil -} - -// writes a list of available rpc endpoints as an html page -func writeListOfEndpoints(w http.ResponseWriter, r *http.Request, funcMap map[string]*RPCFunc) { - noArgNames := []string{} - argNames := []string{} - for name, funcData := range funcMap { - if len(funcData.args) == 0 { - noArgNames = append(noArgNames, name) - } else { - argNames = append(argNames, name) - } - } - sort.Strings(noArgNames) - sort.Strings(argNames) - buf := new(bytes.Buffer) - buf.WriteString("<html><body>") - buf.WriteString("<br>Available endpoints:<br>") - - for _, name := range noArgNames { - link := fmt.Sprintf("http://%s/%s", r.Host, name) - buf.WriteString(fmt.Sprintf("<a href=\"%s\">%s</a></br>", link, link)) - } - - buf.WriteString("<br>Endpoints that require arguments:<br>") - for _, name := range argNames { - link := fmt.Sprintf("http://%s/%s?", r.Host, name) - funcData := funcMap[name] - for i, argName := range funcData.argNames { - link += argName + "=_" - if i < len(funcData.argNames)-1 { - link += "&" - } - } - buf.WriteString(fmt.Sprintf("<a href=\"%s\">%s</a></br>", link, link)) - } - buf.WriteString("</body></html>") - w.Header().Set("Content-Type", "text/html") - w.WriteHeader(200) - w.Write(buf.Bytes()) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_params.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_params.go deleted file mode 100644 index acf5b4c8..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_params.go +++ /dev/null @@ -1,89 +0,0 @@ -package rpcserver - -import ( - "encoding/hex" - "fmt" - "net/http" - "regexp" - "strconv" -) - -var ( - // Parts of regular expressions - atom = "[A-Z0-9!#$%&'*+\\-/=?^_`{|}~]+" - dotAtom = atom + `(?:\.` + atom + `)*` - domain = `[A-Z0-9.-]+\.[A-Z]{2,4}` - - RE_HEX = regexp.MustCompile(`^(?i)[a-f0-9]+$`) - RE_EMAIL = regexp.MustCompile(`^(?i)(` + dotAtom + `)@(` + dotAtom + `)$`) - RE_ADDRESS = regexp.MustCompile(`^(?i)[a-z0-9]{25,34}$`) - RE_HOST = regexp.MustCompile(`^(?i)(` + domain + `)$`) - - //RE_ID12 = regexp.MustCompile(`^[a-zA-Z0-9]{12}$`) -) - -func GetParam(r *http.Request, param string) string { - s := r.URL.Query().Get(param) - if s == "" { - s = r.FormValue(param) - } - return s -} - -func GetParamByteSlice(r *http.Request, param string) ([]byte, error) { - s := GetParam(r, param) - return hex.DecodeString(s) -} - -func GetParamInt64(r *http.Request, param string) (int64, error) { - s := GetParam(r, param) - i, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return i, nil -} - -func GetParamInt32(r *http.Request, param string) (int32, error) { - s := GetParam(r, param) - i, err := strconv.ParseInt(s, 10, 32) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return int32(i), nil -} - -func GetParamUint64(r *http.Request, param string) (uint64, error) { - s := GetParam(r, param) - i, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return i, nil -} - -func GetParamUint(r *http.Request, param string) (uint, error) { - s := GetParam(r, param) - i, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return uint(i), nil -} - -func GetParamRegexp(r *http.Request, param string, re *regexp.Regexp) (string, error) { - s := GetParam(r, param) - if !re.MatchString(s) { - return "", fmt.Errorf(param, "Did not match regular expression %v", re.String()) - } - return s, nil -} - -func GetParamFloat64(r *http.Request, param string) (float64, error) { - s := GetParam(r, param) - f, err := strconv.ParseFloat(s, 64) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return f, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_server.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_server.go deleted file mode 100644 index f3e4b2ce..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_server.go +++ /dev/null @@ -1,121 +0,0 @@ -// Commons for HTTP handling -package rpcserver - -import ( - "bufio" - "bytes" - "fmt" - "net" - "net/http" - "runtime/debug" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/alert" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types" -) - -func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, error) { - log.Notice(Fmt("Starting RPC HTTP server on %v", listenAddr)) - listener, err := net.Listen("tcp", listenAddr) - if err != nil { - return nil, fmt.Errorf("Failed to listen to %v", listenAddr) - } - go func() { - res := http.Serve( - listener, - RecoverAndLogHandler(handler), - ) - log.Crit("RPC HTTP server stopped", "result", res) - }() - return listener, nil -} - -func WriteRPCResponse(w http.ResponseWriter, res RPCResponse) { - buf, n, err := new(bytes.Buffer), int(0), error(nil) - wire.WriteJSON(res, buf, &n, &err) - if err != nil { - log.Error("Failed to write RPC response", "error", err, "res", res) - } - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - w.Write(buf.Bytes()) -} - -//----------------------------------------------------------------------------- - -// Wraps an HTTP handler, adding error logging. -// If the inner function panics, the outer function recovers, logs, sends an -// HTTP 500 error response. -func RecoverAndLogHandler(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Wrap the ResponseWriter to remember the status - rww := &ResponseWriterWrapper{-1, w} - begin := time.Now() - - // Common headers - origin := r.Header.Get("Origin") - rww.Header().Set("Access-Control-Allow-Origin", origin) - rww.Header().Set("Access-Control-Allow-Credentials", "true") - rww.Header().Set("Access-Control-Expose-Headers", "X-Server-Time") - rww.Header().Set("X-Server-Time", fmt.Sprintf("%v", begin.Unix())) - - defer func() { - // Send a 500 error if a panic happens during a handler. - // Without this, Chrome & Firefox were retrying aborted ajax requests, - // at least to my localhost. - if e := recover(); e != nil { - - // If RPCResponse - if res, ok := e.(RPCResponse); ok { - WriteRPCResponse(rww, res) - } else { - // For the rest, - log.Error("Panic in RPC HTTP handler", "error", e, "stack", string(debug.Stack())) - rww.WriteHeader(http.StatusInternalServerError) - WriteRPCResponse(rww, NewRPCResponse("", nil, Fmt("Internal Server Error: %v", e))) - } - } - - // Finally, log. - durationMS := time.Since(begin).Nanoseconds() / 1000000 - if rww.Status == -1 { - rww.Status = 200 - } - log.Info("Served RPC HTTP response", - "method", r.Method, "url", r.URL, - "status", rww.Status, "duration", durationMS, - "remoteAddr", r.RemoteAddr, - ) - }() - - handler.ServeHTTP(rww, r) - }) -} - -// Remember the status for logging -type ResponseWriterWrapper struct { - Status int - http.ResponseWriter -} - -func (w *ResponseWriterWrapper) WriteHeader(status int) { - w.Status = status - w.ResponseWriter.WriteHeader(status) -} - -// implements http.Hijacker -func (w *ResponseWriterWrapper) Hijack() (net.Conn, *bufio.ReadWriter, error) { - return w.ResponseWriter.(http.Hijacker).Hijack() -} - -// Stick it as a deferred statement in gouroutines to prevent the program from crashing. -func Recover(daemonName string) { - if e := recover(); e != nil { - stack := string(debug.Stack()) - errorString := fmt.Sprintf("[%s] %s\n%s", daemonName, e, stack) - alert.Alert(errorString) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/log.go deleted file mode 100644 index aab9721f..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package rpcserver - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" -) - -var log = log15.New("module", "rpcserver") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types/types.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types/types.go deleted file mode 100644 index c93e6735..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types/types.go +++ /dev/null @@ -1,24 +0,0 @@ -package rpctypes - -type RPCRequest struct { - JSONRPC string `json:"jsonrpc"` - ID string `json:"id"` - Method string `json:"method"` - Params []interface{} `json:"params"` -} - -type RPCResponse struct { - JSONRPC string `json:"jsonrpc"` - ID string `json:"id"` - Result interface{} `json:"result"` - Error string `json:"error"` -} - -func NewRPCResponse(id string, res interface{}, err string) RPCResponse { - return RPCResponse{ - JSONRPC: "2.0", - ID: id, - Result: res, - Error: err, - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/version.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/version.go deleted file mode 100644 index 2982824d..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/version.go +++ /dev/null @@ -1,3 +0,0 @@ -package rpc - -const Version = "0.4.0" diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go deleted file mode 100644 index f323c19b..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go +++ /dev/null @@ -1,181 +0,0 @@ -package state - -import ( - "bytes" - "errors" - "fmt" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -// Execute the block to mutate State. -// Also, execute txs on the proxyAppCtx and validate apphash -// Rolls back before executing transactions. -// Rolls back if invalid, but never commits. -func (s *State) ExecBlock(proxyAppCtx proxy.AppContext, block *types.Block, blockPartsHeader types.PartSetHeader) error { - - // Validate the block. - err := s.validateBlock(block) - if err != nil { - return err - } - - // Update the validator set - valSet := s.Validators.Copy() - // Update valSet with signatures from block. - updateValidatorsWithBlock(s.LastValidators, valSet, block) - // TODO: Update the validator set (e.g. block.Data.ValidatorUpdates?) - nextValSet := valSet.Copy() - - // First, rollback. - if err != nil { - proxyAppCtx.RollbackSync() - return err - } - - // Execute, or rollback. (Does not commit) - err = s.execBlockOnProxyApp(proxyAppCtx, block) - if err != nil { - proxyAppCtx.RollbackSync() - return err - } - - // All good! - nextValSet.IncrementAccum(1) - s.Validators = nextValSet - s.LastValidators = valSet - s.LastAppHash = block.AppHash - s.LastBlockHeight = block.Height - s.LastBlockHash = block.Hash() - s.LastBlockParts = blockPartsHeader - s.LastBlockTime = block.Time - - return nil -} - -// Commits block on proxyAppCtx. -func (s *State) Commit(proxyAppCtx proxy.AppContext) error { - err := proxyAppCtx.CommitSync() - return err -} - -// Executes transactions on proxyAppCtx. -func (s *State) execBlockOnProxyApp(proxyAppCtx proxy.AppContext, block *types.Block) error { - // Execute transactions and get hash - var invalidTxErr error - proxyCb := func(req tmsp.Request, res tmsp.Response) { - switch res := res.(type) { - case tmsp.ResponseAppendTx: - reqAppendTx := req.(tmsp.RequestAppendTx) - if res.RetCode != tmsp.RetCodeOK { - if invalidTxErr == nil { - invalidTxErr = InvalidTxError{reqAppendTx.TxBytes, res.RetCode} - } - } - case tmsp.ResponseEvent: - s.evc.FireEvent(types.EventStringApp(), types.EventDataApp{res.Key, res.Data}) - } - } - proxyAppCtx.SetResponseCallback(proxyCb) - for _, tx := range block.Data.Txs { - proxyAppCtx.AppendTxAsync(tx) - if err := proxyAppCtx.Error(); err != nil { - return err - } - } - hash, err := proxyAppCtx.GetHashSync() - if err != nil { - log.Warn("Error computing proxyAppCtx hash", "error", err) - return err - } - if invalidTxErr != nil { - log.Warn("Invalid transaction in block") - return invalidTxErr - } - - // Check that appHash matches - if !bytes.Equal(block.AppHash, hash) { - log.Warn(Fmt("App hash in proposal was %X, computed %X instead", block.AppHash, hash)) - return InvalidAppHashError{block.AppHash, hash} - } - - return nil -} - -func (s *State) validateBlock(block *types.Block) error { - // Basic block validation. - err := block.ValidateBasic(s.ChainID, s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime) - if err != nil { - return err - } - - // Validate block LastValidation. - if block.Height == 1 { - if len(block.LastValidation.Precommits) != 0 { - return errors.New("Block at height 1 (first block) should have no LastValidation precommits") - } - } else { - if len(block.LastValidation.Precommits) != s.LastValidators.Size() { - return fmt.Errorf("Invalid block validation size. Expected %v, got %v", - s.LastValidators.Size(), len(block.LastValidation.Precommits)) - } - err := s.LastValidators.VerifyValidation( - s.ChainID, s.LastBlockHash, s.LastBlockParts, block.Height-1, block.LastValidation) - if err != nil { - return err - } - } - - return nil -} - -// Updates the LastCommitHeight of the validators in valSet, in place. -// Assumes that lastValSet matches the valset of block.LastValidators -// CONTRACT: lastValSet is not mutated. -func updateValidatorsWithBlock(lastValSet *types.ValidatorSet, valSet *types.ValidatorSet, block *types.Block) { - - for i, precommit := range block.LastValidation.Precommits { - if precommit == nil { - continue - } - _, val := lastValSet.GetByIndex(i) - if val == nil { - PanicCrisis(Fmt("Failed to fetch validator at index %v", i)) - } - if _, val_ := valSet.GetByAddress(val.Address); val_ != nil { - val_.LastCommitHeight = block.Height - 1 - updated := valSet.Update(val_) - if !updated { - PanicCrisis("Failed to update validator LastCommitHeight") - } - } else { - // XXX This is not an error if validator was removed. - // But, we don't mutate validators yet so go ahead and panic. - PanicCrisis("Could not find validator") - } - } - -} - -//----------------------------------------------------------------------------- - -type InvalidTxError struct { - Tx types.Tx - tmsp.RetCode -} - -func (txErr InvalidTxError) Error() string { - return Fmt("Invalid tx: [%v] code: [%v]", txErr.Tx, txErr.RetCode) -} - -type InvalidAppHashError struct { - Expected []byte - Got []byte -} - -func (hashErr InvalidAppHashError) Error() string { - return Fmt("Invalid hash: [%X] got: [%X]", hashErr.Expected, hashErr.Got) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go deleted file mode 100644 index 316471ea..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package state - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "state") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go deleted file mode 100644 index e890ea8c..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go +++ /dev/null @@ -1,139 +0,0 @@ -package state - -import ( - "bytes" - "io/ioutil" - "sync" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -var ( - stateKey = []byte("stateKey") -) - -//----------------------------------------------------------------------------- - -// NOTE: not goroutine-safe. -type State struct { - mtx sync.Mutex - db dbm.DB - GenesisDoc *types.GenesisDoc - ChainID string - LastBlockHeight int - LastBlockHash []byte - LastBlockParts types.PartSetHeader - LastBlockTime time.Time - Validators *types.ValidatorSet - LastValidators *types.ValidatorSet - LastAppHash []byte - - evc events.Fireable // typically an events.EventCache -} - -func LoadState(db dbm.DB) *State { - s := &State{db: db} - buf := db.Get(stateKey) - if len(buf) == 0 { - return nil - } else { - r, n, err := bytes.NewReader(buf), new(int), new(error) - wire.ReadBinaryPtr(&s, r, 0, n, err) - if *err != nil { - // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED - Exit(Fmt("Data has been corrupted or its spec has changed: %v\n", *err)) - } - // TODO: ensure that buf is completely read. - } - return s -} - -func (s *State) Copy() *State { - return &State{ - db: s.db, - GenesisDoc: s.GenesisDoc, - ChainID: s.ChainID, - LastBlockHeight: s.LastBlockHeight, - LastBlockHash: s.LastBlockHash, - LastBlockParts: s.LastBlockParts, - LastBlockTime: s.LastBlockTime, - Validators: s.Validators.Copy(), - LastValidators: s.LastValidators.Copy(), - LastAppHash: s.LastAppHash, - evc: nil, - } -} - -func (s *State) Save() { - s.mtx.Lock() - defer s.mtx.Unlock() - - buf, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(s, buf, n, err) - if *err != nil { - PanicCrisis(*err) - } - s.db.Set(stateKey, buf.Bytes()) -} - -// Implements events.Eventable. Typically uses events.EventCache -func (s *State) SetFireable(evc events.Fireable) { - s.mtx.Lock() - defer s.mtx.Unlock() - - s.evc = evc -} - -//----------------------------------------------------------------------------- -// Genesis - -func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) *State { - genDocJSON, err := ioutil.ReadFile(genDocFile) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) - } - genDoc := types.GenesisDocFromJSON(genDocJSON) - return MakeGenesisState(db, genDoc) -} - -func MakeGenesisState(db dbm.DB, genDoc *types.GenesisDoc) *State { - if len(genDoc.Validators) == 0 { - Exit(Fmt("The genesis file has no validators")) - } - - if genDoc.GenesisTime.IsZero() { - genDoc.GenesisTime = time.Now() - } - - // Make validators slice - validators := make([]*types.Validator, len(genDoc.Validators)) - for i, val := range genDoc.Validators { - pubKey := val.PubKey - address := pubKey.Address() - - // Make validator - validators[i] = &types.Validator{ - Address: address, - PubKey: pubKey, - VotingPower: val.Amount, - } - } - - return &State{ - db: db, - GenesisDoc: genDoc, - ChainID: genDoc.ChainID, - LastBlockHeight: 0, - LastBlockHash: nil, - LastBlockParts: types.PartSetHeader{}, - LastBlockTime: genDoc.GenesisTime, - Validators: types.NewValidatorSet(validators), - LastValidators: types.NewValidatorSet(nil), - LastAppHash: genDoc.AppHash, - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf deleted file mode 100644 index 0e10d8a5..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf +++ /dev/null @@ -1,68 +0,0 @@ -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=send -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=call -[34mINFO[0m[07-22|18:13:12] Out account: Account{DFF89D4BE8CDDC7A1993C91A1C7FFE32D3778570:<nil> B:1536646667 C:120 S: P:{Base: 100011111110; Set: 11111111111111 []}} [34mmodule[0m=state -[34mINFO[0m[07-22|18:13:12] Calling contract 000000000000000000000000DFF89D4BE8CDDC7A1993C91A1C7FFE32D3778570 with code 60606040526000357C0100000000000000000000000000000000000000000000000000000000900480632FEE78D7146037576035565B005B6040600450606C565B604051808273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16815260200191505060405180910390F35B60003390506075565B9056 [34mmodule[0m=state -[34mINFO[0m[07-22|18:13:12] Code for this contract: 60606040526000357C0100000000000000000000000000000000000000000000000000000000900480632FEE78D7146037576035565B005B6040600450606C565B604051808273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16815260200191505060405180910390F35B60003390506075565B9056 [34mmodule[0m=state -(1) (00000000) 000000000000000000000000DFF89D4BE8CDDC7A1993C91A1C7FFE32D3778570 (code=120) gas: 1000 (d) 2FEE78D7 -(pc) 0 (op) PUSH1 (st) 0 => 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 2 (op) PUSH1 (st) 1 => 0x0000000000000000000000000000000000000000000000000000000000000040 -(pc) 4 (op) MSTORE (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 5 (op) PUSH1 (st) 0 => 0x0000000000000000000000000000000000000000000000000000000000000000 -(pc) 7 (op) CALLDATALOAD (st) 1 => 0x2FEE78D700000000000000000000000000000000000000000000000000000000 -(pc) 8 (op) PUSH29 (st) 1 => 0x0000000100000000000000000000000000000000000000000000000000000000 -(pc) 38 (op) SWAP1 (st) 2 => [2] 2FEE78D700000000000000000000000000000000000000000000000000000000 -(pc) 39 (op) DIV (st) 2 21680047490780924029029108358227327141478116379726555908761811030043504148480 / 26959946667150639794667015087019630673637144422540572481103610249216 = 804157655 (000000000000000000000000000000000000000000000000000000002FEE78D7) -(pc) 40 (op) DUP1 (st) 1 => [1] 0x000000000000000000000000000000000000000000000000000000002FEE78D7 -(pc) 41 (op) PUSH4 (st) 2 => 0x000000000000000000000000000000000000000000000000000000002FEE78D7 -(pc) 46 (op) EQ (st) 3 000000000000000000000000000000000000000000000000000000002FEE78D7 == 000000000000000000000000000000000000000000000000000000002FEE78D7 = 1 -(pc) 47 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000037 -(pc) 49 (op) JUMPI (st) 3 ~> 55 -(pc) 55 (op) JUMPDEST (st) 1 -(pc) 56 (op) PUSH1 (st) 1 => 0x0000000000000000000000000000000000000000000000000000000000000040 -(pc) 58 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000004 -(pc) 60 (op) POP (st) 3 => 10000000 -(pc) 61 (op) PUSH1 (st) 2 => 0x000000000000000000000000000000000000000000000000000000000000006C -(pc) 63 (op) JUMP (st) 3 ~> 108 -(pc) 108 (op) JUMPDEST (st) 2 -(pc) 109 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000000 -(pc) 111 (op) CALLER (st) 3 => 000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 112 (op) SWAP1 (st) 4 => [2] 0000000000000000000000000000000000000000000000000000000000000000 -(pc) 113 (op) POP (st) 4 => 10000000 -(pc) 114 (op) PUSH1 (st) 3 => 0x0000000000000000000000000000000000000000000000000000000000000075 -(pc) 116 (op) JUMP (st) 4 ~> 117 -(pc) 117 (op) JUMPDEST (st) 3 -(pc) 118 (op) SWAP1 (st) 3 => [2] 0000000000000000000000000000000000000000000000000000000000000040 -(pc) 119 (op) JUMP (st) 3 ~> 64 -(pc) 64 (op) JUMPDEST (st) 2 -(pc) 65 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000040 -(pc) 67 (op) MLOAD (st) 3 => 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 68 (op) DUP1 (st) 3 => [1] 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 69 (op) DUP3 (st) 4 => [3] 0x000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 70 (op) PUSH20 (st) 5 => 0x000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -(pc) 91 (op) AND (st) 6 000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF & 000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 = 000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 92 (op) DUP2 (st) 5 => [2] 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 93 (op) MSTORE (st) 6 => 0x000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 94 (op) PUSH1 (st) 4 => 0x0000000000000000000000000000000000000000000000000000000000000020 -(pc) 96 (op) ADD (st) 5 32 + 96 = 128 (0000000000000000000000000000000000000000000000000000000000000080) -(pc) 97 (op) SWAP2 (st) 4 => [3] 000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 98 (op) POP (st) 4 => 10000000 -(pc) 99 (op) POP (st) 3 => 10000000 -(pc) 100 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000040 -(pc) 102 (op) MLOAD (st) 3 => 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 103 (op) DUP1 (st) 3 => [1] 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 104 (op) SWAP2 (st) 4 => [3] 0000000000000000000000000000000000000000000000000000000000000080 -(pc) 105 (op) SUB (st) 4 128 - 96 = 32 (0000000000000000000000000000000000000000000000000000000000000020) -(pc) 106 (op) SWAP1 (st) 3 => [2] 0000000000000000000000000000000000000000000000000000000000000060 -(pc) 107 (op) RETURN (st) 3 => [96, 32] (32) 0x000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -[34mINFO[0m[07-22|18:13:12] Successful execution [34mmodule[0m=state -[32mNOTE[0m[07-22|18:13:12] VM call complete [32mmodule[0m=state [32mcaller[0m="VMAccount{000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 B:1529024268 C: N:1 S:0000000000000000000000000000000000000000000000000000000000000000}" [32mcallee[0m="VMAccount{000000000000000000000000DFF89D4BE8CDDC7A1993C91A1C7FFE32D3778570 B:1536646668 C:60606040526000357C0100000000000000000000000000000000000000000000000000000000900480632FEE78D7146037576035565B005B6040600450606C565B604051808273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16815260200191505060405180910390F35B60003390506075565B9056 N:0 S:0000000000000000000000000000000000000000000000000000000000000000}" [32mreturn[0m=000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [32merr[0m=nil -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=name -[34mINFO[0m[07-22|18:13:12] New NameTx [34mmodule[0m=state [34mvalue[0m=10000 [34mcostPerBlock[0m=1237 [34mexpiresIn[0m=8 [34mlastBlock[0m=0 -[34mINFO[0m[07-22|18:13:12] Creating namereg entry [34mmodule[0m=state [34mname[0m=satoshi [34mexpiresIn[0m=8 -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=name -[34mINFO[0m[07-22|18:13:12] Invalid characters found in NameTx.Data (�€Èû). Only the kind of things found in a JSON file are allowed [34mmodule[0m=state -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=create_account -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=bond -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=bond -PASS -ok github.com/tendermint/tendermint/state 0.311s diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/README.md b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/README.md deleted file mode 100644 index f99294b0..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# `tendermint/block` - -## Block - -TODO: document - -### Header - -### Validation - -### Data - -## PartSet - -PartSet is used to split a byteslice of data into parts (pieces) for transmission. -By splitting data into smaller parts and computing a Merkle root hash on the list, -you can verify that a part is legitimately part of the complete data, and the -part can be forwarded to other peers before all the parts are known. In short, -it's a fast way to propagate a large file over a gossip network. - -PartSet was inspired by the LibSwift project. - -Usage: - -```Go -data := RandBytes(2 << 20) // Something large - -partSet := NewPartSetFromData(data) -partSet.Total() // Total number of 4KB parts -partSet.Count() // Equal to the Total, since we already have all the parts -partSet.Hash() // The Merkle root hash -partSet.BitArray() // A BitArray of partSet.Total() 1's - -header := partSet.Header() // Send this to the peer -header.Total // Total number of parts -header.Hash // The merkle root hash - -// Now we'll reconstruct the data from the parts -partSet2 := NewPartSetFromHeader(header) -partSet2.Total() // Same total as partSet.Total() -partSet2.Count() // Zero, since this PartSet doesn't have any parts yet. -partSet2.Hash() // Same hash as in partSet.Hash() -partSet2.BitArray() // A BitArray of partSet.Total() 0's - -// In a gossip network the parts would arrive in arbitrary order, perhaps -// in response to explicit requests for parts, or optimistically in response -// to the receiving peer's partSet.BitArray(). -for !partSet2.IsComplete() { - part := receivePartFromGossipNetwork() - added, err := partSet2.AddPart(part) - if err != nil { - // A wrong part, - // the merkle trail does not hash to partSet2.Hash() - } else if !added { - // A duplicate part already received - } -} - -data2, _ := ioutil.ReadAll(partSet2.GetReader()) -bytes.Equal(data, data2) // true -``` diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go deleted file mode 100644 index 8b68b96f..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go +++ /dev/null @@ -1,355 +0,0 @@ -package types - -import ( - "bytes" - "errors" - "fmt" - "strings" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -const MaxBlockSize = 22020096 // 21MB TODO make it configurable - -type Block struct { - *Header `json:"header"` - *Data `json:"data"` - LastValidation *Validation `json:"last_validation"` -} - -// Basic validation that doesn't involve state data. -func (b *Block) ValidateBasic(chainID string, lastBlockHeight int, lastBlockHash []byte, - lastBlockParts PartSetHeader, lastBlockTime time.Time) error { - if b.ChainID != chainID { - return errors.New(Fmt("Wrong Block.Header.ChainID. Expected %v, got %v", chainID, b.ChainID)) - } - if b.Height != lastBlockHeight+1 { - return errors.New(Fmt("Wrong Block.Header.Height. Expected %v, got %v", lastBlockHeight+1, b.Height)) - } - /* TODO: Determine bounds for Time - See blockchain/reactor "stopSyncingDurationMinutes" - - if !b.Time.After(lastBlockTime) { - return errors.New("Invalid Block.Header.Time") - } - */ - // TODO: validate Fees - if b.NumTxs != len(b.Data.Txs) { - return errors.New(Fmt("Wrong Block.Header.NumTxs. Expected %v, got %v", len(b.Data.Txs), b.NumTxs)) - } - if !bytes.Equal(b.LastBlockHash, lastBlockHash) { - return errors.New(Fmt("Wrong Block.Header.LastBlockHash. Expected %X, got %X", lastBlockHash, b.LastBlockHash)) - } - if !b.LastBlockParts.Equals(lastBlockParts) { - return errors.New(Fmt("Wrong Block.Header.LastBlockParts. Expected %v, got %v", lastBlockParts, b.LastBlockParts)) - } - if !bytes.Equal(b.LastValidationHash, b.LastValidation.Hash()) { - return errors.New(Fmt("Wrong Block.Header.LastValidationHash. Expected %X, got %X", b.LastValidationHash, b.LastValidation.Hash())) - } - if b.Header.Height != 1 { - if err := b.LastValidation.ValidateBasic(); err != nil { - return err - } - } - if !bytes.Equal(b.DataHash, b.Data.Hash()) { - return errors.New(Fmt("Wrong Block.Header.DataHash. Expected %X, got %X", b.DataHash, b.Data.Hash())) - } - // NOTE: the AppHash and ValidatorsHash are validated later. - return nil -} - -func (b *Block) FillHeader() { - b.LastValidationHash = b.LastValidation.Hash() - b.DataHash = b.Data.Hash() -} - -// Computes and returns the block hash. -// If the block is incomplete, block hash is nil for safety. -func (b *Block) Hash() []byte { - if b.Header == nil || b.Data == nil || b.LastValidation == nil { - return nil - } - b.FillHeader() - return b.Header.Hash() -} - -func (b *Block) MakePartSet() *PartSet { - return NewPartSetFromData(wire.BinaryBytes(b)) -} - -// Convenience. -// A nil block never hashes to anything. -// Nothing hashes to a nil hash. -func (b *Block) HashesTo(hash []byte) bool { - if len(hash) == 0 { - return false - } - if b == nil { - return false - } - return bytes.Equal(b.Hash(), hash) -} - -func (b *Block) String() string { - return b.StringIndented("") -} - -func (b *Block) StringIndented(indent string) string { - if b == nil { - return "nil-Block" - } - return fmt.Sprintf(`Block{ -%s %v -%s %v -%s %v -%s}#%X`, - indent, b.Header.StringIndented(indent+" "), - indent, b.Data.StringIndented(indent+" "), - indent, b.LastValidation.StringIndented(indent+" "), - indent, b.Hash()) -} - -func (b *Block) StringShort() string { - if b == nil { - return "nil-Block" - } else { - return fmt.Sprintf("Block#%X", b.Hash()) - } -} - -//----------------------------------------------------------------------------- - -type Header struct { - ChainID string `json:"chain_id"` - Height int `json:"height"` - Time time.Time `json:"time"` - Fees int64 `json:"fees"` - NumTxs int `json:"num_txs"` - LastBlockHash []byte `json:"last_block_hash"` - LastBlockParts PartSetHeader `json:"last_block_parts"` - LastValidationHash []byte `json:"last_validation_hash"` - DataHash []byte `json:"data_hash"` - ValidatorsHash []byte `json:"validators_hash"` - AppHash []byte `json:"app_hash"` -} - -// NOTE: hash is nil if required fields are missing. -func (h *Header) Hash() []byte { - if len(h.ValidatorsHash) == 0 { - return nil - } - return merkle.SimpleHashFromMap(map[string]interface{}{ - "ChainID": h.ChainID, - "Height": h.Height, - "Time": h.Time, - "Fees": h.Fees, - "NumTxs": h.NumTxs, - "LastBlock": h.LastBlockHash, - "LastBlockParts": h.LastBlockParts, - "LastValidation": h.LastValidationHash, - "Data": h.DataHash, - "Validators": h.ValidatorsHash, - "App": h.AppHash, - }) -} - -func (h *Header) StringIndented(indent string) string { - if h == nil { - return "nil-Header" - } - return fmt.Sprintf(`Header{ -%s ChainID: %v -%s Height: %v -%s Time: %v -%s Fees: %v -%s NumTxs: %v -%s LastBlock: %X -%s LastBlockParts: %v -%s LastValidation: %X -%s Data: %X -%s Validators: %X -%s App: %X -%s}#%X`, - indent, h.ChainID, - indent, h.Height, - indent, h.Time, - indent, h.Fees, - indent, h.NumTxs, - indent, h.LastBlockHash, - indent, h.LastBlockParts, - indent, h.LastValidationHash, - indent, h.DataHash, - indent, h.ValidatorsHash, - indent, h.AppHash, - indent, h.Hash()) -} - -//------------------------------------- - -// NOTE: Validation is empty for height 1, but never nil. -type Validation struct { - // NOTE: The Precommits are in order of address to preserve the bonded ValidatorSet order. - // Any peer with a block can gossip precommits by index with a peer without recalculating the - // active ValidatorSet. - Precommits []*Vote `json:"precommits"` - - // Volatile - firstPrecommit *Vote - hash []byte - bitArray *BitArray -} - -func (v *Validation) FirstPrecommit() *Vote { - if len(v.Precommits) == 0 { - return nil - } - if v.firstPrecommit != nil { - return v.firstPrecommit - } - for _, precommit := range v.Precommits { - if precommit != nil { - v.firstPrecommit = precommit - return precommit - } - } - return nil -} - -func (v *Validation) Height() int { - if len(v.Precommits) == 0 { - return 0 - } - return v.FirstPrecommit().Height -} - -func (v *Validation) Round() int { - if len(v.Precommits) == 0 { - return 0 - } - return v.FirstPrecommit().Round -} - -func (v *Validation) Type() byte { - return VoteTypePrecommit -} - -func (v *Validation) Size() int { - if v == nil { - return 0 - } - return len(v.Precommits) -} - -func (v *Validation) BitArray() *BitArray { - if v.bitArray == nil { - v.bitArray = NewBitArray(len(v.Precommits)) - for i, precommit := range v.Precommits { - v.bitArray.SetIndex(i, precommit != nil) - } - } - return v.bitArray -} - -func (v *Validation) GetByIndex(index int) *Vote { - return v.Precommits[index] -} - -func (v *Validation) IsCommit() bool { - if len(v.Precommits) == 0 { - return false - } - return true -} - -func (v *Validation) ValidateBasic() error { - if len(v.Precommits) == 0 { - return errors.New("No precommits in validation") - } - height, round := v.Height(), v.Round() - for _, precommit := range v.Precommits { - // It's OK for precommits to be missing. - if precommit == nil { - continue - } - // Ensure that all votes are precommits - if precommit.Type != VoteTypePrecommit { - return fmt.Errorf("Invalid validation vote. Expected precommit, got %v", - precommit.Type) - } - // Ensure that all heights are the same - if precommit.Height != height { - return fmt.Errorf("Invalid validation precommit height. Expected %v, got %v", - height, precommit.Height) - } - // Ensure that all rounds are the same - if precommit.Round != round { - return fmt.Errorf("Invalid validation precommit round. Expected %v, got %v", - round, precommit.Round) - } - } - return nil -} - -func (v *Validation) Hash() []byte { - if v.hash == nil { - bs := make([]interface{}, len(v.Precommits)) - for i, precommit := range v.Precommits { - bs[i] = precommit - } - v.hash = merkle.SimpleHashFromBinaries(bs) - } - return v.hash -} - -func (v *Validation) StringIndented(indent string) string { - if v == nil { - return "nil-Validation" - } - precommitStrings := make([]string, len(v.Precommits)) - for i, precommit := range v.Precommits { - precommitStrings[i] = precommit.String() - } - return fmt.Sprintf(`Validation{ -%s Precommits: %v -%s}#%X`, - indent, strings.Join(precommitStrings, "\n"+indent+" "), - indent, v.hash) -} - -//----------------------------------------------------------------------------- - -type Data struct { - Txs []Tx `json:"txs"` - - // Volatile - hash []byte -} - -func (data *Data) Hash() []byte { - if data.hash == nil { - txs := make([]interface{}, len(data.Txs)) - for i, tx := range data.Txs { - txs[i] = tx - } - data.hash = merkle.SimpleHashFromBinaries(txs) // NOTE: leaves are TxIDs. - } - return data.hash -} - -func (data *Data) StringIndented(indent string) string { - if data == nil { - return "nil-Data" - } - txStrings := make([]string, len(data.Txs)) - for i, tx := range data.Txs { - txStrings[i] = fmt.Sprintf("Tx:%v", tx) - } - return fmt.Sprintf(`Data{ -%s %v -%s}#%X`, - indent, strings.Join(txStrings, "\n"+indent+" "), - indent, data.hash) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block_meta.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block_meta.go deleted file mode 100644 index b72c0c86..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block_meta.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -type BlockMeta struct { - Hash []byte `json:"hash"` // The block hash - Header *Header `json:"header"` // The block's Header - PartsHeader PartSetHeader `json:"parts_header"` // The PartSetHeader, for transfer -} - -func NewBlockMeta(block *Block, blockParts *PartSet) *BlockMeta { - return &BlockMeta{ - Hash: block.Hash(), - Header: block.Header, - PartsHeader: blockParts.Header(), - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go deleted file mode 100644 index e8f96401..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go deleted file mode 100644 index 67510baa..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go +++ /dev/null @@ -1,102 +0,0 @@ -package types - -import ( - "time" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// Functions to generate eventId strings - -// Reserved -func EventStringBond() string { return "Bond" } -func EventStringUnbond() string { return "Unbond" } -func EventStringRebond() string { return "Rebond" } -func EventStringDupeout() string { return "Dupeout" } -func EventStringFork() string { return "Fork" } - -func EventStringNewBlock() string { return "NewBlock" } -func EventStringNewRound() string { return "NewRound" } -func EventStringTimeoutPropose() string { return "TimeoutPropose" } -func EventStringCompleteProposal() string { return "CompleteProposal" } -func EventStringPolka() string { return "Polka" } -func EventStringUnlock() string { return "Unlock" } -func EventStringLock() string { return "Lock" } -func EventStringRelock() string { return "Relock" } -func EventStringTimeoutWait() string { return "TimeoutWait" } -func EventStringVote() string { return "Vote" } -func EventStringApp() string { return "App" } - -//---------------------------------------- - -const ( - EventDataTypeNewBlock = byte(0x01) - EventDataTypeFork = byte(0x02) - EventDataTypeTx = byte(0x03) - EventDataTypeApp = byte(0x04) // Custom app event - - EventDataTypeRoundState = byte(0x11) - EventDataTypeVote = byte(0x12) -) - -type EventData interface { - AssertIsEventData() -} - -var _ = wire.RegisterInterface( - struct{ EventData }{}, - wire.ConcreteType{EventDataNewBlock{}, EventDataTypeNewBlock}, - // wire.ConcreteType{EventDataFork{}, EventDataTypeFork }, - wire.ConcreteType{EventDataTx{}, EventDataTypeTx}, - wire.ConcreteType{EventDataApp{}, EventDataTypeApp}, - wire.ConcreteType{EventDataRoundState{}, EventDataTypeRoundState}, - wire.ConcreteType{EventDataVote{}, EventDataTypeVote}, -) - -// Most event messages are basic types (a block, a transaction) -// but some (an input to a call tx or a receive) are more exotic - -type EventDataNewBlock struct { - Block *Block `json:"block"` -} - -// All txs fire EventDataTx -type EventDataTx struct { - Tx Tx `json:"tx"` - Return []byte `json:"return"` - Exception string `json:"exception"` -} - -type EventDataApp struct { - Key string `json:"key"` - Data []byte `json:"bytes"` -} - -// We fire the most recent round state that led to the event -// (ie. NewRound will have the previous rounds state) -type EventDataRoundState struct { - CurrentTime time.Time `json:"current_time"` - - Height int `json:"height"` - Round int `json:"round"` - Step string `json:"step"` - StartTime time.Time `json:"start_time"` - CommitTime time.Time `json:"commit_time"` - Proposal *Proposal `json:"proposal"` - ProposalBlock *Block `json:"proposal_block"` - LockedRound int `json:"locked_round"` - LockedBlock *Block `json:"locked_block"` - POLRound int `json:"pol_round"` -} - -type EventDataVote struct { - Index int - Address []byte - Vote *Vote -} - -func (_ EventDataNewBlock) AssertIsEventData() {} -func (_ EventDataTx) AssertIsEventData() {} -func (_ EventDataApp) AssertIsEventData() {} -func (_ EventDataRoundState) AssertIsEventData() {} -func (_ EventDataVote) AssertIsEventData() {} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/genesis.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/genesis.go deleted file mode 100644 index 0966cf23..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/genesis.go +++ /dev/null @@ -1,48 +0,0 @@ -package types - -import ( - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -//------------------------------------------------------------ -// we store the gendoc in the db - -var GenDocKey = []byte("GenDocKey") - -//------------------------------------------------------------ -// core types for a genesis definition - -type GenesisValidator struct { - PubKey crypto.PubKeyEd25519 `json:"pub_key"` - Amount int64 `json:"amount"` - Name string `json:"name"` -} - -type GenesisDoc struct { - GenesisTime time.Time `json:"genesis_time"` - ChainID string `json:"chain_id"` - Validators []GenesisValidator `json:"validators"` - AppHash []byte `json:"app_hash"` -} - -// Utility method for saving GenensisDoc as JSON file. -func (genDoc *GenesisDoc) SaveAs(file string) error { - genDocBytes := wire.JSONBytes(genDoc) - return WriteFile(file, genDocBytes, 0644) -} - -//------------------------------------------------------------ -// Make genesis state from file - -func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) { - var err error - wire.ReadJSONPtr(&genState, jsonBlob, &err) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc: %v", err)) - } - return -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/keys.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/keys.go deleted file mode 100644 index 90591b95..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/keys.go +++ /dev/null @@ -1,6 +0,0 @@ -package types - -var ( - PeerStateKey = "ConsensusReactor.peerState" - PeerMempoolChKey = "MempoolReactor.peerMempoolCh" -) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/log.go deleted file mode 100644 index 1f22008f..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package types - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "types") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/myfile b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/myfile deleted file mode 100644 index d4401eddd73a489b7f045232f80c08e4c7f2dc41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 598 zcmZQ%WMX7w%gie%Eiq&O0|QHDMouFJ2AD9A2?qI$_ke;x)$IADB?#q=zHkw!O2$20 zIL+it&d)0;N=$}X#*hy+{T?H0N@7W(Ar~{uUbu4@e*x{~O3%+v&q>uw&d+5OFHTJ^ zN-fE$)XU2+(L+c;jADMlCCF%<rM~Cfwk5hri&tFG%I7UkH4-hCedN5%>VU_>?#Nr3 tj8JRIrf3puLW~@VDJey%#l?n<`4l^mOPIRGDPWBmCWIx>z+`0P0s!aXQ}F-* diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set.go deleted file mode 100644 index 8bf2b3cf..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set.go +++ /dev/null @@ -1,241 +0,0 @@ -package types - -import ( - "bytes" - "errors" - "fmt" - "io" - "sync" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -const ( - partSize = 4096 // 4KB -) - -var ( - ErrPartSetUnexpectedIndex = errors.New("Error part set unexpected index") - ErrPartSetInvalidProof = errors.New("Error part set invalid proof") -) - -type Part struct { - Proof merkle.SimpleProof `json:"proof"` - Bytes []byte `json:"bytes"` - - // Cache - hash []byte -} - -func (part *Part) Hash() []byte { - if part.hash != nil { - return part.hash - } else { - hasher := ripemd160.New() - hasher.Write(part.Bytes) // doesn't err - part.hash = hasher.Sum(nil) - return part.hash - } -} - -func (part *Part) String() string { - return part.StringIndented("") -} - -func (part *Part) StringIndented(indent string) string { - return fmt.Sprintf(`Part{ -%s Proof: %v -%s Bytes: %X -%s}`, - indent, part.Proof.StringIndented(indent+" "), - indent, part.Bytes, - indent) -} - -//------------------------------------- - -type PartSetHeader struct { - Total int `json:"total"` - Hash []byte `json:"hash"` -} - -func (psh PartSetHeader) String() string { - return fmt.Sprintf("PartSet{T:%v %X}", psh.Total, Fingerprint(psh.Hash)) -} - -func (psh PartSetHeader) IsZero() bool { - return psh.Total == 0 -} - -func (psh PartSetHeader) Equals(other PartSetHeader) bool { - return psh.Total == other.Total && bytes.Equal(psh.Hash, other.Hash) -} - -func (psh PartSetHeader) WriteSignBytes(w io.Writer, n *int, err *error) { - wire.WriteTo([]byte(Fmt(`{"hash":"%X","total":%v}`, psh.Hash, psh.Total)), w, n, err) -} - -//------------------------------------- - -type PartSet struct { - total int - hash []byte - - mtx sync.Mutex - parts []*Part - partsBitArray *BitArray - count int -} - -// Returns an immutable, full PartSet from the data bytes. -// The data bytes are split into "partSize" chunks, and merkle tree computed. -func NewPartSetFromData(data []byte) *PartSet { - // divide data into 4kb parts. - total := (len(data) + partSize - 1) / partSize - parts := make([]*Part, total) - parts_ := make([]merkle.Hashable, total) - partsBitArray := NewBitArray(total) - for i := 0; i < total; i++ { - part := &Part{ - Bytes: data[i*partSize : MinInt(len(data), (i+1)*partSize)], - } - parts[i] = part - parts_[i] = part - partsBitArray.SetIndex(i, true) - } - // Compute merkle proofs - proofs := merkle.SimpleProofsFromHashables(parts_) - for i := 0; i < total; i++ { - parts[i].Proof = *proofs[i] - } - return &PartSet{ - total: total, - hash: proofs[0].RootHash, - parts: parts, - partsBitArray: partsBitArray, - count: total, - } -} - -// Returns an empty PartSet ready to be populated. -func NewPartSetFromHeader(header PartSetHeader) *PartSet { - return &PartSet{ - total: header.Total, - hash: header.Hash, - parts: make([]*Part, header.Total), - partsBitArray: NewBitArray(header.Total), - count: 0, - } -} - -func (ps *PartSet) Header() PartSetHeader { - if ps == nil { - return PartSetHeader{} - } else { - return PartSetHeader{ - Total: ps.total, - Hash: ps.hash, - } - } -} - -func (ps *PartSet) HasHeader(header PartSetHeader) bool { - if ps == nil { - return false - } else { - return ps.Header().Equals(header) - } -} - -func (ps *PartSet) BitArray() *BitArray { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return ps.partsBitArray.Copy() -} - -func (ps *PartSet) Hash() []byte { - if ps == nil { - return nil - } - return ps.hash -} - -func (ps *PartSet) HashesTo(hash []byte) bool { - if ps == nil { - return false - } - return bytes.Equal(ps.hash, hash) -} - -func (ps *PartSet) Count() int { - if ps == nil { - return 0 - } - return ps.count -} - -func (ps *PartSet) Total() int { - if ps == nil { - return 0 - } - return ps.total -} - -func (ps *PartSet) AddPart(part *Part) (bool, error) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - // Invalid part index - if part.Proof.Index >= ps.total { - return false, ErrPartSetUnexpectedIndex - } - - // If part already exists, return false. - if ps.parts[part.Proof.Index] != nil { - return false, nil - } - - // Check hash proof - if !part.Proof.Verify(part.Hash(), ps.Hash()) { - return false, ErrPartSetInvalidProof - } - - // Add part - ps.parts[part.Proof.Index] = part - ps.partsBitArray.SetIndex(part.Proof.Index, true) - ps.count++ - return true, nil -} - -func (ps *PartSet) GetPart(index int) *Part { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return ps.parts[index] -} - -func (ps *PartSet) IsComplete() bool { - return ps.count == ps.total -} - -func (ps *PartSet) GetReader() io.Reader { - if !ps.IsComplete() { - PanicSanity("Cannot GetReader() on incomplete PartSet") - } - buf := []byte{} - for _, part := range ps.parts { - buf = append(buf, part.Bytes...) - } - return bytes.NewReader(buf) -} - -func (ps *PartSet) StringShort() string { - if ps == nil { - return "nil-PartSet" - } else { - return fmt.Sprintf("(%v of %v)", ps.Count(), ps.Total()) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set_test.go deleted file mode 100644 index 565a3b51..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package types - -import ( - "bytes" - "io/ioutil" - "testing" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" -) - -func TestBasicPartSet(t *testing.T) { - - // Construct random data of size partSize * 100 - data := RandBytes(partSize * 100) - - partSet := NewPartSetFromData(data) - if len(partSet.Hash()) == 0 { - t.Error("Expected to get hash") - } - if partSet.Total() != 100 { - t.Errorf("Expected to get 100 parts, but got %v", partSet.Total()) - } - if !partSet.IsComplete() { - t.Errorf("PartSet should be complete") - } - - // Test adding parts to a new partSet. - partSet2 := NewPartSetFromHeader(partSet.Header()) - - for i := 0; i < partSet.Total(); i++ { - part := partSet.GetPart(i) - //t.Logf("\n%v", part) - added, err := partSet2.AddPart(part) - if !added || err != nil { - t.Errorf("Failed to add part %v, error: %v", i, err) - } - } - - if !bytes.Equal(partSet.Hash(), partSet2.Hash()) { - t.Error("Expected to get same hash") - } - if partSet2.Total() != 100 { - t.Errorf("Expected to get 100 parts, but got %v", partSet2.Total()) - } - if !partSet2.IsComplete() { - t.Errorf("Reconstructed PartSet should be complete") - } - - // Reconstruct data, assert that they are equal. - data2Reader := partSet2.GetReader() - data2, err := ioutil.ReadAll(data2Reader) - if err != nil { - t.Errorf("Error reading data2Reader: %v", err) - } - if !bytes.Equal(data, data2) { - t.Errorf("Got wrong data.") - } - -} - -func TestWrongProof(t *testing.T) { - - // Construct random data of size partSize * 100 - data := RandBytes(partSize * 100) - partSet := NewPartSetFromData(data) - - // Test adding a part with wrong data. - partSet2 := NewPartSetFromHeader(partSet.Header()) - - // Test adding a part with wrong trail. - part := partSet.GetPart(0) - part.Proof.InnerHashes[0][0] += byte(0x01) - added, err := partSet2.AddPart(part) - if added || err == nil { - t.Errorf("Expected to fail adding a part with bad trail.") - } - - // Test adding a part with wrong bytes. - part = partSet.GetPart(1) - part.Bytes[0] += byte(0x01) - added, err = partSet2.AddPart(part) - if added || err == nil { - t.Errorf("Expected to fail adding a part with bad bytes.") - } - -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/priv_validator.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/priv_validator.go deleted file mode 100644 index c4d62407..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/priv_validator.go +++ /dev/null @@ -1,197 +0,0 @@ -package types - -import ( - "bytes" - "errors" - "fmt" - "io/ioutil" - "os" - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" -) - -const ( - stepNone = 0 // Used to distinguish the initial state - stepPropose = 1 - stepPrevote = 2 - stepPrecommit = 3 -) - -func voteToStep(vote *Vote) int8 { - switch vote.Type { - case VoteTypePrevote: - return stepPrevote - case VoteTypePrecommit: - return stepPrecommit - default: - PanicSanity("Unknown vote type") - return 0 - } -} - -type PrivValidator struct { - Address []byte `json:"address"` - PubKey crypto.PubKeyEd25519 `json:"pub_key"` - PrivKey crypto.PrivKeyEd25519 `json:"priv_key"` - LastHeight int `json:"last_height"` - LastRound int `json:"last_round"` - LastStep int8 `json:"last_step"` - - // For persistence. - // Overloaded for testing. - filePath string - mtx sync.Mutex -} - -// Generates a new validator with private key. -func GenPrivValidator() *PrivValidator { - privKeyBytes := new([64]byte) - copy(privKeyBytes[:32], CRandBytes(32)) - pubKeyBytes := ed25519.MakePublicKey(privKeyBytes) - pubKey := crypto.PubKeyEd25519(*pubKeyBytes) - privKey := crypto.PrivKeyEd25519(*privKeyBytes) - return &PrivValidator{ - Address: pubKey.Address(), - PubKey: pubKey, - PrivKey: privKey, - LastHeight: 0, - LastRound: 0, - LastStep: stepNone, - filePath: "", - } -} - -func LoadPrivValidator(filePath string) *PrivValidator { - privValJSONBytes, err := ioutil.ReadFile(filePath) - if err != nil { - Exit(err.Error()) - } - privVal := wire.ReadJSON(&PrivValidator{}, privValJSONBytes, &err).(*PrivValidator) - if err != nil { - Exit(Fmt("Error reading PrivValidator from %v: %v\n", filePath, err)) - } - privVal.filePath = filePath - return privVal -} - -func LoadOrGenPrivValidator(filePath string) *PrivValidator { - var privValidator *PrivValidator - if _, err := os.Stat(filePath); err == nil { - privValidator = LoadPrivValidator(filePath) - log.Notice("Loaded PrivValidator", - "file", filePath, "privValidator", privValidator) - } else { - privValidator = GenPrivValidator() - privValidator.SetFile(filePath) - privValidator.Save() - log.Notice("Generated PrivValidator", "file", filePath) - } - return privValidator -} - -func (privVal *PrivValidator) SetFile(filePath string) { - privVal.mtx.Lock() - defer privVal.mtx.Unlock() - privVal.filePath = filePath -} - -func (privVal *PrivValidator) Save() { - privVal.mtx.Lock() - defer privVal.mtx.Unlock() - privVal.save() -} - -func (privVal *PrivValidator) save() { - if privVal.filePath == "" { - PanicSanity("Cannot save PrivValidator: filePath not set") - } - jsonBytes := wire.JSONBytes(privVal) - err := WriteFileAtomic(privVal.filePath, jsonBytes, 0600) - if err != nil { - // `@; BOOM!!! - PanicCrisis(err) - } -} - -func (privVal *PrivValidator) SignVote(chainID string, vote *Vote) error { - privVal.mtx.Lock() - defer privVal.mtx.Unlock() - - // If height regression, panic - if privVal.LastHeight > vote.Height { - return errors.New("Height regression in SignVote") - } - // More cases for when the height matches - if privVal.LastHeight == vote.Height { - // If round regression, panic - if privVal.LastRound > vote.Round { - return errors.New("Round regression in SignVote") - } - // If step regression, panic - if privVal.LastRound == vote.Round && privVal.LastStep > voteToStep(vote) { - return errors.New("Step regression in SignVote") - } - } - - // Persist height/round/step - privVal.LastHeight = vote.Height - privVal.LastRound = vote.Round - privVal.LastStep = voteToStep(vote) - privVal.save() - - // Sign - privVal.SignVoteUnsafe(chainID, vote) - return nil -} - -func (privVal *PrivValidator) SignVoteUnsafe(chainID string, vote *Vote) { - vote.Signature = privVal.PrivKey.Sign(SignBytes(chainID, vote)).(crypto.SignatureEd25519) -} - -func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) error { - privVal.mtx.Lock() - defer privVal.mtx.Unlock() - if privVal.LastHeight < proposal.Height || - privVal.LastHeight == proposal.Height && privVal.LastRound < proposal.Round || - privVal.LastHeight == 0 && privVal.LastRound == 0 && privVal.LastStep == stepNone { - - // Persist height/round/step - privVal.LastHeight = proposal.Height - privVal.LastRound = proposal.Round - privVal.LastStep = stepPropose - privVal.save() - - // Sign - proposal.Signature = privVal.PrivKey.Sign(SignBytes(chainID, proposal)).(crypto.SignatureEd25519) - return nil - } else { - return errors.New(fmt.Sprintf("Attempt of duplicate signing of proposal: Height %v, Round %v", proposal.Height, proposal.Round)) - } -} - -func (privVal *PrivValidator) String() string { - return fmt.Sprintf("PrivValidator{%X LH:%v, LR:%v, LS:%v}", privVal.Address, privVal.LastHeight, privVal.LastRound, privVal.LastStep) -} - -//------------------------------------- - -type PrivValidatorsByAddress []*PrivValidator - -func (pvs PrivValidatorsByAddress) Len() int { - return len(pvs) -} - -func (pvs PrivValidatorsByAddress) Less(i, j int) bool { - return bytes.Compare(pvs[i].Address, pvs[j].Address) == -1 -} - -func (pvs PrivValidatorsByAddress) Swap(i, j int) { - it := pvs[i] - pvs[i] = pvs[j] - pvs[j] = it -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go deleted file mode 100644 index e67db26a..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go +++ /dev/null @@ -1,47 +0,0 @@ -package types - -import ( - "errors" - "fmt" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -var ( - ErrInvalidBlockPartSignature = errors.New("Error invalid block part signature") - ErrInvalidBlockPartHash = errors.New("Error invalid block part hash") -) - -type Proposal struct { - Height int `json:"height"` - Round int `json:"round"` - BlockPartsHeader PartSetHeader `json:"block_parts_header"` - POLRound int `json:"pol_round"` // -1 if null. - Signature crypto.SignatureEd25519 `json:"signature"` -} - -// polRound: -1 if no polRound. -func NewProposal(height int, round int, blockPartsHeader PartSetHeader, polRound int) *Proposal { - return &Proposal{ - Height: height, - Round: round, - BlockPartsHeader: blockPartsHeader, - POLRound: polRound, - } -} - -func (p *Proposal) String() string { - return fmt.Sprintf("Proposal{%v/%v %v %v %v}", p.Height, p.Round, - p.BlockPartsHeader, p.POLRound, p.Signature) -} - -func (p *Proposal) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":"%s"`, chainID)), w, n, err) - wire.WriteTo([]byte(`,"proposal":{"block_parts_header":`), w, n, err) - p.BlockPartsHeader.WriteSignBytes(w, n, err) - wire.WriteTo([]byte(Fmt(`,"height":%v,"pol_round":%v`, p.Height, p.POLRound)), w, n, err) - wire.WriteTo([]byte(Fmt(`,"round":%v}}`, p.Round)), w, n, err) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal_test.go deleted file mode 100644 index a0024828..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package types - -import ( - "testing" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" -) - -func TestProposalSignable(t *testing.T) { - proposal := &Proposal{ - Height: 12345, - Round: 23456, - BlockPartsHeader: PartSetHeader{111, []byte("blockparts")}, - POLRound: -1, - } - signBytes := SignBytes(config.GetString("chain_id"), proposal) - signStr := string(signBytes) - - expected := Fmt(`{"chain_id":"%s","proposal":{"block_parts_header":{"hash":"626C6F636B7061727473","total":111},"height":12345,"pol_round":-1,"round":23456}}`, - config.GetString("chain_id")) - if signStr != expected { - t.Errorf("Got unexpected sign string for SendTx. Expected:\n%v\nGot:\n%v", expected, signStr) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go deleted file mode 100644 index 041f3bc4..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go +++ /dev/null @@ -1,30 +0,0 @@ -package types - -import ( - "bytes" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" -) - -// Signable is an interface for all signable things. -// It typically removes signatures before serializing. -type Signable interface { - WriteSignBytes(chainID string, w io.Writer, n *int, err *error) -} - -// SignBytes is a convenience method for getting the bytes to sign of a Signable. -func SignBytes(chainID string, o Signable) []byte { - buf, n, err := new(bytes.Buffer), new(int), new(error) - o.WriteSignBytes(chainID, buf, n, err) - if *err != nil { - PanicCrisis(err) - } - return buf.Bytes() -} - -// HashSignBytes is a convenience method for getting the hash of the bytes of a signable -func HashSignBytes(chainID string, o Signable) []byte { - return merkle.SimpleHashFromBinary(SignBytes(chainID, o)) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/stats.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/stats.go deleted file mode 100644 index 29e00535..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/stats.go +++ /dev/null @@ -1,46 +0,0 @@ -package types - -import ( - "time" -) - -type Stats struct { - Blocks int64 `json:"blocks"` - TotalTime int64 `json:"total_time"` - LastCommitTime time.Time `json:"last_commit_time"` - - MinCommitTime int64 `json:"min_commit_time"` - MaxCommitTime int64 `json:"max_commit_time"` - MeanCommitTime int64 `json:"mean_commit_time"` -} - -func NewStats() *Stats { - return &Stats{ - LastCommitTime: time.Now(), - MinCommitTime: 100000000, - MaxCommitTime: 0, - } -} - -func (s *Stats) Update() { - newCommitTime := time.Now() - since := newCommitTime.Sub(s.LastCommitTime).Nanoseconds() - - var newS Stats - - newS.Blocks += 1 - newS.LastCommitTime = newCommitTime - - // update min and max - if since < s.MinCommitTime { - newS.MinCommitTime = since - } - if since > s.MaxCommitTime { - newS.MaxCommitTime = since - } - - // update total and average - newS.TotalTime += since - newS.MeanCommitTime = int64(float64(newS.TotalTime) / float64(newS.Blocks)) - *s = newS -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx.go deleted file mode 100644 index a3cb9fc0..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx.go +++ /dev/null @@ -1,3 +0,0 @@ -package types - -type Tx []byte diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go deleted file mode 100644 index e7807008..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go +++ /dev/null @@ -1,85 +0,0 @@ -package types - -import ( - "bytes" - "fmt" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// Volatile state for each Validator -// Also persisted with the state, but fields change -// every height|round so they don't go in merkle.Tree -type Validator struct { - Address []byte `json:"address"` - PubKey crypto.PubKeyEd25519 `json:"pub_key"` - LastCommitHeight int `json:"last_commit_height"` - VotingPower int64 `json:"voting_power"` - Accum int64 `json:"accum"` -} - -// Creates a new copy of the validator so we can mutate accum. -// Panics if the validator is nil. -func (v *Validator) Copy() *Validator { - vCopy := *v - return &vCopy -} - -// Returns the one with higher Accum. -func (v *Validator) CompareAccum(other *Validator) *Validator { - if v == nil { - return other - } - if v.Accum > other.Accum { - return v - } else if v.Accum < other.Accum { - return other - } else { - if bytes.Compare(v.Address, other.Address) < 0 { - return v - } else if bytes.Compare(v.Address, other.Address) > 0 { - return other - } else { - PanicSanity("Cannot compare identical validators") - return nil - } - } -} - -func (v *Validator) String() string { - if v == nil { - return "nil-Validator" - } - return fmt.Sprintf("Validator{%X %v %v-%v-%v VP:%v A:%v}", - v.Address, - v.PubKey, - v.LastCommitHeight, - v.VotingPower, - v.Accum) -} - -func (v *Validator) Hash() []byte { - return wire.BinaryRipemd160(v) -} - -//------------------------------------- - -var ValidatorCodec = validatorCodec{} - -type validatorCodec struct{} - -func (vc validatorCodec) Encode(o interface{}, w io.Writer, n *int, err *error) { - wire.WriteBinary(o.(*Validator), w, n, err) -} - -func (vc validatorCodec) Decode(r io.Reader, n *int, err *error) interface{} { - return wire.ReadBinary(&Validator{}, r, 0, n, err) -} - -func (vc validatorCodec) Compare(o1 interface{}, o2 interface{}) int { - PanicSanity("ValidatorCodec.Compare not implemented") - return 0 -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set.go deleted file mode 100644 index d156adc8..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set.go +++ /dev/null @@ -1,311 +0,0 @@ -package types - -import ( - "bytes" - "fmt" - "sort" - "strings" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" -) - -// ValidatorSet represent a set of *Validator at a given height. -// The validators can be fetched by address or index. -// The index is in order of .Address, so the indices are fixed -// for all rounds of a given blockchain height. -// On the other hand, the .AccumPower of each validator and -// the designated .Proposer() of a set changes every round, -// upon calling .IncrementAccum(). -// NOTE: Not goroutine-safe. -// NOTE: All get/set to validators should copy the value for safety. -// TODO: consider validator Accum overflow -// TODO: replace validators []*Validator with github.com/jaekwon/go-ibbs? -type ValidatorSet struct { - Validators []*Validator // NOTE: persisted via reflect, must be exported. - - // cached (unexported) - proposer *Validator - totalVotingPower int64 -} - -func NewValidatorSet(vals []*Validator) *ValidatorSet { - validators := make([]*Validator, len(vals)) - for i, val := range vals { - validators[i] = val.Copy() - } - sort.Sort(ValidatorsByAddress(validators)) - vs := &ValidatorSet{ - Validators: validators, - } - - if vals != nil { - vs.IncrementAccum(1) - } - return vs -} - -// TODO: mind the overflow when times and votingPower shares too large. -func (valSet *ValidatorSet) IncrementAccum(times int) { - // Add VotingPower * times to each validator and order into heap. - validatorsHeap := NewHeap() - for _, val := range valSet.Validators { - val.Accum += int64(val.VotingPower) * int64(times) // TODO: mind overflow - validatorsHeap.Push(val, accumComparable(val.Accum)) - } - - // Decrement the validator with most accum, times times. - for i := 0; i < times; i++ { - mostest := validatorsHeap.Peek().(*Validator) - if i == times-1 { - valSet.proposer = mostest - } - mostest.Accum -= int64(valSet.TotalVotingPower()) - validatorsHeap.Update(mostest, accumComparable(mostest.Accum)) - } -} - -func (valSet *ValidatorSet) Copy() *ValidatorSet { - validators := make([]*Validator, len(valSet.Validators)) - for i, val := range valSet.Validators { - // NOTE: must copy, since IncrementAccum updates in place. - validators[i] = val.Copy() - } - return &ValidatorSet{ - Validators: validators, - proposer: valSet.proposer, - totalVotingPower: valSet.totalVotingPower, - } -} - -func (valSet *ValidatorSet) HasAddress(address []byte) bool { - idx := sort.Search(len(valSet.Validators), func(i int) bool { - return bytes.Compare(address, valSet.Validators[i].Address) <= 0 - }) - return idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0 -} - -func (valSet *ValidatorSet) GetByAddress(address []byte) (index int, val *Validator) { - idx := sort.Search(len(valSet.Validators), func(i int) bool { - return bytes.Compare(address, valSet.Validators[i].Address) <= 0 - }) - if idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0 { - return idx, valSet.Validators[idx].Copy() - } else { - return 0, nil - } -} - -func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) { - val = valSet.Validators[index] - return val.Address, val.Copy() -} - -func (valSet *ValidatorSet) Size() int { - return len(valSet.Validators) -} - -func (valSet *ValidatorSet) TotalVotingPower() int64 { - if valSet.totalVotingPower == 0 { - for _, val := range valSet.Validators { - valSet.totalVotingPower += val.VotingPower - } - } - return valSet.totalVotingPower -} - -func (valSet *ValidatorSet) Proposer() (proposer *Validator) { - if len(valSet.Validators) == 0 { - return nil - } - if valSet.proposer == nil { - for _, val := range valSet.Validators { - valSet.proposer = valSet.proposer.CompareAccum(val) - } - } - return valSet.proposer.Copy() -} - -func (valSet *ValidatorSet) Hash() []byte { - if len(valSet.Validators) == 0 { - return nil - } - hashables := make([]merkle.Hashable, len(valSet.Validators)) - for i, val := range valSet.Validators { - hashables[i] = val - } - return merkle.SimpleHashFromHashables(hashables) -} - -func (valSet *ValidatorSet) Add(val *Validator) (added bool) { - val = val.Copy() - idx := sort.Search(len(valSet.Validators), func(i int) bool { - return bytes.Compare(val.Address, valSet.Validators[i].Address) <= 0 - }) - if idx == len(valSet.Validators) { - valSet.Validators = append(valSet.Validators, val) - // Invalidate cache - valSet.proposer = nil - valSet.totalVotingPower = 0 - return true - } else if bytes.Compare(valSet.Validators[idx].Address, val.Address) == 0 { - return false - } else { - newValidators := make([]*Validator, len(valSet.Validators)+1) - copy(newValidators[:idx], valSet.Validators[:idx]) - newValidators[idx] = val - copy(newValidators[idx+1:], valSet.Validators[idx:]) - valSet.Validators = newValidators - // Invalidate cache - valSet.proposer = nil - valSet.totalVotingPower = 0 - return true - } -} - -func (valSet *ValidatorSet) Update(val *Validator) (updated bool) { - index, sameVal := valSet.GetByAddress(val.Address) - if sameVal == nil { - return false - } else { - valSet.Validators[index] = val.Copy() - // Invalidate cache - valSet.proposer = nil - valSet.totalVotingPower = 0 - return true - } -} - -func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) { - idx := sort.Search(len(valSet.Validators), func(i int) bool { - return bytes.Compare(address, valSet.Validators[i].Address) <= 0 - }) - if idx == len(valSet.Validators) || bytes.Compare(valSet.Validators[idx].Address, address) != 0 { - return nil, false - } else { - removedVal := valSet.Validators[idx] - newValidators := valSet.Validators[:idx] - if idx+1 < len(valSet.Validators) { - newValidators = append(newValidators, valSet.Validators[idx+1:]...) - } - valSet.Validators = newValidators - // Invalidate cache - valSet.proposer = nil - valSet.totalVotingPower = 0 - return removedVal, true - } -} - -func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) { - for i, val := range valSet.Validators { - stop := fn(i, val.Copy()) - if stop { - break - } - } -} - -// Verify that +2/3 of the set had signed the given signBytes -func (valSet *ValidatorSet) VerifyValidation(chainID string, - hash []byte, parts PartSetHeader, height int, v *Validation) error { - if valSet.Size() != len(v.Precommits) { - return fmt.Errorf("Invalid validation -- wrong set size: %v vs %v", valSet.Size(), len(v.Precommits)) - } - if height != v.Height() { - return fmt.Errorf("Invalid validation -- wrong height: %v vs %v", height, v.Height()) - } - - talliedVotingPower := int64(0) - round := v.Round() - - for idx, precommit := range v.Precommits { - // may be nil if validator skipped. - if precommit == nil { - continue - } - if precommit.Height != height { - return fmt.Errorf("Invalid validation -- wrong height: %v vs %v", height, precommit.Height) - } - if precommit.Round != round { - return fmt.Errorf("Invalid validation -- wrong round: %v vs %v", round, precommit.Round) - } - if precommit.Type != VoteTypePrecommit { - return fmt.Errorf("Invalid validation -- not precommit @ index %v", idx) - } - _, val := valSet.GetByIndex(idx) - // Validate signature - precommitSignBytes := SignBytes(chainID, precommit) - if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) { - return fmt.Errorf("Invalid validation -- invalid signature: %v", precommit) - } - if !bytes.Equal(precommit.BlockHash, hash) { - continue // Not an error, but doesn't count - } - if !parts.Equals(precommit.BlockPartsHeader) { - continue // Not an error, but doesn't count - } - // Good precommit! - talliedVotingPower += val.VotingPower - } - - if talliedVotingPower > valSet.TotalVotingPower()*2/3 { - return nil - } else { - return fmt.Errorf("Invalid validation -- insufficient voting power: got %v, needed %v", - talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1)) - } -} - -func (valSet *ValidatorSet) String() string { - return valSet.StringIndented("") -} - -func (valSet *ValidatorSet) StringIndented(indent string) string { - if valSet == nil { - return "nil-ValidatorSet" - } - valStrings := []string{} - valSet.Iterate(func(index int, val *Validator) bool { - valStrings = append(valStrings, val.String()) - return false - }) - return fmt.Sprintf(`ValidatorSet{ -%s Proposer: %v -%s Validators: -%s %v -%s}`, - indent, valSet.Proposer().String(), - indent, - indent, strings.Join(valStrings, "\n"+indent+" "), - indent) - -} - -//------------------------------------- -// Implements sort for sorting validators by address. - -type ValidatorsByAddress []*Validator - -func (vs ValidatorsByAddress) Len() int { - return len(vs) -} - -func (vs ValidatorsByAddress) Less(i, j int) bool { - return bytes.Compare(vs[i].Address, vs[j].Address) == -1 -} - -func (vs ValidatorsByAddress) Swap(i, j int) { - it := vs[i] - vs[i] = vs[j] - vs[j] = it -} - -//------------------------------------- -// Use with Heap for sorting validators by accum - -type accumComparable int64 - -// We want to find the validator with the greatest accum. -func (ac accumComparable) Less(o interface{}) bool { - return int64(ac) > int64(o.(accumComparable)) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set_test.go deleted file mode 100644 index 5064e796..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package types - -import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - - "bytes" - "strings" - "testing" -) - -func randPubKey() crypto.PubKeyEd25519 { - var pubKey [32]byte - copy(pubKey[:], RandBytes(32)) - return crypto.PubKeyEd25519(pubKey) -} - -func randValidator_() *Validator { - return &Validator{ - Address: RandBytes(20), - PubKey: randPubKey(), - VotingPower: RandInt64(), - Accum: RandInt64(), - } -} - -func randValidatorSet(numValidators int) *ValidatorSet { - validators := make([]*Validator, numValidators) - for i := 0; i < numValidators; i++ { - validators[i] = randValidator_() - } - return NewValidatorSet(validators) -} - -func TestCopy(t *testing.T) { - vset := randValidatorSet(10) - vsetHash := vset.Hash() - if len(vsetHash) == 0 { - t.Fatalf("ValidatorSet had unexpected zero hash") - } - - vsetCopy := vset.Copy() - vsetCopyHash := vsetCopy.Hash() - - if !bytes.Equal(vsetHash, vsetCopyHash) { - t.Fatalf("ValidatorSet copy had wrong hash. Orig: %X, Copy: %X", vsetHash, vsetCopyHash) - } -} - -func TestProposerSelection(t *testing.T) { - vset := NewValidatorSet([]*Validator{ - newValidator([]byte("foo"), 1000), - newValidator([]byte("bar"), 300), - newValidator([]byte("baz"), 330), - }) - proposers := []string{} - for i := 0; i < 99; i++ { - val := vset.Proposer() - proposers = append(proposers, string(val.Address)) - vset.IncrementAccum(1) - } - expected := `foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo foo baz bar foo foo foo baz foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo` - if expected != strings.Join(proposers, " ") { - t.Errorf("Expected sequence of proposers was\n%v\nbut got \n%v", expected, strings.Join(proposers, " ")) - } -} - -func newValidator(address []byte, power int64) *Validator { - return &Validator{Address: address, VotingPower: power} -} - -func TestProposerSelection2(t *testing.T) { - addr1 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - addr2 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} - addr3 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2} - - // when all voting power is same, we go in order of addresses - val1, val2, val3 := newValidator(addr1, 100), newValidator(addr2, 100), newValidator(addr3, 100) - valList := []*Validator{val1, val2, val3} - vals := NewValidatorSet(valList) - for i := 0; i < len(valList)*5; i++ { - ii := i % len(valList) - prop := vals.Proposer() - if !bytes.Equal(prop.Address, valList[ii].Address) { - t.Fatalf("Expected %X. Got %X", valList[ii].Address, prop.Address) - } - vals.IncrementAccum(1) - } - - // One validator has more than the others, but not enough to propose twice in a row - *val3 = *newValidator(addr3, 400) - vals = NewValidatorSet(valList) - prop := vals.Proposer() - if !bytes.Equal(prop.Address, addr3) { - t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address) - } - vals.IncrementAccum(1) - prop = vals.Proposer() - if !bytes.Equal(prop.Address, addr1) { - t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address) - } - - // One validator has more than the others, and enough to be proposer twice in a row - *val3 = *newValidator(addr3, 401) - vals = NewValidatorSet(valList) - prop = vals.Proposer() - if !bytes.Equal(prop.Address, addr3) { - t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address) - } - vals.IncrementAccum(1) - prop = vals.Proposer() - if !bytes.Equal(prop.Address, addr3) { - t.Fatalf("Expected address with highest voting power to be second proposer. Got %X", prop.Address) - } - vals.IncrementAccum(1) - prop = vals.Proposer() - if !bytes.Equal(prop.Address, addr1) { - t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address) - } - - // each validator should be the proposer a proportional number of times - val1, val2, val3 = newValidator(addr1, 4), newValidator(addr2, 5), newValidator(addr3, 3) - valList = []*Validator{val1, val2, val3} - propCount := make([]int, 3) - vals = NewValidatorSet(valList) - for i := 0; i < 120; i++ { - prop := vals.Proposer() - ii := prop.Address[19] - propCount[ii] += 1 - vals.IncrementAccum(1) - } - - if propCount[0] != 40 { - t.Fatalf("Expected prop count for validator with 4/12 of voting power to be 40/120. Got %d/120", propCount[0]) - } - if propCount[1] != 50 { - t.Fatalf("Expected prop count for validator with 5/12 of voting power to be 50/120. Got %d/120", propCount[1]) - } - if propCount[2] != 30 { - t.Fatalf("Expected prop count for validator with 3/12 of voting power to be 30/120. Got %d/120", propCount[2]) - } -} - -func BenchmarkValidatorSetCopy(b *testing.B) { - b.StopTimer() - vset := NewValidatorSet([]*Validator{}) - for i := 0; i < 1000; i++ { - privKey := crypto.GenPrivKeyEd25519() - pubKey := privKey.PubKey().(crypto.PubKeyEd25519) - val := &Validator{ - Address: pubKey.Address(), - PubKey: pubKey, - } - if !vset.Add(val) { - panic("Failed to add validator") - } - } - b.StartTimer() - - for i := 0; i < b.N; i++ { - vset.Copy() - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go deleted file mode 100644 index d1ecfe65..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go +++ /dev/null @@ -1,85 +0,0 @@ -package types - -import ( - "errors" - "fmt" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -var ( - ErrVoteUnexpectedStep = errors.New("Unexpected step") - ErrVoteInvalidAccount = errors.New("Invalid round vote account") - ErrVoteInvalidSignature = errors.New("Invalid round vote signature") - ErrVoteInvalidBlockHash = errors.New("Invalid block hash") -) - -type ErrVoteConflictingSignature struct { - VoteA *Vote - VoteB *Vote -} - -func (err *ErrVoteConflictingSignature) Error() string { - return "Conflicting round vote signature" -} - -// Represents a prevote, precommit, or commit vote from validators for consensus. -type Vote struct { - Height int `json:"height"` - Round int `json:"round"` - Type byte `json:"type"` - BlockHash []byte `json:"block_hash"` // empty if vote is nil. - BlockPartsHeader PartSetHeader `json:"block_parts_header"` // zero if vote is nil. - Signature crypto.SignatureEd25519 `json:"signature"` -} - -// Types of votes -const ( - VoteTypePrevote = byte(0x01) - VoteTypePrecommit = byte(0x02) -) - -func (vote *Vote) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":"%s"`, chainID)), w, n, err) - wire.WriteTo([]byte(Fmt(`,"vote":{"block_hash":"%X","block_parts_header":%v`, vote.BlockHash, vote.BlockPartsHeader)), w, n, err) - wire.WriteTo([]byte(Fmt(`,"height":%v,"round":%v,"type":%v}}`, vote.Height, vote.Round, vote.Type)), w, n, err) -} - -func (vote *Vote) Copy() *Vote { - voteCopy := *vote - return &voteCopy -} - -func (vote *Vote) String() string { - if vote == nil { - return "nil-Vote" - } - var typeString string - switch vote.Type { - case VoteTypePrevote: - typeString = "Prevote" - case VoteTypePrecommit: - typeString = "Precommit" - default: - PanicSanity("Unknown vote type") - } - - return fmt.Sprintf("Vote{%v/%02d/%v(%v) %X#%v %v}", vote.Height, vote.Round, vote.Type, typeString, Fingerprint(vote.BlockHash), vote.BlockPartsHeader, vote.Signature) -} - -//-------------------------------------------------------------------------------- -// TODO: Move blocks/Validation to here? - -// Common interface between *consensus.VoteSet and types.Validation -type VoteSetReader interface { - Height() int - Round() int - Type() byte - Size() int - BitArray() *BitArray - GetByIndex(int) *Vote - IsCommit() bool -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set deleted file mode 100644 index e69de29b..00000000 diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set.go deleted file mode 100644 index 55c24b14..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set.go +++ /dev/null @@ -1,323 +0,0 @@ -package types - -import ( - "bytes" - "fmt" - "strings" - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// VoteSet helps collect signatures from validators at each height+round -// for a predefined vote type. -// Note that there three kinds of votes: prevotes, precommits, and commits. -// A commit of prior rounds can be added added in lieu of votes/precommits. -// NOTE: Assumes that the sum total of voting power does not exceed MaxUInt64. -type VoteSet struct { - height int - round int - type_ byte - - mtx sync.Mutex - valSet *ValidatorSet - votes []*Vote // validator index -> vote - votesBitArray *BitArray // validator index -> has vote? - votesByBlock map[string]int64 // string(blockHash)+string(blockParts) -> vote sum. - totalVotes int64 - maj23Hash []byte - maj23PartsHeader PartSetHeader - maj23Exists bool -} - -// Constructs a new VoteSet struct used to accumulate votes for given height/round. -func NewVoteSet(height int, round int, type_ byte, valSet *ValidatorSet) *VoteSet { - if height == 0 { - PanicSanity("Cannot make VoteSet for height == 0, doesn't make sense.") - } - return &VoteSet{ - height: height, - round: round, - type_: type_, - valSet: valSet, - votes: make([]*Vote, valSet.Size()), - votesBitArray: NewBitArray(valSet.Size()), - votesByBlock: make(map[string]int64), - totalVotes: 0, - } -} - -func (voteSet *VoteSet) Height() int { - if voteSet == nil { - return 0 - } else { - return voteSet.height - } -} - -func (voteSet *VoteSet) Round() int { - if voteSet == nil { - return -1 - } else { - return voteSet.round - } -} - -func (voteSet *VoteSet) Type() byte { - if voteSet == nil { - return 0x00 - } else { - return voteSet.type_ - } -} - -func (voteSet *VoteSet) Size() int { - if voteSet == nil { - return 0 - } else { - return voteSet.valSet.Size() - } -} - -// Returns added=true, index if vote was added -// Otherwise returns err=ErrVote[UnexpectedStep|InvalidAccount|InvalidSignature|InvalidBlockHash|ConflictingSignature] -// Duplicate votes return added=false, err=nil. -// NOTE: vote should not be mutated after adding. -func (voteSet *VoteSet) AddByIndex(valIndex int, vote *Vote) (added bool, address []byte, err error) { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - - return voteSet.addByIndex(valIndex, vote) -} - -// Returns added=true, index if vote was added -// Otherwise returns err=ErrVote[UnexpectedStep|InvalidAccount|InvalidSignature|InvalidBlockHash|ConflictingSignature] -// Duplicate votes return added=false, err=nil. -// NOTE: vote should not be mutated after adding. -func (voteSet *VoteSet) AddByAddress(address []byte, vote *Vote) (added bool, index int, err error) { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - - // Ensure that signer is a validator. - valIndex, val := voteSet.valSet.GetByAddress(address) - if val == nil { - return false, 0, ErrVoteInvalidAccount - } - - return voteSet.addVote(val, valIndex, vote) -} - -func (voteSet *VoteSet) addByIndex(valIndex int, vote *Vote) (added bool, address []byte, err error) { - // Ensure that signer is a validator. - address, val := voteSet.valSet.GetByIndex(valIndex) - if val == nil { - return false, nil, ErrVoteInvalidAccount - } - - added, _, err = voteSet.addVote(val, valIndex, vote) - return -} - -func (voteSet *VoteSet) addVote(val *Validator, valIndex int, vote *Vote) (bool, int, error) { - - // Make sure the step matches. (or that vote is commit && round < voteSet.round) - if (vote.Height != voteSet.height) || - (vote.Round != voteSet.round) || - (vote.Type != voteSet.type_) { - return false, 0, ErrVoteUnexpectedStep - } - - // Check signature. - if !val.PubKey.VerifyBytes(SignBytes(config.GetString("chain_id"), vote), vote.Signature) { - // Bad signature. - return false, 0, ErrVoteInvalidSignature - } - - // If vote already exists, return false. - if existingVote := voteSet.votes[valIndex]; existingVote != nil { - if bytes.Equal(existingVote.BlockHash, vote.BlockHash) { - return false, valIndex, nil - } else { - return false, valIndex, &ErrVoteConflictingSignature{ - VoteA: existingVote, - VoteB: vote, - } - } - } - - // Add vote. - voteSet.votes[valIndex] = vote - voteSet.votesBitArray.SetIndex(valIndex, true) - blockKey := string(vote.BlockHash) + string(wire.BinaryBytes(vote.BlockPartsHeader)) - totalBlockHashVotes := voteSet.votesByBlock[blockKey] + val.VotingPower - voteSet.votesByBlock[blockKey] = totalBlockHashVotes - voteSet.totalVotes += val.VotingPower - - // If we just nudged it up to two thirds majority, add it. - if totalBlockHashVotes > voteSet.valSet.TotalVotingPower()*2/3 && - (totalBlockHashVotes-val.VotingPower) <= voteSet.valSet.TotalVotingPower()*2/3 { - voteSet.maj23Hash = vote.BlockHash - voteSet.maj23PartsHeader = vote.BlockPartsHeader - voteSet.maj23Exists = true - } - - return true, valIndex, nil -} - -func (voteSet *VoteSet) BitArray() *BitArray { - if voteSet == nil { - return nil - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return voteSet.votesBitArray.Copy() -} - -func (voteSet *VoteSet) GetByIndex(valIndex int) *Vote { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return voteSet.votes[valIndex] -} - -func (voteSet *VoteSet) GetByAddress(address []byte) *Vote { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - valIndex, val := voteSet.valSet.GetByAddress(address) - if val == nil { - PanicSanity("GetByAddress(address) returned nil") - } - return voteSet.votes[valIndex] -} - -func (voteSet *VoteSet) HasTwoThirdsMajority() bool { - if voteSet == nil { - return false - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return voteSet.maj23Exists -} - -func (voteSet *VoteSet) IsCommit() bool { - if voteSet == nil { - return false - } - if voteSet.type_ != VoteTypePrecommit { - return false - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return len(voteSet.maj23Hash) > 0 -} - -func (voteSet *VoteSet) HasTwoThirdsAny() bool { - if voteSet == nil { - return false - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return voteSet.totalVotes > voteSet.valSet.TotalVotingPower()*2/3 -} - -// Returns either a blockhash (or nil) that received +2/3 majority. -// If there exists no such majority, returns (nil, false). -func (voteSet *VoteSet) TwoThirdsMajority() (hash []byte, parts PartSetHeader, ok bool) { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - if voteSet.maj23Exists { - return voteSet.maj23Hash, voteSet.maj23PartsHeader, true - } else { - return nil, PartSetHeader{}, false - } -} - -func (voteSet *VoteSet) String() string { - if voteSet == nil { - return "nil-VoteSet" - } - return voteSet.StringIndented("") -} - -func (voteSet *VoteSet) StringIndented(indent string) string { - voteStrings := make([]string, len(voteSet.votes)) - for i, vote := range voteSet.votes { - if vote == nil { - voteStrings[i] = "nil-Vote" - } else { - voteStrings[i] = vote.String() - } - } - return fmt.Sprintf(`VoteSet{ -%s H:%v R:%v T:%v -%s %v -%s %v -%s}`, - indent, voteSet.height, voteSet.round, voteSet.type_, - indent, strings.Join(voteStrings, "\n"+indent+" "), - indent, voteSet.votesBitArray, - indent) -} - -func (voteSet *VoteSet) StringShort() string { - if voteSet == nil { - return "nil-VoteSet" - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return fmt.Sprintf(`VoteSet{H:%v R:%v T:%v +2/3:%v %v}`, - voteSet.height, voteSet.round, voteSet.type_, voteSet.maj23Exists, voteSet.votesBitArray) -} - -//-------------------------------------------------------------------------------- -// Validation - -func (voteSet *VoteSet) MakeValidation() *Validation { - if voteSet.type_ != VoteTypePrecommit { - PanicSanity("Cannot MakeValidation() unless VoteSet.Type is VoteTypePrecommit") - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - if len(voteSet.maj23Hash) == 0 { - PanicSanity("Cannot MakeValidation() unless a blockhash has +2/3") - } - precommits := make([]*Vote, voteSet.valSet.Size()) - voteSet.valSet.Iterate(func(valIndex int, val *Validator) bool { - vote := voteSet.votes[valIndex] - if vote == nil { - return false - } - if !bytes.Equal(vote.BlockHash, voteSet.maj23Hash) { - return false - } - if !vote.BlockPartsHeader.Equals(voteSet.maj23PartsHeader) { - return false - } - precommits[valIndex] = vote - return false - }) - return &Validation{ - Precommits: precommits, - } -} - -//-------------------------------------------------------------------------------- -// For testing... - -func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidator) { - privVal := GenPrivValidator() - _, tempFilePath := Tempfile("priv_validator_") - privVal.SetFile(tempFilePath) - votePower := minPower - if randPower { - votePower += int64(RandUint32()) - } - val := &Validator{ - Address: privVal.Address, - PubKey: privVal.PubKey, - LastCommitHeight: 0, - VotingPower: votePower, - Accum: 0, - } - return val, privVal -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set_test.go deleted file mode 100644 index d066b9f1..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set_test.go +++ /dev/null @@ -1,278 +0,0 @@ -package types - -import ( - "bytes" - "sort" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common/test" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - - "testing" -) - -func randVoteSet(height int, round int, type_ byte, numValidators int, votingPower int64) (*VoteSet, *ValidatorSet, []*PrivValidator) { - vals := make([]*Validator, numValidators) - privValidators := make([]*PrivValidator, numValidators) - for i := 0; i < numValidators; i++ { - val, privValidator := RandValidator(false, votingPower) - vals[i] = val - privValidators[i] = privValidator - } - valSet := NewValidatorSet(vals) - sort.Sort(PrivValidatorsByAddress(privValidators)) - return NewVoteSet(height, round, type_, valSet), valSet, privValidators -} - -// Convenience: Return new vote with different height -func withHeight(vote *Vote, height int) *Vote { - vote = vote.Copy() - vote.Height = height - return vote -} - -// Convenience: Return new vote with different round -func withRound(vote *Vote, round int) *Vote { - vote = vote.Copy() - vote.Round = round - return vote -} - -// Convenience: Return new vote with different type -func withType(vote *Vote, type_ byte) *Vote { - vote = vote.Copy() - vote.Type = type_ - return vote -} - -// Convenience: Return new vote with different blockHash -func withBlockHash(vote *Vote, blockHash []byte) *Vote { - vote = vote.Copy() - vote.BlockHash = blockHash - return vote -} - -// Convenience: Return new vote with different blockParts -func withBlockPartsHeader(vote *Vote, blockPartsHeader PartSetHeader) *Vote { - vote = vote.Copy() - vote.BlockPartsHeader = blockPartsHeader - return vote -} - -func signAddVote(privVal *PrivValidator, vote *Vote, voteSet *VoteSet) (bool, error) { - privVal.SignVoteUnsafe(config.GetString("chain_id"), vote) - added, _, err := voteSet.AddByAddress(privVal.Address, vote) - return added, err -} - -func TestAddVote(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) - val0 := privValidators[0] - - // t.Logf(">> %v", voteSet) - - if voteSet.GetByAddress(val0.Address) != nil { - t.Errorf("Expected GetByAddress(val0.Address) to be nil") - } - if voteSet.BitArray().GetIndex(0) { - t.Errorf("Expected BitArray.GetIndex(0) to be false") - } - hash, header, ok := voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } - - vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} - signAddVote(val0, vote, voteSet) - - if voteSet.GetByAddress(val0.Address) == nil { - t.Errorf("Expected GetByAddress(val0.Address) to be present") - } - if !voteSet.BitArray().GetIndex(0) { - t.Errorf("Expected BitArray.GetIndex(0) to be true") - } - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } -} - -func Test2_3Majority(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) - - vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} - - // 6 out of 10 voted for nil. - for i := 0; i < 6; i++ { - signAddVote(privValidators[i], vote, voteSet) - } - hash, header, ok := voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } - - // 7th validator voted for some blockhash - { - signAddVote(privValidators[6], withBlockHash(vote, RandBytes(32)), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } - } - - // 8th validator voted for nil. - { - signAddVote(privValidators[7], vote, voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || !ok { - t.Errorf("There should be 2/3 majority for nil") - } - } -} - -func Test2_3MajorityRedux(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 100, 1) - - blockHash := CRandBytes(32) - blockPartsTotal := 123 - blockPartsHeader := PartSetHeader{blockPartsTotal, CRandBytes(32)} - - vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockPartsHeader: blockPartsHeader} - - // 66 out of 100 voted for nil. - for i := 0; i < 66; i++ { - signAddVote(privValidators[i], vote, voteSet) - } - hash, header, ok := voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } - - // 67th validator voted for nil - { - signAddVote(privValidators[66], withBlockHash(vote, nil), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority: last vote added was nil") - } - } - - // 68th validator voted for a different BlockParts PartSetHeader - { - blockPartsHeader := PartSetHeader{blockPartsTotal, CRandBytes(32)} - signAddVote(privValidators[67], withBlockPartsHeader(vote, blockPartsHeader), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Hash") - } - } - - // 69th validator voted for different BlockParts Total - { - blockPartsHeader := PartSetHeader{blockPartsTotal + 1, blockPartsHeader.Hash} - signAddVote(privValidators[68], withBlockPartsHeader(vote, blockPartsHeader), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Total") - } - } - - // 70th validator voted for different BlockHash - { - signAddVote(privValidators[69], withBlockHash(vote, RandBytes(32)), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority: last vote added had different BlockHash") - } - } - - // 71st validator voted for the right BlockHash & BlockPartsHeader - { - signAddVote(privValidators[70], vote, voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if !bytes.Equal(hash, blockHash) || !header.Equals(blockPartsHeader) || !ok { - t.Errorf("There should be 2/3 majority") - } - } -} - -func TestBadVotes(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) - - // val0 votes for nil. - vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} - added, err := signAddVote(privValidators[0], vote, voteSet) - if !added || err != nil { - t.Errorf("Expected VoteSet.Add to succeed") - } - - // val0 votes again for some block. - added, err = signAddVote(privValidators[0], withBlockHash(vote, RandBytes(32)), voteSet) - if added || err == nil { - t.Errorf("Expected VoteSet.Add to fail, dupeout.") - } - - // val1 votes on another height - added, err = signAddVote(privValidators[1], withHeight(vote, height+1), voteSet) - if added { - t.Errorf("Expected VoteSet.Add to fail, wrong height") - } - - // val2 votes on another round - added, err = signAddVote(privValidators[2], withRound(vote, round+1), voteSet) - if added { - t.Errorf("Expected VoteSet.Add to fail, wrong round") - } - - // val3 votes of another type. - added, err = signAddVote(privValidators[3], withType(vote, VoteTypePrecommit), voteSet) - if added { - t.Errorf("Expected VoteSet.Add to fail, wrong type") - } -} - -func TestMakeValidation(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrecommit, 10, 1) - blockHash, blockPartsHeader := CRandBytes(32), PartSetHeader{123, CRandBytes(32)} - - vote := &Vote{Height: height, Round: round, Type: VoteTypePrecommit, - BlockHash: blockHash, BlockPartsHeader: blockPartsHeader} - - // 6 out of 10 voted for some block. - for i := 0; i < 6; i++ { - signAddVote(privValidators[i], vote, voteSet) - } - - // MakeValidation should fail. - AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeValidation() }) - - // 7th voted for some other block. - { - vote := withBlockHash(vote, RandBytes(32)) - vote = withBlockPartsHeader(vote, PartSetHeader{123, RandBytes(32)}) - signAddVote(privValidators[6], vote, voteSet) - } - - // The 8th voted like everyone else. - { - signAddVote(privValidators[7], vote, voteSet) - } - - validation := voteSet.MakeValidation() - - // Validation should have 10 elements - if len(validation.Precommits) != 10 { - t.Errorf("Validation Precommits should have the same number of precommits as validators") - } - - // Ensure that Validation precommits are ordered. - if err := validation.ValidateBasic(); err != nil { - t.Errorf("Error in Validation.ValidateBasic(): %v", err) - } - -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go index f8478ba6..e5945c81 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go @@ -7,9 +7,9 @@ import ( "net" "strings" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" + "github.com/tendermint/tmsp/types" ) // var maxNumberConnections = 2 diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go index e8756a41..634c89b3 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go @@ -1,6 +1,6 @@ package types -import "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" +import "github.com/tendermint/go-wire" const ( requestTypeEcho = byte(0x01) diff --git a/account/account.go b/account/account.go index 2caea0d2..62e1a820 100644 --- a/account/account.go +++ b/account/account.go @@ -5,10 +5,11 @@ import ( "fmt" "io" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" ptypes "github.com/eris-ltd/eris-db/permission/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-merkle" + "github.com/tendermint/go-wire" ) // Signable is an interface for all signable things. @@ -38,12 +39,12 @@ func HashSignBytes(chainID string, o Signable) []byte { // on the blockchain. // Serialized by wire.[read|write]Reflect type Account struct { - Address []byte `json:"address"` - PubKey PubKey `json:"pub_key"` - Sequence int `json:"sequence"` - Balance int64 `json:"balance"` - Code []byte `json:"code"` // VM code - StorageRoot []byte `json:"storage_root"` // VM storage merkle root. + Address []byte `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` + Sequence int `json:"sequence"` + Balance int64 `json:"balance"` + Code []byte `json:"code"` // VM code + StorageRoot []byte `json:"storage_root"` // VM storage merkle root. Permissions ptypes.AccountPermissions `json:"permissions"` } @@ -72,3 +73,18 @@ var AccountCodec = wire.Codec{ Encode: AccountEncoder, Decode: AccountDecoder, } + +func EncodeAccount(acc *Account) []byte { + w := new(bytes.Buffer) + var n int + var err error + AccountEncoder(acc, w, &n, &err) + return w.Bytes() +} + +func DecodeAccount(accBytes []byte) *Account { + var n int + var err error + acc := AccountDecoder(bytes.NewBuffer(accBytes), &n, &err) + return acc.(*Account) +} diff --git a/account/priv_account.go b/account/priv_account.go index 1def3a2a..4e016a0f 100644 --- a/account/priv_account.go +++ b/account/priv_account.go @@ -1,19 +1,20 @@ package account import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/ed25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" + "github.com/tendermint/go-crypto" ) type PrivAccount struct { - Address []byte `json:"address"` - PubKey PubKey `json:"pub_key"` - PrivKey PrivKey `json:"priv_key"` + Address []byte `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` + PrivKey crypto.PrivKey `json:"priv_key"` } func (pA *PrivAccount) Generate(index int) *PrivAccount { - newPrivKey := pA.PrivKey.(PrivKeyEd25519).Generate(index) + newPrivKey := pA.PrivKey.(crypto.PrivKeyEd25519).Generate(index) newPubKey := newPrivKey.PubKey() newAddress := newPubKey.Address() return &PrivAccount{ @@ -23,7 +24,7 @@ func (pA *PrivAccount) Generate(index int) *PrivAccount { } } -func (pA *PrivAccount) Sign(chainID string, o Signable) Signature { +func (pA *PrivAccount) Sign(chainID string, o Signable) crypto.Signature { return pA.PrivKey.Sign(SignBytes(chainID, o)) } @@ -38,8 +39,8 @@ func GenPrivAccount() *PrivAccount { privKeyBytes := new([64]byte) copy(privKeyBytes[:32], CRandBytes(32)) pubKeyBytes := ed25519.MakePublicKey(privKeyBytes) - pubKey := PubKeyEd25519(*pubKeyBytes) - privKey := PrivKeyEd25519(*privKeyBytes) + pubKey := crypto.PubKeyEd25519(*pubKeyBytes) + privKey := crypto.PrivKeyEd25519(*privKeyBytes) return &PrivAccount{ Address: pubKey.Address(), PubKey: pubKey, @@ -58,8 +59,8 @@ func GenPrivAccountFromSecret(secret string) *PrivAccount { privKeyBytes := new([64]byte) copy(privKeyBytes[:32], privKey32) pubKeyBytes := ed25519.MakePublicKey(privKeyBytes) - pubKey := PubKeyEd25519(*pubKeyBytes) - privKey := PrivKeyEd25519(*privKeyBytes) + pubKey := crypto.PubKeyEd25519(*pubKeyBytes) + privKey := crypto.PrivKeyEd25519(*privKeyBytes) return &PrivAccount{ Address: pubKey.Address(), PubKey: pubKey, @@ -74,8 +75,8 @@ func GenPrivAccountFromPrivKeyBytes(privKeyBytes []byte) *PrivAccount { var privKeyArray [64]byte copy(privKeyArray[:], privKeyBytes) pubKeyBytes := ed25519.MakePublicKey(&privKeyArray) - pubKey := PubKeyEd25519(*pubKeyBytes) - privKey := PrivKeyEd25519(privKeyArray) + pubKey := crypto.PubKeyEd25519(*pubKeyBytes) + privKey := crypto.PrivKeyEd25519(privKeyArray) return &PrivAccount{ Address: pubKey.Address(), PubKey: pubKey, diff --git a/account/priv_key.go b/account/priv_key.go deleted file mode 100644 index b7f1dd9f..00000000 --- a/account/priv_key.go +++ /dev/null @@ -1,70 +0,0 @@ -package account - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// PrivKey is part of PrivAccount and state.PrivValidator. -type PrivKey interface { - Sign(msg []byte) Signature - PubKey() PubKey -} - -// Types of PrivKey implementations -const ( - PrivKeyTypeEd25519 = byte(0x01) -) - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ PrivKey }{}, - wire.ConcreteType{PrivKeyEd25519{}, PrivKeyTypeEd25519}, -) - -//------------------------------------- - -// Implements PrivKey -type PrivKeyEd25519 [64]byte - -func (key PrivKeyEd25519) Sign(msg []byte) Signature { - privKeyBytes := [64]byte(key) - signatureBytes := ed25519.Sign(&privKeyBytes, msg) - return SignatureEd25519(*signatureBytes) -} - -func (privKey PrivKeyEd25519) PubKey() PubKey { - privKeyBytes := [64]byte(privKey) - return PubKeyEd25519(*ed25519.MakePublicKey(&privKeyBytes)) -} - -func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte { - keyCurve25519 := new([32]byte) - privKeyBytes := [64]byte(privKey) - extra25519.PrivateKeyToCurve25519(keyCurve25519, &privKeyBytes) - return keyCurve25519 -} - -func (privKey PrivKeyEd25519) String() string { - return Fmt("PrivKeyEd25519{*****}") -} - -// Deterministically generates new priv-key bytes from key. -func (key PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { - newBytes := wire.BinarySha256(struct { - PrivKey [64]byte - Index int - }{key, index}) - var newKey [64]byte - copy(newKey[:], newBytes) - return PrivKeyEd25519(newKey) -} - -func GenPrivKeyEd25519() PrivKeyEd25519 { - privKeyBytes := new([64]byte) - copy(privKeyBytes[:32], CRandBytes(32)) - ed25519.MakePublicKey(privKeyBytes) - return PrivKeyEd25519(*privKeyBytes) -} diff --git a/account/pub_key.go b/account/pub_key.go deleted file mode 100644 index 9b949a51..00000000 --- a/account/pub_key.go +++ /dev/null @@ -1,90 +0,0 @@ -package account - -import ( - "bytes" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/ripemd160" -) - -// PubKey is part of Account and Validator. -type PubKey interface { - Address() []byte - VerifyBytes(msg []byte, sig Signature) bool -} - -// Types of PubKey implementations -const ( - PubKeyTypeEd25519 = byte(0x01) -) - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ PubKey }{}, - wire.ConcreteType{PubKeyEd25519{}, PubKeyTypeEd25519}, -) - -//------------------------------------- - -// Implements PubKey -type PubKeyEd25519 [32]byte - -// TODO: Slicing the array gives us length prefixing but loses the type byte. -// Revisit if we add more pubkey types. -// For now, we artificially append the type byte in front to give us backwards -// compatibility for when the pubkey wasn't fixed length array -func (pubKey PubKeyEd25519) Address() []byte { - w, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(pubKey[:], w, n, err) - if *err != nil { - PanicCrisis(*err) - } - // append type byte - encodedPubkey := append([]byte{1}, w.Bytes()...) - hasher := ripemd160.New() - hasher.Write(encodedPubkey) // does not error - return hasher.Sum(nil) -} - -// TODO: Consider returning a reason for failure, or logging a runtime type mismatch. -func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { - sig, ok := sig_.(SignatureEd25519) - if !ok { - return false - } - pubKeyBytes := [32]byte(pubKey) - sigBytes := [64]byte(sig) - return ed25519.Verify(&pubKeyBytes, msg, &sigBytes) -} - -// For use with golang/crypto/nacl/box -// If error, returns nil. -func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte { - keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey) - ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes) - if !ok { - return nil - } - return keyCurve25519 -} - -func (pubKey PubKeyEd25519) String() string { - return Fmt("PubKeyEd25519{%X}", pubKey[:]) -} - -// Must return the full bytes in hex. -// Used for map keying, etc. -func (pubKey PubKeyEd25519) KeyString() string { - return Fmt("%X", pubKey[:]) -} - -func (pubKey PubKeyEd25519) Equals(other PubKey) bool { - if otherEd, ok := other.(PubKeyEd25519); ok { - return bytes.Equal(pubKey[:], otherEd[:]) - } else { - return false - } -} diff --git a/account/signature.go b/account/signature.go deleted file mode 100644 index 2b829324..00000000 --- a/account/signature.go +++ /dev/null @@ -1,34 +0,0 @@ -package account - -import ( - "fmt" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// Signature is a part of Txs and consensus Votes. -type Signature interface { - IsZero() bool - String() string -} - -// Types of Signature implementations -const ( - SignatureTypeEd25519 = byte(0x01) -) - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ Signature }{}, - wire.ConcreteType{SignatureEd25519{}, SignatureTypeEd25519}, -) - -//------------------------------------- - -// Implements Signature -type SignatureEd25519 [64]byte - -func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } - -func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } diff --git a/account/signature_test.go b/account/signature_test.go deleted file mode 100644 index 0e278935..00000000 --- a/account/signature_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package account - -import ( - "bytes" - "testing" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -func TestSignAndValidate(t *testing.T) { - - privAccount := GenPrivAccount() - pubKey := privAccount.PubKey - privKey := privAccount.PrivKey - - msg := CRandBytes(128) - sig := privKey.Sign(msg) - t.Logf("msg: %X, sig: %X", msg, sig) - - // Test the signature - if !pubKey.VerifyBytes(msg, sig) { - t.Errorf("Account message signature verification failed") - } - - // Mutate the signature, just one bit. - sigEd := sig.(SignatureEd25519) - sigEd[0] ^= byte(0x01) - sig = Signature(sigEd) - - if pubKey.VerifyBytes(msg, sig) { - t.Errorf("Account message signature verification should have failed but passed instead") - } -} - -func TestBinaryDecode(t *testing.T) { - - privAccount := GenPrivAccount() - pubKey := privAccount.PubKey - privKey := privAccount.PrivKey - - msg := CRandBytes(128) - sig := privKey.Sign(msg) - t.Logf("msg: %X, sig: %X", msg, sig) - - buf, n, err := new(bytes.Buffer), new(int64), new(error) - wire.WriteBinary(sig, buf, n, err) - if *err != nil { - t.Fatalf("Failed to write Signature: %v", err) - } - - if len(buf.Bytes()) != ed25519.SignatureSize+1 { - // 1 byte TypeByte, 64 bytes signature bytes - t.Fatalf("Unexpected signature write size: %v", len(buf.Bytes())) - } - if buf.Bytes()[0] != SignatureTypeEd25519 { - t.Fatalf("Unexpected signature type byte") - } - - sig2, ok := wire.ReadBinary(SignatureEd25519{}, buf, n, err).(SignatureEd25519) - if !ok || *err != nil { - t.Fatalf("Failed to read Signature: %v", err) - } - - // Test the signature - if !pubKey.VerifyBytes(msg, sig2) { - t.Errorf("Account message signature verification failed") - } -} diff --git a/erisdb/codec.go b/erisdb/codec.go index 84d29761..0039c675 100644 --- a/erisdb/codec.go +++ b/erisdb/codec.go @@ -1,7 +1,7 @@ package erisdb import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/go-wire" rpc "github.com/eris-ltd/eris-db/rpc" "io" "io/ioutil" diff --git a/erisdb/config.go b/erisdb/config.go index 1c038cd6..7873d89d 100644 --- a/erisdb/config.go +++ b/erisdb/config.go @@ -1,7 +1,7 @@ package erisdb import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" + cfg "github.com/tendermint/go-config" ) var config cfg.Config diff --git a/erisdb/erisdbss/http.go b/erisdb/erisdbss/http.go index c98a45a6..7349b35f 100644 --- a/erisdb/erisdbss/http.go +++ b/erisdb/erisdbss/http.go @@ -4,9 +4,9 @@ import ( "bytes" "encoding/json" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/server" stypes "github.com/eris-ltd/eris-db/state/types" "net/http" diff --git a/erisdb/erisdbss/log.go b/erisdb/erisdbss/log.go index 37760e9c..71921642 100644 --- a/erisdb/erisdbss/log.go +++ b/erisdb/erisdbss/log.go @@ -1,7 +1,7 @@ package erisdbss import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" ) var log = log15.New("module", "eris/serverserver") diff --git a/erisdb/erisdbss/server_manager.go b/erisdb/erisdbss/server_manager.go index 6c96ac67..42f5449f 100644 --- a/erisdb/erisdbss/server_manager.go +++ b/erisdb/erisdbss/server_manager.go @@ -3,8 +3,8 @@ package erisdbss import ( "bufio" "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" "github.com/eris-ltd/eris-db/files" "github.com/eris-ltd/eris-db/server" "os" diff --git a/erisdb/event_cache.go b/erisdb/event_cache.go index 81d4bca5..a28752d0 100644 --- a/erisdb/event_cache.go +++ b/erisdb/event_cache.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/go-events" ) var ( @@ -92,7 +92,7 @@ func (this *EventSubscriptions) add(eventId string) (string, error) { } cache := newEventCache() _, errC := this.eventEmitter.Subscribe(subId, eventId, - func(evt types.EventData) { + func(evt events.EventData) { cache.mtx.Lock() defer cache.mtx.Unlock() cache.events = append(cache.events, evt) diff --git a/erisdb/event_cache_test.go b/erisdb/event_cache_test.go index 83410eae..e2348844 100644 --- a/erisdb/event_cache_test.go +++ b/erisdb/event_cache_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/types" ) var mockInterval = 10 * time.Millisecond @@ -16,13 +16,13 @@ var mockInterval = 10 * time.Millisecond type mockSub struct { subId string eventId string - f func(types.EventData) + f func(events.EventData) shutdown bool sdChan chan struct{} } // A mock event -func newMockSub(subId, eventId string, f func(types.EventData)) mockSub { +func newMockSub(subId, eventId string, f func(events.EventData)) mockSub { return mockSub{subId, eventId, f, false, make(chan struct{})} } @@ -34,7 +34,7 @@ func newMockEventEmitter() *mockEventEmitter { return &mockEventEmitter{make(map[string]mockSub)} } -func (this *mockEventEmitter) Subscribe(subId, eventId string, callback func(types.EventData)) (bool, error) { +func (this *mockEventEmitter) Subscribe(subId, eventId string, callback func(events.EventData)) (bool, error) { if _, ok := this.subs[subId]; ok { return false, nil } @@ -47,7 +47,7 @@ func (this *mockEventEmitter) Subscribe(subId, eventId string, callback func(typ go func() { for { if !me.shutdown { - me.f(types.EventDataNewBlock{}) + me.f(events.EventDataNewBlock{}) } else { return } diff --git a/erisdb/pipe/accounts.go b/erisdb/pipe/accounts.go index 01b5bded..c7ca7857 100644 --- a/erisdb/pipe/accounts.go +++ b/erisdb/pipe/accounts.go @@ -6,8 +6,8 @@ import ( "fmt" "sync" - cmn "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" acm "github.com/eris-ltd/eris-db/account" + cmn "github.com/tendermint/go-common" "github.com/eris-ltd/eris-db/tmsp" ) @@ -61,8 +61,8 @@ func (this *accounts) Accounts(fda []*FilterData) (*AccountList, error) { if err != nil { return nil, fmt.Errorf("Error in query: " + err.Error()) } - state.GetAccounts().Iterate(func(key interface{}, value interface{}) bool { - acc := value.(*acm.Account) + state.GetAccounts().Iterate(func(key, value []byte) bool { + acc := acm.DecodeAccount(value) if filter.Match(acc) { accounts = append(accounts, acc) } @@ -93,11 +93,11 @@ func (this *accounts) StorageAt(address, key []byte) (*StorageItem, error) { storageRoot := account.StorageRoot storageTree := state.LoadStorage(storageRoot) - _, value := storageTree.Get(cmn.LeftPadWord256(key).Bytes()) + _, value, _ := storageTree.Get(cmn.LeftPadWord256(key).Bytes()) if value == nil { return &StorageItem{key, []byte{}}, nil } - return &StorageItem{key, value.([]byte)}, nil + return &StorageItem{key, value}, nil } // Get the storage of the account with address 'address'. @@ -112,9 +112,9 @@ func (this *accounts) Storage(address []byte) (*Storage, error) { storageRoot := account.StorageRoot storageTree := state.LoadStorage(storageRoot) - storageTree.Iterate(func(key interface{}, value interface{}) bool { + storageTree.Iterate(func(key, value []byte) bool { storageItems = append(storageItems, StorageItem{ - key.([]byte), value.([]byte)}) + key, value}) return false }) return &Storage{storageRoot, storageItems}, nil diff --git a/erisdb/pipe/blockchain.go b/erisdb/pipe/blockchain.go index e2543282..d2bca86d 100644 --- a/erisdb/pipe/blockchain.go +++ b/erisdb/pipe/blockchain.go @@ -2,8 +2,8 @@ package pipe import ( "fmt" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/state" "math" "strconv" diff --git a/erisdb/pipe/config.go b/erisdb/pipe/config.go index 24e78b5c..43f8f604 100644 --- a/erisdb/pipe/config.go +++ b/erisdb/pipe/config.go @@ -1,8 +1,8 @@ package pipe import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + cfg "github.com/tendermint/go-config" + "github.com/tendermint/log15" ) var log = log15.New("module", "eris/erisdb_pipe") diff --git a/erisdb/pipe/consensus.go b/erisdb/pipe/consensus.go index 69f1a7a5..0e28643e 100644 --- a/erisdb/pipe/consensus.go +++ b/erisdb/pipe/consensus.go @@ -1,7 +1,7 @@ package pipe import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/tmsp" ) diff --git a/erisdb/pipe/events.go b/erisdb/pipe/events.go index f2d15bdb..becd9205 100644 --- a/erisdb/pipe/events.go +++ b/erisdb/pipe/events.go @@ -1,8 +1,7 @@ package pipe import ( - evts "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + evts "github.com/tendermint/go-events" ) // TODO improve @@ -17,7 +16,7 @@ func newEvents(eventSwitch *evts.EventSwitch) *events { } // Subscribe to an event. -func (this *events) Subscribe(subId, event string, callback func(types.EventData)) (bool, error) { +func (this *events) Subscribe(subId, event string, callback func(evts.EventData)) (bool, error) { this.eventSwitch.AddListenerForEvent(subId, event, callback) return true, nil } diff --git a/erisdb/pipe/namereg.go b/erisdb/pipe/namereg.go index f9a42a77..ac15350d 100644 --- a/erisdb/pipe/namereg.go +++ b/erisdb/pipe/namereg.go @@ -6,6 +6,7 @@ import ( "fmt" "sync" + sm "github.com/eris-ltd/eris-db/state" "github.com/eris-ltd/eris-db/tmsp" "github.com/eris-ltd/eris-db/txs" ) @@ -65,8 +66,8 @@ func (this *namereg) Entries(filters []*FilterData) (*ResultListNames, error) { if err != nil { return nil, fmt.Errorf("Error in query: " + err.Error()) } - state.GetNames().Iterate(func(key interface{}, value interface{}) bool { - nre := value.(*types.NameRegEntry) + state.GetNames().Iterate(func(key, value []byte) bool { + nre := sm.DecodeNameRegEntry(value) if filter.Match(nre) { names = append(names, nre) } diff --git a/erisdb/pipe/pipe.go b/erisdb/pipe/pipe.go index 043ba67f..2e43fa5b 100644 --- a/erisdb/pipe/pipe.go +++ b/erisdb/pipe/pipe.go @@ -2,9 +2,9 @@ package pipe import ( - em "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" + em "github.com/tendermint/go-events" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/tmsp" txs "github.com/eris-ltd/eris-db/txs" @@ -48,7 +48,7 @@ type ( } EventEmitter interface { - Subscribe(subId, event string, callback func(types.EventData)) (bool, error) + Subscribe(subId, event string, callback func(em.EventData)) (bool, error) Unsubscribe(subId string) (bool, error) } diff --git a/erisdb/pipe/transactor.go b/erisdb/pipe/transactor.go index 07031a7b..31779df3 100644 --- a/erisdb/pipe/transactor.go +++ b/erisdb/pipe/transactor.go @@ -12,9 +12,9 @@ import ( "github.com/eris-ltd/eris-db/state" "github.com/eris-ltd/eris-db/txs" - cmn "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - tEvents "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - mintTypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + cmn "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + tEvents "github.com/tendermint/go-events" "github.com/eris-ltd/eris-db/tmsp" ) @@ -184,7 +184,7 @@ func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, } wc := make(chan *types.EventDataCall) subId := fmt.Sprintf("%X", rec.TxHash) - this.eventEmitter.Subscribe(subId, types.EventStringAccCall(addr), func(evt mintTypes.EventData) { + this.eventEmitter.Subscribe(subId, types.EventStringAccCall(addr), func(evt tEvents.EventData) { event := evt.(types.EventDataCall) if bytes.Equal(event.TxID, rec.TxHash) { wc <- &event @@ -268,7 +268,7 @@ func (this *transactor) SignTx(tx types.Tx, privAccounts []*account.PrivAccount) bondTx := tx.(*types.BondTx) // the first privaccount corresponds to the BondTx pub key. // the rest to the inputs - bondTx.Signature = privAccounts[0].Sign(chainId, bondTx).(account.SignatureEd25519) + bondTx.Signature = privAccounts[0].Sign(chainId, bondTx).(crypto.SignatureEd25519) for i, input := range bondTx.Inputs { input.PubKey = privAccounts[i+1].PubKey input.Signature = privAccounts[i+1].Sign(chainId, bondTx) @@ -276,11 +276,11 @@ func (this *transactor) SignTx(tx types.Tx, privAccounts []*account.PrivAccount) break case *types.UnbondTx: unbondTx := tx.(*types.UnbondTx) - unbondTx.Signature = privAccounts[0].Sign(chainId, unbondTx).(account.SignatureEd25519) + unbondTx.Signature = privAccounts[0].Sign(chainId, unbondTx).(crypto.SignatureEd25519) break case *types.RebondTx: rebondTx := tx.(*types.RebondTx) - rebondTx.Signature = privAccounts[0].Sign(chainId, rebondTx).(account.SignatureEd25519) + rebondTx.Signature = privAccounts[0].Sign(chainId, rebondTx).(crypto.SignatureEd25519) break default: return nil, fmt.Errorf("Object is not a proper transaction: %v\n", tx) diff --git a/erisdb/pipe/types.go b/erisdb/pipe/types.go index 5e1b784f..8f7f2470 100644 --- a/erisdb/pipe/types.go +++ b/erisdb/pipe/types.go @@ -1,9 +1,9 @@ package pipe import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" // NodeInfo (drop this!) - csus "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/go-p2p" // NodeInfo (drop this!) + csus "github.com/tendermint/tendermint/consensus" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" ) diff --git a/erisdb/serve.go b/erisdb/serve.go index d74e70cd..5ca98370 100644 --- a/erisdb/serve.go +++ b/erisdb/serve.go @@ -6,23 +6,23 @@ import ( "bytes" "path" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" - tmcfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/node" sm "github.com/eris-ltd/eris-db/state" stypes "github.com/eris-ltd/eris-db/state/types" + . "github.com/tendermint/go-common" + cfg "github.com/tendermint/go-config" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-events" + "github.com/tendermint/go-p2p" + "github.com/tendermint/go-wire" + "github.com/tendermint/log15" + tmcfg "github.com/tendermint/tendermint/config/tendermint" + "github.com/tendermint/tendermint/node" ep "github.com/eris-ltd/eris-db/erisdb/pipe" "github.com/eris-ltd/eris-db/server" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/server" edbapp "github.com/eris-ltd/eris-db/tmsp" + tmsp "github.com/tendermint/tmsp/server" ) const ERISDB_VERSION = "0.11.5" @@ -143,11 +143,13 @@ func startNode(nd *node.Node, ready chan struct{}, shutDown <-chan struct{}) { nd.Start() - // If seedNode is provided by config, dial out. + /* + // If seedNode is provided by config, dial out. + // should be handled by core - if len(tmConfig.GetString("seeds")) > 0 { - nd.DialSeed() - } + if len(tmConfig.GetString("seeds")) > 0 { + nd.DialSeed() + }*/ if len(tmConfig.GetString("rpc_laddr")) > 0 { nd.StartRPC() diff --git a/erisdb/wsService.go b/erisdb/wsService.go index f146a50e..6c6dfd86 100644 --- a/erisdb/wsService.go +++ b/erisdb/wsService.go @@ -7,7 +7,7 @@ import ( rpc "github.com/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/server" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/go-events" ) // Used for ErisDb. Implements WebSocketService. @@ -103,7 +103,7 @@ func (this *ErisDbWsService) EventSubscribe(request *rpc.RPCRequest, requester i if errSID != nil { return nil, rpc.INTERNAL_ERROR, errSID } - callback := func(ret types.EventData) { + callback := func(ret events.EventData) { this.writeResponse(subId, ret, session) } _, errC := this.pipe.Events().Subscribe(subId, eventId, callback) diff --git a/evm/log.go b/evm/log.go index e0861876..82880ae9 100644 --- a/evm/log.go +++ b/evm/log.go @@ -1,7 +1,7 @@ package vm import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "vm") diff --git a/evm/native.go b/evm/native.go index 6dbc7763..5082e061 100644 --- a/evm/native.go +++ b/evm/native.go @@ -3,7 +3,7 @@ package vm import ( "crypto/sha256" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) var registeredNativeContracts = make(map[Word256]NativeContract) diff --git a/evm/snative.go b/evm/snative.go index 209dcd5e..9c50cd4e 100644 --- a/evm/snative.go +++ b/evm/snative.go @@ -3,7 +3,7 @@ package vm import ( "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/evm/stack.go b/evm/stack.go index 287b34ab..979aba2e 100644 --- a/evm/stack.go +++ b/evm/stack.go @@ -2,7 +2,7 @@ package vm import ( "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) // Not goroutine safe diff --git a/evm/test/fake_app_state.go b/evm/test/fake_app_state.go index 952c02b6..9204218f 100644 --- a/evm/test/fake_app_state.go +++ b/evm/test/fake_app_state.go @@ -1,7 +1,7 @@ package vm import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" . "github.com/eris-ltd/eris-db/evm" "github.com/eris-ltd/eris-db/evm/sha3" ) diff --git a/evm/test/log_event_test.go b/evm/test/log_event_test.go index a120d349..6df305af 100644 --- a/evm/test/log_event_test.go +++ b/evm/test/log_event_test.go @@ -5,9 +5,9 @@ import ( "reflect" "testing" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-events" + "github.com/tendermint/tendermint/types" . "github.com/eris-ltd/eris-db/evm" ) diff --git a/evm/test/vm_test.go b/evm/test/vm_test.go index 6753fe8e..f061aa6e 100644 --- a/evm/test/vm_test.go +++ b/evm/test/vm_test.go @@ -8,9 +8,9 @@ import ( "testing" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-events" + "github.com/tendermint/tendermint/types" . "github.com/eris-ltd/eris-db/evm" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/evm/types.go b/evm/types.go index f13cd730..5588d996 100644 --- a/evm/types.go +++ b/evm/types.go @@ -1,7 +1,7 @@ package vm import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/evm/vm.go b/evm/vm.go index d93395da..af947fbc 100644 --- a/evm/vm.go +++ b/evm/vm.go @@ -6,11 +6,11 @@ import ( "fmt" "math/big" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" "github.com/eris-ltd/eris-db/evm/sha3" ptypes "github.com/eris-ltd/eris-db/permission/types" types "github.com/eris-ltd/eris-db/txs" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-events" ) var ( diff --git a/files/log.go b/files/log.go index 9067bf13..a18f6b6a 100644 --- a/files/log.go +++ b/files/log.go @@ -1,7 +1,7 @@ package files import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" ) var log = log15.New("module", "eris/server/files") diff --git a/permission/types/permissions.go b/permission/types/permissions.go index 13c32964..3c43ed17 100644 --- a/permission/types/permissions.go +++ b/permission/types/permissions.go @@ -2,7 +2,7 @@ package types import ( "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) //------------------------------------------------------------------------------------------------ diff --git a/permission/types/snatives.go b/permission/types/snatives.go index 94e602b7..57315ac9 100644 --- a/permission/types/snatives.go +++ b/permission/types/snatives.go @@ -1,7 +1,7 @@ package types import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/go-wire" ) //--------------------------------------------------------------------------------------------------- diff --git a/server/log.go b/server/log.go index 09e6fbda..aacad33d 100644 --- a/server/log.go +++ b/server/log.go @@ -1,7 +1,7 @@ package server import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" ) var log = log15.New("module", "eris/server") diff --git a/server/logging.go b/server/logging.go index 8b1ba444..a5a70031 100644 --- a/server/logging.go +++ b/server/logging.go @@ -2,7 +2,7 @@ package server import ( "fmt" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" "os" ) diff --git a/state/block_cache.go b/state/block_cache.go index a53675bd..a0d282ed 100644 --- a/state/block_cache.go +++ b/state/block_cache.go @@ -4,22 +4,16 @@ import ( "bytes" "sort" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-merkle" acm "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/txs" ) func makeStorage(db dbm.DB, root []byte) merkle.Tree { - storage := merkle.NewIAVLTree( - wire.BasicCodec, - wire.BasicCodec, - 1024, - db, - ) + storage := merkle.NewIAVLTree(1024, db) storage.Load(root) return storage } @@ -104,10 +98,10 @@ func (cache *BlockCache) GetStorage(addr Word256, key Word256) (value Word256) { } // Load and set cache - _, val_ := storage.Get(key.Bytes()) + _, val_, _ := storage.Get(key.Bytes()) value = Zero256 if val_ != nil { - value = LeftPadWord256(val_.([]byte)) + value = LeftPadWord256(val_) } cache.storages[Tuple256{addr, key}] = storageInfo{value, false} return value diff --git a/state/common.go b/state/common.go index 4e65bf06..1f572a21 100644 --- a/state/common.go +++ b/state/common.go @@ -1,7 +1,7 @@ package state import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" acm "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/evm" ) diff --git a/state/execution.go b/state/execution.go index 295cc1ae..bb635d0c 100644 --- a/state/execution.go +++ b/state/execution.go @@ -5,8 +5,8 @@ import ( "errors" "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-events" acm "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/evm" diff --git a/state/genesis_test.go b/state/genesis_test.go index 4f1c03d0..e47f98f8 100644 --- a/state/genesis_test.go +++ b/state/genesis_test.go @@ -6,7 +6,7 @@ import ( "fmt" "testing" - tdb "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" + tdb "github.com/tendermint/go-db" ptypes "github.com/eris-ltd/eris-db/permission/types" . "github.com/eris-ltd/eris-db/state/types" ) diff --git a/state/log.go b/state/log.go index 316471ea..5b102b57 100644 --- a/state/log.go +++ b/state/log.go @@ -1,7 +1,7 @@ package state import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "state") diff --git a/state/permissions_test.go b/state/permissions_test.go index 12ab10a4..9f3e8270 100644 --- a/state/permissions_test.go +++ b/state/permissions_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + . "github.com/tendermint/go-common" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-events" + "github.com/tendermint/tendermint/types" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" . "github.com/eris-ltd/eris-db/state/types" diff --git a/state/state.go b/state/state.go index da2dc1e2..626c6aaf 100644 --- a/state/state.go +++ b/state/state.go @@ -11,13 +11,13 @@ import ( . "github.com/eris-ltd/eris-db/state/types" txs "github.com/eris-ltd/eris-db/txs" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-events" + "github.com/tendermint/go-merkle" + "github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/types" ) var ( @@ -65,13 +65,13 @@ func LoadState(db dbm.DB) *State { s.LastBondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, maxLoadStateElementSize, n, err).(*types.ValidatorSet) s.UnbondingValidators = wire.ReadBinary(&types.ValidatorSet{}, r, maxLoadStateElementSize, n, err).(*types.ValidatorSet) accountsHash := wire.ReadByteSlice(r, maxLoadStateElementSize, n, err) - s.accounts = merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) + s.accounts = merkle.NewIAVLTree(defaultAccountsCacheCapacity, db) s.accounts.Load(accountsHash) //validatorInfosHash := wire.ReadByteSlice(r, maxLoadStateElementSize, n, err) //s.validatorInfos = merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, db) //s.validatorInfos.Load(validatorInfosHash) nameRegHash := wire.ReadByteSlice(r, maxLoadStateElementSize, n, err) - s.nameReg = merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) + s.nameReg = merkle.NewIAVLTree(0, db) s.nameReg.Load(nameRegHash) if *err != nil { // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED @@ -167,22 +167,20 @@ func (s *State) GetGasLimit() int64 { // State.accounts // Returns nil if account does not exist with given address. -// The returned Account is a copy, so mutating it -// has no side effects. // Implements Statelike func (s *State) GetAccount(address []byte) *acm.Account { - _, acc := s.accounts.Get(address) - if acc == nil { + _, accBytes, _ := s.accounts.Get(address) + if accBytes == nil { return nil } - return acc.(*acm.Account).Copy() + return acm.DecodeAccount(accBytes) } // The account is copied before setting, so mutating it // afterwards has no side effects. // Implements Statelike func (s *State) UpdateAccount(account *acm.Account) bool { - return s.accounts.Set(account.Address, account) + return s.accounts.Set(account.Address, acm.EncodeAccount(account)) } // Implements Statelike @@ -316,7 +314,7 @@ func (s *State) SetValidatorInfos(validatorInfos merkle.Tree) { // State.storage func (s *State) LoadStorage(hash []byte) (storage merkle.Tree) { - storage = merkle.NewIAVLTree(wire.BasicCodec, wire.BasicCodec, 1024, s.DB) + storage = merkle.NewIAVLTree(1024, s.DB) storage.Load(hash) return storage } @@ -326,20 +324,31 @@ func (s *State) LoadStorage(hash []byte) (storage merkle.Tree) { // State.nameReg func (s *State) GetNameRegEntry(name string) *txs.NameRegEntry { - _, value := s.nameReg.Get(name) - if value == nil { + _, valueBytes, _ := s.nameReg.Get([]byte(name)) + if valueBytes == nil { return nil } - return value.(*txs.NameRegEntry).Copy() + return DecodeNameRegEntry(valueBytes) +} + +func DecodeNameRegEntry(entryBytes []byte) *txs.NameRegEntry { + var n int + var err error + value := NameRegCodec.Decode(bytes.NewBuffer(entryBytes), &n, &err) + return value.(*txs.NameRegEntry) } func (s *State) UpdateNameRegEntry(entry *txs.NameRegEntry) bool { - return s.nameReg.Set(entry.Name, entry) + w := new(bytes.Buffer) + var n int + var err error + NameRegCodec.Encode(entry, w, &n, &err) + return s.nameReg.Set([]byte(entry.Name), w.Bytes()) } func (s *State) RemoveNameRegEntry(name string) bool { - _, removed := s.nameReg.Remove(name) + _, removed := s.nameReg.Remove([]byte(name)) return removed } @@ -395,7 +404,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { } // Make accounts state tree - accounts := merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) + accounts := merkle.NewIAVLTree(defaultAccountsCacheCapacity, db) for _, genAcc := range genDoc.Accounts { perm := ptypes.ZeroAccountPermissions if genAcc.Permissions != nil { @@ -408,7 +417,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { Balance: genAcc.Amount, Permissions: perm, } - accounts.Set(acc.Address, acc) + accounts.Set(acc.Address, acm.EncodeAccount(acc)) } // global permissions are saved as the 0 address @@ -428,7 +437,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { Balance: 1337, Permissions: globalPerms, } - accounts.Set(permsAcc.Address, permsAcc) + accounts.Set(permsAcc.Address, acm.EncodeAccount(permsAcc)) // Make validatorInfos state tree && validators slice /* @@ -464,7 +473,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { */ // Make namereg tree - nameReg := merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) + nameReg := merkle.NewIAVLTree(0, db) // TODO: add names, contracts to genesis.json // IAVLTrees must be persisted before copy operations. diff --git a/state/state_test.go b/state/state_test.go index 596b1782..9c917e78 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + _ "github.com/tendermint/tendermint/config/tendermint_test" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" ) diff --git a/state/test.go b/state/test.go index 32a070bd..3e290fb9 100644 --- a/state/test.go +++ b/state/test.go @@ -4,12 +4,13 @@ import ( "sort" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" . "github.com/eris-ltd/eris-db/state/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/tendermint/types" ) func RandAccount(randBalance bool, minBalance int64) (*acm.Account, *acm.PrivAccount) { @@ -46,7 +47,7 @@ func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numVali for i := 0; i < numValidators; i++ { val, privVal := types.RandValidator(randBonded, minBonded) validators[i] = GenesisValidator{ - PubKey: val.PubKey, + PubKey: val.PubKey.(crypto.PubKeyEd25519), Amount: val.VotingPower, UnbondTo: []BasicAccount{ { diff --git a/state/tx_cache.go b/state/tx_cache.go index 06e55bf1..0bc4a801 100644 --- a/state/tx_cache.go +++ b/state/tx_cache.go @@ -6,7 +6,8 @@ import ( ptypes "github.com/eris-ltd/eris-db/permission/types" // for GlobalPermissionAddress ... "github.com/eris-ltd/eris-db/txs" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" ) type TxCache struct { @@ -161,7 +162,7 @@ func toVMAccount(acc *acm.Account) *vm.Account { // Converts vm.Account to backend.Account struct. func toStateAccount(acc *vm.Account) *acm.Account { - var pubKey acm.PubKey + var pubKey crypto.PubKey var storageRoot []byte if acc.Other != nil { pubKey, storageRoot = acc.Other.(vmAccountOther).unpack() @@ -181,11 +182,11 @@ func toStateAccount(acc *vm.Account) *acm.Account { // Everything in acmAccount that doesn't belong in // exported vmAccount fields. type vmAccountOther struct { - PubKey acm.PubKey + PubKey crypto.PubKey StorageRoot []byte } -func (accOther vmAccountOther) unpack() (acm.PubKey, []byte) { +func (accOther vmAccountOther) unpack() (crypto.PubKey, []byte) { return accOther.PubKey, accOther.StorageRoot } diff --git a/state/tx_cache_test.go b/state/tx_cache_test.go index f07d2cfa..a943ec72 100644 --- a/state/tx_cache_test.go +++ b/state/tx_cache_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/go-wire" ) func TestStateToFromVMAccount(t *testing.T) { diff --git a/state/types/genesis.go b/state/types/genesis.go index 95e34d23..8886da40 100644 --- a/state/types/genesis.go +++ b/state/types/genesis.go @@ -3,9 +3,9 @@ package types import ( "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-wire" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/test/mock/mock_web_api_test.go b/test/mock/mock_web_api_test.go index fc5c65ca..8671952b 100644 --- a/test/mock/mock_web_api_test.go +++ b/test/mock/mock_web_api_test.go @@ -7,9 +7,9 @@ import ( // edb "github.com/eris-ltd/erisdb/erisdb" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/suite" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/log15" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" edb "github.com/eris-ltd/eris-db/erisdb" ep "github.com/eris-ltd/eris-db/erisdb/pipe" diff --git a/test/mock/pipe.go b/test/mock/pipe.go index 03d09e47..3ec3966d 100644 --- a/test/mock/pipe.go +++ b/test/mock/pipe.go @@ -4,8 +4,8 @@ import ( ep "github.com/eris-ltd/eris-db/erisdb/pipe" td "github.com/eris-ltd/eris-db/test/testdata/testdata" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" ) diff --git a/test/server/scumbag.go b/test/server/scumbag.go index dbf50eff..b068666a 100644 --- a/test/server/scumbag.go +++ b/test/server/scumbag.go @@ -3,7 +3,7 @@ package server import ( "encoding/json" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" "github.com/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/server" "os" diff --git a/test/transacting/transacting_tes.go b/test/transacting/transacting_tes.go index e7fa397b..50c642a5 100644 --- a/test/transacting/transacting_tes.go +++ b/test/transacting/transacting_tes.go @@ -10,7 +10,7 @@ import ( ess "github.com/eris-ltd/eris-db/erisdb/erisdbss" // ep "github.com/eris-ltd/eris-db/erisdb/pipe" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" "github.com/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/server" td "github.com/eris-ltd/eris-db/test/testdata/testdata" diff --git a/test/web_api/shared.go b/test/web_api/shared.go index 4f08a3c4..1c3acb46 100644 --- a/test/web_api/shared.go +++ b/test/web_api/shared.go @@ -2,7 +2,7 @@ package web_api import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" "os" "runtime" ) diff --git a/tmsp/erisdb.go b/tmsp/erisdb.go index dd89e533..b1329313 100644 --- a/tmsp/erisdb.go +++ b/tmsp/erisdb.go @@ -2,28 +2,31 @@ package tmsp import ( "bytes" + "fmt" "sync" - //sm "github.com/eris-ltd/eris-db/state" - // txs "github.com/eris-ltd/eris-db/txs" - sm "github.com/eris-ltd/eris-db/state" types "github.com/eris-ltd/eris-db/txs" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" + "github.com/tendermint/go-events" + "github.com/tendermint/go-wire" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" + tmsp "github.com/tendermint/tmsp/types" ) //-------------------------------------------------------------------------------- -// ErisDBApp holds the current state and opens new contexts for proposed updates to the state +// ErisDBApp holds the current state, runs transactions, computes hashes. +// Typically two connections are opened by the tendermint core: +// one for mempool, one for consensus. type ErisDBApp struct { mtx sync.Mutex state *sm.State - evsw *events.EventSwitch + cache *sm.BlockCache + + evc *events.EventCache + evsw *events.EventSwitch } func (app *ErisDBApp) GetState() *sm.State { @@ -35,104 +38,61 @@ func (app *ErisDBApp) GetState() *sm.State { func NewErisDBApp(s *sm.State, evsw *events.EventSwitch) *ErisDBApp { return &ErisDBApp{ state: s, + cache: sm.NewBlockCache(s), + evc: events.NewEventCache(evsw), evsw: evsw, } } // Implements tmsp.Application -func (app *ErisDBApp) Open() tmsp.AppContext { - app.mtx.Lock() - state := app.state.Copy() - app.mtx.Unlock() - return &ErisDBAppContext{ - state: state, - cache: sm.NewBlockCache(state), - evc: events.NewEventCache(app.evsw), - } -} - -//-------------------------------------------------------------------------------- -// ErisDBAppContext runs transactions, computes hashes, and handles commits/rollbacks. -// Typically two contexts (connections) are opened by the tendermint core: -// one for mempool, one for consensus. - -type ErisDBAppContext struct { - app *ErisDBApp - - state *sm.State - cache *sm.BlockCache - - evc *events.EventCache -} - -func (appC *ErisDBAppContext) Echo(message string) string { - return message +func (appC *ErisDBApp) Info() (info string) { + return "ErisDB" } -func (appC *ErisDBAppContext) Info() []string { - return []string{"ErisDB"} -} - -func (appC *ErisDBAppContext) SetOption(key string, value string) tmsp.RetCode { - return 0 +// Implements tmsp.Application +func (appC *ErisDBApp) SetOption(key string, value string) (log string) { + return "" } -func (appC ErisDBAppContext) AppendTx(txBytes []byte) ([]tmsp.Event, tmsp.RetCode) { +// Implements tmsp.Application +func (appC ErisDBApp) AppendTx(txBytes []byte) (code tmsp.CodeType, result []byte, log string) { var n int var err error tx := new(types.Tx) buf := bytes.NewBuffer(txBytes) wire.ReadBinaryPtr(tx, buf, len(txBytes), &n, &err) if err != nil { - // TODO: handle error - return nil, tmsp.RetCodeEncodingError + return tmsp.CodeType_EncodingError, nil, fmt.Sprintf("Encoding error: %v", err) } err = sm.ExecTx(appC.cache, *tx, true, appC.evc) if err != nil { - // TODO: handle error - return nil, tmsp.RetCodeInternalError // ?! + return tmsp.CodeType_InternalError, nil, fmt.Sprintf("Encoding error: %v", err) } - return nil, tmsp.RetCodeOK + return tmsp.CodeType_OK, nil, "" } -func (appC *ErisDBAppContext) GetHash() ([]byte, tmsp.RetCode) { - appC.cache.Sync() - return appC.state.Hash(), tmsp.RetCodeOK +// Implements tmsp.Application +func (appC ErisDBApp) CheckTx(txBytes []byte) (code tmsp.CodeType, result []byte, log string) { + // TODO: precheck + return tmsp.CodeType_OK, nil, "" } -func (appC *ErisDBAppContext) Commit() tmsp.RetCode { +// Implements tmsp.Application +// GetHash should commit the state (called at end of block) +func (appC *ErisDBApp) GetHash() (hash []byte, log string) { + appC.cache.Sync() + // save state to disk appC.state.Save() - // flush events to listeners + // flush events to listeners (XXX: note issue with blocking) appC.evc.Flush() - // update underlying app state for new tmsp connections - appC.app.mtx.Lock() - appC.app.state = appC.state - appC.app.mtx.Unlock() - return 0 -} - -func (appC *ErisDBAppContext) Rollback() tmsp.RetCode { - appC.app.mtx.Lock() - appC.state = appC.app.state - appC.app.mtx.Unlock() - - appC.cache = sm.NewBlockCache(appC.state) - return 0 -} - -func (appC *ErisDBAppContext) AddListener(key string) tmsp.RetCode { - return 0 -} - -func (appC *ErisDBAppContext) RemListener(key string) tmsp.RetCode { - return 0 + return appC.state.Hash(), "" } -func (appC *ErisDBAppContext) Close() error { - return nil +func (appC *ErisDBApp) Query(query []byte) (code tmsp.CodeType, result []byte, log string) { + return tmsp.CodeType_OK, nil, "" } diff --git a/txs/config.go b/txs/config.go index e8f96401..cb982879 100644 --- a/txs/config.go +++ b/txs/config.go @@ -1,7 +1,7 @@ package types import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" + cfg "github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/txs/events.go b/txs/events.go index 522658e4..edf7046c 100644 --- a/txs/events.go +++ b/txs/events.go @@ -4,10 +4,10 @@ import ( "fmt" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" // Block + "github.com/tendermint/tendermint/types" // Block ) // Functions to generate eventId strings diff --git a/txs/log.go b/txs/log.go index 1f22008f..dbe8a678 100644 --- a/txs/log.go +++ b/txs/log.go @@ -1,7 +1,7 @@ package types import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "types") diff --git a/txs/tx.go b/txs/tx.go index a65666c3..439ffe55 100644 --- a/txs/tx.go +++ b/txs/tx.go @@ -7,12 +7,13 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" // votes for dupeout .. + "github.com/tendermint/tendermint/types" // votes for dupeout .. + "github.com/tendermint/go-crypto" ) var ( @@ -98,11 +99,11 @@ var _ = wire.RegisterInterface( //----------------------------------------------------------------------------- type TxInput struct { - Address []byte `json:"address"` // Hash of the PubKey - Amount int64 `json:"amount"` // Must not exceed account balance - Sequence int `json:"sequence"` // Must be 1 greater than the last committed TxInput - Signature acm.Signature `json:"signature"` // Depends on the PubKey type and the whole Tx - PubKey acm.PubKey `json:"pub_key"` // Must not be nil, may be nil + Address []byte `json:"address"` // Hash of the PubKey + Amount int64 `json:"amount"` // Must not exceed account balance + Sequence int `json:"sequence"` // Must be 1 greater than the last committed TxInput + Signature crypto.Signature `json:"signature"` // Depends on the PubKey type and the whole Tx + PubKey crypto.PubKey `json:"pub_key"` // Must not be nil, may be nil } func (txIn *TxInput) ValidateBasic() error { @@ -256,10 +257,10 @@ func (tx *NameTx) String() string { //----------------------------------------------------------------------------- type BondTx struct { - PubKey acm.PubKeyEd25519 `json:"pub_key"` - Signature acm.SignatureEd25519 `json:"signature"` - Inputs []*TxInput `json:"inputs"` - UnbondTo []*TxOutput `json:"unbond_to"` + PubKey crypto.PubKeyEd25519 `json:"pub_key"` + Signature crypto.SignatureEd25519 `json:"signature"` + Inputs []*TxInput `json:"inputs"` + UnbondTo []*TxOutput `json:"unbond_to"` } func (tx *BondTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { @@ -290,9 +291,9 @@ func (tx *BondTx) String() string { //----------------------------------------------------------------------------- type UnbondTx struct { - Address []byte `json:"address"` - Height int `json:"height"` - Signature acm.SignatureEd25519 `json:"signature"` + Address []byte `json:"address"` + Height int `json:"height"` + Signature crypto.SignatureEd25519 `json:"signature"` } func (tx *UnbondTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { @@ -307,9 +308,9 @@ func (tx *UnbondTx) String() string { //----------------------------------------------------------------------------- type RebondTx struct { - Address []byte `json:"address"` - Height int `json:"height"` - Signature acm.SignatureEd25519 `json:"signature"` + Address []byte `json:"address"` + Height int `json:"height"` + Signature crypto.SignatureEd25519 `json:"signature"` } func (tx *RebondTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { diff --git a/txs/tx_test.go b/txs/tx_test.go index b52e4df7..8e772b9a 100644 --- a/txs/tx_test.go +++ b/txs/tx_test.go @@ -3,8 +3,8 @@ package types import ( "testing" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" + . "github.com/tendermint/go-common" + _ "github.com/tendermint/tendermint/config/tendermint_test" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/txs/tx_utils.go b/txs/tx_utils.go index 97bc8a6b..f8ce376a 100644 --- a/txs/tx_utils.go +++ b/txs/tx_utils.go @@ -4,6 +4,8 @@ import ( "fmt" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" + + "github.com/tendermint/go-crypto" ) type AccountGetter interface { @@ -20,7 +22,7 @@ func NewSendTx() *SendTx { } } -func (tx *SendTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error { +func (tx *SendTx) AddInput(st AccountGetter, pubkey crypto.PubKey, amt int64) error { addr := pubkey.Address() acc := st.GetAccount(addr) if acc == nil { @@ -29,13 +31,13 @@ func (tx *SendTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1) } -func (tx *SendTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error { +func (tx *SendTx) AddInputWithNonce(pubkey crypto.PubKey, amt int64, nonce int) error { addr := pubkey.Address() tx.Inputs = append(tx.Inputs, &TxInput{ Address: addr, Amount: amt, Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: pubkey, }) return nil @@ -61,7 +63,7 @@ func (tx *SendTx) SignInput(chainID string, i int, privAccount *acm.PrivAccount) //---------------------------------------------------------------------------- // CallTx interface for creating tx -func NewCallTx(st AccountGetter, from acm.PubKey, to, data []byte, amt, gasLimit, fee int64) (*CallTx, error) { +func NewCallTx(st AccountGetter, from crypto.PubKey, to, data []byte, amt, gasLimit, fee int64) (*CallTx, error) { addr := from.Address() acc := st.GetAccount(addr) if acc == nil { @@ -72,13 +74,13 @@ func NewCallTx(st AccountGetter, from acm.PubKey, to, data []byte, amt, gasLimit return NewCallTxWithNonce(from, to, data, amt, gasLimit, fee, nonce), nil } -func NewCallTxWithNonce(from acm.PubKey, to, data []byte, amt, gasLimit, fee int64, nonce int) *CallTx { +func NewCallTxWithNonce(from crypto.PubKey, to, data []byte, amt, gasLimit, fee int64, nonce int) *CallTx { addr := from.Address() input := &TxInput{ Address: addr, Amount: amt, Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: from, } @@ -99,7 +101,7 @@ func (tx *CallTx) Sign(chainID string, privAccount *acm.PrivAccount) { //---------------------------------------------------------------------------- // NameTx interface for creating tx -func NewNameTx(st AccountGetter, from acm.PubKey, name, data string, amt, fee int64) (*NameTx, error) { +func NewNameTx(st AccountGetter, from crypto.PubKey, name, data string, amt, fee int64) (*NameTx, error) { addr := from.Address() acc := st.GetAccount(addr) if acc == nil { @@ -110,13 +112,13 @@ func NewNameTx(st AccountGetter, from acm.PubKey, name, data string, amt, fee in return NewNameTxWithNonce(from, name, data, amt, fee, nonce), nil } -func NewNameTxWithNonce(from acm.PubKey, name, data string, amt, fee int64, nonce int) *NameTx { +func NewNameTxWithNonce(from crypto.PubKey, name, data string, amt, fee int64, nonce int) *NameTx { addr := from.Address() input := &TxInput{ Address: addr, Amount: amt, Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: from, } @@ -136,8 +138,8 @@ func (tx *NameTx) Sign(chainID string, privAccount *acm.PrivAccount) { //---------------------------------------------------------------------------- // BondTx interface for adding inputs/outputs and adding signatures -func NewBondTx(pubkey acm.PubKey) (*BondTx, error) { - pubkeyEd, ok := pubkey.(acm.PubKeyEd25519) +func NewBondTx(pubkey crypto.PubKey) (*BondTx, error) { + pubkeyEd, ok := pubkey.(crypto.PubKeyEd25519) if !ok { return nil, fmt.Errorf("Pubkey must be ed25519") } @@ -148,7 +150,7 @@ func NewBondTx(pubkey acm.PubKey) (*BondTx, error) { }, nil } -func (tx *BondTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error { +func (tx *BondTx) AddInput(st AccountGetter, pubkey crypto.PubKey, amt int64) error { addr := pubkey.Address() acc := st.GetAccount(addr) if acc == nil { @@ -157,13 +159,13 @@ func (tx *BondTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1) } -func (tx *BondTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error { +func (tx *BondTx) AddInputWithNonce(pubkey crypto.PubKey, amt int64, nonce int) error { addr := pubkey.Address() tx.Inputs = append(tx.Inputs, &TxInput{ Address: addr, Amount: amt, Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: pubkey, }) return nil @@ -179,7 +181,7 @@ func (tx *BondTx) AddOutput(addr []byte, amt int64) error { func (tx *BondTx) SignBond(chainID string, privAccount *acm.PrivAccount) error { sig := privAccount.Sign(chainID, tx) - sigEd, ok := sig.(acm.SignatureEd25519) + sigEd, ok := sig.(crypto.SignatureEd25519) if !ok { return fmt.Errorf("Bond signer must be ED25519") } @@ -207,7 +209,7 @@ func NewUnbondTx(addr []byte, height int) *UnbondTx { } func (tx *UnbondTx) Sign(chainID string, privAccount *acm.PrivAccount) { - tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519) + tx.Signature = privAccount.Sign(chainID, tx).(crypto.SignatureEd25519) } //---------------------------------------------------------------------- @@ -221,13 +223,13 @@ func NewRebondTx(addr []byte, height int) *RebondTx { } func (tx *RebondTx) Sign(chainID string, privAccount *acm.PrivAccount) { - tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519) + tx.Signature = privAccount.Sign(chainID, tx).(crypto.SignatureEd25519) } //---------------------------------------------------------------------------- // PermissionsTx interface for creating tx -func NewPermissionsTx(st AccountGetter, from acm.PubKey, args ptypes.PermArgs) (*PermissionsTx, error) { +func NewPermissionsTx(st AccountGetter, from crypto.PubKey, args ptypes.PermArgs) (*PermissionsTx, error) { addr := from.Address() acc := st.GetAccount(addr) if acc == nil { @@ -238,13 +240,13 @@ func NewPermissionsTx(st AccountGetter, from acm.PubKey, args ptypes.PermArgs) ( return NewPermissionsTxWithNonce(from, args, nonce), nil } -func NewPermissionsTxWithNonce(from acm.PubKey, args ptypes.PermArgs, nonce int) *PermissionsTx { +func NewPermissionsTxWithNonce(from crypto.PubKey, args ptypes.PermArgs, nonce int) *PermissionsTx { addr := from.Address() input := &TxInput{ Address: addr, Amount: 1, // NOTE: amounts can't be 0 ... Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: from, } -- GitLab