From 6d17c2ac2b27fe78370d7f60b8c15f765dea661d Mon Sep 17 00:00:00 2001 From: Ethan Buchman <ethan@coinculture.info> Date: Mon, 7 Dec 2015 20:07:56 -0500 Subject: [PATCH] godep --- Godeps/Godeps.json | 160 ++- .../src/github.com/gin-gonic/gin/auth_test.go | 2 +- .../gin-gonic/gin/binding/binding_test.go | 2 +- .../gin/binding/default_validator.go | 2 +- .../gin-gonic/gin/binding/validate_test.go | 2 +- .../src/github.com/gin-gonic/gin/context.go | 8 +- .../github.com/gin-gonic/gin/context_test.go | 4 +- .../github.com/gin-gonic/gin/debug_test.go | 2 +- .../github.com/gin-gonic/gin/errors_test.go | 2 +- .../gin/examples/app-engine/hello.go | 2 +- .../gin-gonic/gin/examples/basic/main.go | 2 +- .../gin/examples/realtime-advanced/main.go | 2 +- .../gin/examples/realtime-advanced/routes.go | 2 +- .../gin/examples/realtime-chat/main.go | 2 +- .../src/github.com/gin-gonic/gin/gin.go | 2 +- .../gin-gonic/gin/gin_integration_test.go | 2 +- .../src/github.com/gin-gonic/gin/gin_test.go | 2 +- .../gin-gonic/gin/githubapi_test.go | 2 +- .../github.com/gin-gonic/gin/logger_test.go | 2 +- .../gin-gonic/gin/middleware_test.go | 4 +- .../src/github.com/gin-gonic/gin/mode.go | 4 +- .../src/github.com/gin-gonic/gin/mode_test.go | 2 +- .../src/github.com/gin-gonic/gin/path_test.go | 2 +- .../github.com/gin-gonic/gin/recovery_test.go | 2 +- .../gin-gonic/gin/render/render_test.go | 2 +- .../gin-gonic/gin/response_writer_test.go | 2 +- .../gin-gonic/gin/routergroup_test.go | 2 +- .../github.com/gin-gonic/gin/routes_test.go | 2 +- .../github.com/gin-gonic/gin/utils_test.go | 2 +- .../websocket/examples/autobahn/server.go | 2 +- .../gorilla/websocket/examples/chat/conn.go | 2 +- .../websocket/examples/filewatch/main.go | 2 +- .../inconshreveable/log15/stack/stack_test.go | 2 +- .../github.com/manucorporat/sse/sse_test.go | 2 +- .../go-stringutil/strings_bench_test.go | 2 +- .../naoina/go-stringutil/strings_test.go | 2 +- .../src/github.com/naoina/toml/decode.go | 2 +- .../naoina/toml/decode_bench_test.go | 2 +- .../src/github.com/naoina/toml/decode_test.go | 2 +- .../src/github.com/naoina/toml/encode.go | 2 +- .../src/github.com/naoina/toml/encode_test.go | 2 +- .../src/github.com/naoina/toml/parse.go | 2 +- .../testify/require/forward_requirements.go | 2 +- .../stretchr/testify/require/requirements.go | 2 +- .../stretchr/testify/suite/suite.go | 4 +- .../stretchr/testify/suite/suite_test.go | 2 +- .../syndtr/goleveldb/leveldb/batch.go | 4 +- .../syndtr/goleveldb/leveldb/batch_test.go | 4 +- .../syndtr/goleveldb/leveldb/bench_test.go | 6 +- .../syndtr/goleveldb/leveldb/cache/cache.go | 2 +- .../syndtr/goleveldb/leveldb/comparer.go | 2 +- .../syndtr/goleveldb/leveldb/corrupt_test.go | 6 +- .../github.com/syndtr/goleveldb/leveldb/db.go | 399 ++---- .../syndtr/goleveldb/leveldb/db_compaction.go | 118 +- .../syndtr/goleveldb/leveldb/db_iter.go | 10 +- .../syndtr/goleveldb/leveldb/db_snapshot.go | 6 +- .../syndtr/goleveldb/leveldb/db_state.go | 18 +- .../syndtr/goleveldb/leveldb/db_test.go | 58 +- .../syndtr/goleveldb/leveldb/db_util.go | 10 +- .../syndtr/goleveldb/leveldb/db_write.go | 81 +- .../syndtr/goleveldb/leveldb/errors.go | 3 +- .../syndtr/goleveldb/leveldb/errors/errors.go | 4 +- .../syndtr/goleveldb/leveldb/external_test.go | 4 +- .../syndtr/goleveldb/leveldb/filter.go | 2 +- .../syndtr/goleveldb/leveldb/filter/bloom.go | 2 +- .../goleveldb/leveldb/filter/bloom_test.go | 2 +- .../goleveldb/leveldb/iterator/array_iter.go | 2 +- .../leveldb/iterator/array_iter_test.go | 4 +- .../leveldb/iterator/indexed_iter.go | 4 +- .../leveldb/iterator/indexed_iter_test.go | 6 +- .../syndtr/goleveldb/leveldb/iterator/iter.go | 2 +- .../leveldb/iterator/iter_suite_test.go | 2 +- .../goleveldb/leveldb/iterator/merged_iter.go | 6 +- .../leveldb/iterator/merged_iter_test.go | 6 +- .../goleveldb/leveldb/journal/journal.go | 4 +- .../syndtr/goleveldb/leveldb/key.go | 2 +- .../syndtr/goleveldb/leveldb/key_test.go | 2 +- .../goleveldb/leveldb/leveldb_suite_test.go | 2 +- .../goleveldb/leveldb/memdb/bench_test.go | 2 +- .../syndtr/goleveldb/leveldb/memdb/memdb.go | 17 +- .../leveldb/memdb/memdb_suite_test.go | 2 +- .../goleveldb/leveldb/memdb/memdb_test.go | 8 +- .../syndtr/goleveldb/leveldb/opt/options.go | 37 +- .../syndtr/goleveldb/leveldb/options.go | 4 +- .../syndtr/goleveldb/leveldb/session.go | 274 +++- .../goleveldb/leveldb/session_compaction.go | 287 ---- .../goleveldb/leveldb/session_record.go | 16 +- .../goleveldb/leveldb/session_record_test.go | 8 +- .../syndtr/goleveldb/leveldb/session_util.go | 6 +- .../goleveldb/leveldb/storage/file_storage.go | 2 +- .../goleveldb/leveldb/storage/mem_storage.go | 2 +- .../goleveldb/leveldb/storage/storage.go | 2 +- .../syndtr/goleveldb/leveldb/storage_test.go | 14 +- .../syndtr/goleveldb/leveldb/table.go | 20 +- .../goleveldb/leveldb/table/block_test.go | 8 +- .../syndtr/goleveldb/leveldb/table/reader.go | 20 +- .../leveldb/table/table_suite_test.go | 2 +- .../goleveldb/leveldb/table/table_test.go | 8 +- .../syndtr/goleveldb/leveldb/table/writer.go | 10 +- .../syndtr/goleveldb/leveldb/testutil/db.go | 6 +- .../syndtr/goleveldb/leveldb/testutil/iter.go | 2 +- .../syndtr/goleveldb/leveldb/testutil/kv.go | 2 +- .../goleveldb/leveldb/testutil/kvtest.go | 4 +- .../goleveldb/leveldb/testutil/storage.go | 4 +- .../syndtr/goleveldb/leveldb/testutil/util.go | 2 +- .../syndtr/goleveldb/leveldb/testutil_test.go | 8 +- .../syndtr/goleveldb/leveldb/util.go | 2 +- .../syndtr/goleveldb/leveldb/version.go | 8 +- .../gosnappy}/snappy/decode.go | 0 .../gosnappy}/snappy/encode.go | 0 .../gosnappy}/snappy/snappy.go | 0 .../gosnappy}/snappy/snappy_test.go | 0 .../github.com/tendermint/ed25519/ed25519.go | 2 +- .../ed25519/extra25519/extra25519.go | 2 +- .../tendermint}/flowcontrol/flowcontrol.go | 0 .../tendermint}/flowcontrol/io.go | 0 .../tendermint}/flowcontrol/io_test.go | 0 .../tendermint}/flowcontrol/util.go | 0 .../github.com/tendermint/go-clist/LICENSE.md | 206 +++ .../github.com/tendermint/go-clist/clist.go | 285 ++++ .../tendermint/go-clist/clist_test.go | 213 +++ .../tendermint/go-common/LICENSE.md | 206 +++ .../{tendermint/common => go-common}/array.go | 0 .../{tendermint/common => go-common}/async.go | 0 .../common => go-common}/bit_array.go | 0 .../common => go-common}/bit_array_test.go | 0 .../common => go-common}/byteslice.go | 0 .../{tendermint/common => go-common}/cmap.go | 0 .../tendermint/go-common/cmap_int.go | 62 + .../tendermint/go-common/cmap_test.go | 71 + .../common => go-common}/colors.go | 0 .../common => go-common}/errors.go | 0 .../{tendermint/common => go-common}/heap.go | 0 .../{tendermint/common => go-common}/int.go | 0 .../src/github.com/tendermint/go-common/io.go | 75 + .../{tendermint/common => go-common}/math.go | 0 .../github.com/tendermint/go-common/net.go | 14 + .../{tendermint/common => go-common}/os.go | 18 +- .../common => go-common}/random.go | 0 .../common => go-common}/repeat_timer.go | 0 .../common => go-common}/service.go | 7 +- .../common => go-common}/string.go | 0 .../common => go-common}/test/assert.go | 0 .../common => go-common}/test/mutate.go | 2 +- .../common => go-common}/throttle_timer.go | 0 .../{tendermint/common => go-common}/word.go | 0 .../tendermint/go-config/LICENSE.md | 206 +++ .../config => go-config}/config.go | 67 +- .../tendermint/go-crypto/LICENSE.md | 206 +++ .../account => go-crypto}/priv_key.go | 17 +- .../account => go-crypto}/pub_key.go | 14 +- .../account => go-crypto}/signature.go | 6 +- .../account => go-crypto}/signature_test.go | 18 +- .../github.com/tendermint/go-db/LICENSE.md | 206 +++ .../{tendermint/db => go-db}/config.go | 2 +- .../tendermint/{tendermint/db => go-db}/db.go | 2 +- .../{tendermint/db => go-db}/level_db.go | 9 +- .../{tendermint/db => go-db}/mem_db.go | 0 .../tendermint/go-logger/LICENSE.md | 206 +++ .../logger => go-logger}/config.go | 2 +- .../{tendermint/logger => go-logger}/log.go | 15 +- .../tendermint/go-merkle/LICENSE.md | 206 +++ .../merkle => go-merkle}/README.md | 0 .../merkle => go-merkle}/iavl_node.go | 26 +- .../merkle => go-merkle}/iavl_proof.go | 12 +- .../merkle => go-merkle}/iavl_test.go | 20 +- .../merkle => go-merkle}/iavl_tree.go | 10 +- .../merkle => go-merkle}/simple_tree.go | 12 +- .../merkle => go-merkle}/simple_tree_test.go | 4 +- .../{tendermint/merkle => go-merkle}/types.go | 0 .../{tendermint/merkle => go-merkle}/util.go | 0 .../github.com/tendermint/go-p2p/LICENSE.md | 206 +++ .../{tendermint/p2p => go-p2p}/README.md | 6 +- .../{tendermint/p2p => go-p2p}/addrbook.go | 7 +- .../p2p => go-p2p}/addrbook_test.go | 0 .../{tendermint/p2p => go-p2p}/connection.go | 90 +- .../tendermint/go-p2p/ip_range_counter.go | 29 + .../{tendermint/p2p => go-p2p}/listener.go | 9 +- .../src/github.com/tendermint/go-p2p/log.go | 7 + .../{tendermint/p2p => go-p2p}/netaddress.go | 2 +- .../{tendermint/p2p => go-p2p}/peer.go | 28 +- .../github.com/tendermint/go-p2p/peer_set.go | 115 ++ .../tendermint/go-p2p/peer_set_test.go | 67 + .../{tendermint/p2p => go-p2p}/pex_reactor.go | 18 +- .../p2p => go-p2p}/secret_connection.go | 36 +- .../p2p => go-p2p}/secret_connection_test.go | 14 +- .../{tendermint/p2p => go-p2p}/switch.go | 35 +- .../{tendermint/p2p => go-p2p}/switch_test.go | 30 +- .../src/github.com/tendermint/go-p2p/types.go | 77 + .../{tendermint/p2p => go-p2p}/upnp/README.md | 0 .../github.com/tendermint/go-p2p/upnp/log.go | 7 + .../{tendermint/p2p => go-p2p}/upnp/probe.go | 2 +- .../{tendermint/p2p => go-p2p}/upnp/upnp.go | 0 .../{tendermint/p2p => go-p2p}/util.go | 0 .../{tendermint/p2p => go-p2p}/version.go | 0 .../github.com/tendermint/go-wire/LICENSE.md | 206 +++ .../{tendermint/wire => go-wire}/README.md | 21 +- .../{tendermint/wire => go-wire}/byteslice.go | 16 +- .../tendermint/go-wire/byteslice_test.go | 86 ++ .../{tendermint/wire => go-wire}/codec.go | 14 +- .../{tendermint/wire => go-wire}/int.go | 52 +- .../{tendermint/wire => go-wire}/int_test.go | 4 +- .../src/github.com/tendermint/go-wire/log.go | 17 + .../{tendermint/wire => go-wire}/reflect.go | 90 +- .../wire => go-wire}/reflect_test.go | 39 +- .../{tendermint/wire => go-wire}/string.go | 8 +- .../tendermint/go-wire/string_test.go | 86 ++ .../{tendermint/wire => go-wire}/time.go | 6 +- .../{tendermint/wire => go-wire}/util.go | 29 +- .../{tendermint/wire => go-wire}/version.go | 0 .../{tendermint/wire => go-wire}/wire.go | 49 +- .../github.com/tendermint/log15/handler.go | 2 +- .../src/github.com/tendermint/log15/root.go | 4 +- .../tendermint/log15/stack/stack_test.go | 2 +- .../tendermint/tendermint/account/account.go | 74 - .../tendermint/account/priv_account.go | 84 -- .../tendermint/tendermint/alert/alert.go | 2 +- .../tendermint/tendermint/alert/config.go | 2 +- .../tendermint/tendermint/alert/log.go | 2 +- .../tendermint/tendermint/blockchain/log.go | 2 +- .../tendermint/tendermint/blockchain/pool.go | 76 +- .../tendermint/blockchain/pool_test.go | 4 +- .../tendermint/blockchain/reactor.go | 64 +- .../tendermint/tendermint/blockchain/store.go | 30 +- .../tendermint/tendermint/common/io.go | 24 - .../tendermint/tendermint/config/log.go | 9 - .../tendermint/config/tendermint/config.go | 96 +- .../tendermint/config/tendermint/genesis.json | 75 + .../config/tendermint_test/config.go | 27 +- .../tendermint/consensus/common_test.go | 335 +++++ .../tendermint/tendermint/consensus/config.go | 2 +- .../tendermint/consensus/height_vote_set.go | 4 +- .../tendermint/tendermint/consensus/log.go | 2 +- .../tendermint/consensus/reactor.go | 71 +- .../tendermint/tendermint/consensus/state.go | 319 ++--- .../tendermint/consensus/state_test.go | 1186 ++++++++++++++++ .../tendermint/tendermint/consensus/test.go | 225 --- .../tendermint/events/event_cache.go | 2 +- .../tendermint/tendermint/events/events.go | 4 +- .../tendermint/tendermint/events/log.go | 2 +- .../tendermint/{p2p => mempool}/config.go | 4 +- .../tendermint/tendermint/mempool/log.go | 2 +- .../tendermint/tendermint/mempool/mempool.go | 259 +++- .../tendermint/mempool/mempool_test.go | 118 ++ .../tendermint/tendermint/mempool/reactor.go | 103 +- .../tendermint/tendermint/node/config.go | 2 +- .../tendermint/tendermint/node/id.go | 8 +- .../tendermint/tendermint/node/log.go | 2 +- .../tendermint/tendermint/node/node.go | 206 +-- .../tendermint/tendermint/node/node_test.go | 20 +- .../tendermint/tendermint/p2p/log.go | 7 - .../tendermint/tendermint/p2p/peer_set.go | 227 --- .../tendermint/p2p/peer_set_test.go | 169 --- .../tendermint/tendermint/p2p/upnp/log.go | 7 - .../tendermint/permission/types/errors.go | 23 - .../permission/types/permissions.go | 238 ---- .../tendermint/permission/types/snatives.go | 102 -- .../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 | 6 +- .../tendermint/tendermint/rpc/client/log.go | 2 +- .../tendermint/rpc/core/accounts.go | 67 - .../tendermint/tendermint/rpc/core/blocks.go | 6 +- .../tendermint/tendermint/rpc/core/config.go | 2 +- .../tendermint/rpc/core/consensus.go | 23 +- .../tendermint/tendermint/rpc/core/log.go | 2 +- .../tendermint/tendermint/rpc/core/mempool.go | 21 +- .../tendermint/tendermint/rpc/core/names.go | 29 - .../tendermint/tendermint/rpc/core/net.go | 16 +- .../tendermint/tendermint/rpc/core/pipe.go | 15 +- .../tendermint/tendermint/rpc/core/routes.go | 30 +- .../tendermint/tendermint/rpc/core/txs.go | 116 -- .../tendermint/rpc/core/types/responses.go | 103 +- .../tendermint/rpc/core_client/client.go | 236 --- .../rpc/core_client/client_methods.go | 1042 -------------- .../tendermint/rpc/core_client/log.go | 7 - .../tendermint/rpc/core_client/ws_client.go | 119 -- .../tendermint/rpc/server/handlers.go | 16 +- .../tendermint/rpc/server/http_server.go | 10 +- .../tendermint/tendermint/rpc/server/log.go | 2 +- .../tendermint/rpc/test/client_rpc_test.go | 129 -- .../tendermint/rpc/test/client_ws_test.go | 212 --- .../tendermint/tendermint/rpc/test/config.go | 13 - .../tendermint/tendermint/rpc/test/helpers.go | 282 ---- .../tendermint/tendermint/rpc/test/tests.go | 281 ---- .../tendermint/rpc/test/ws_helpers.go | 271 ---- .../tendermint/state/block_cache.go | 293 ---- .../tendermint/tendermint/state/common.go | 18 - .../tendermint/tendermint/state/execution.go | 1036 ++------------ .../tendermint/state/genesis_test.go | 87 -- .../tendermint/tendermint/state/log.go | 2 +- .../tendermint/state/permissions_test.go | 1265 ----------------- .../tendermint/tendermint/state/state.go | 454 +----- .../tendermint/tendermint/state/state_test.go | 699 --------- .../tendermint/tendermint/state/test.go | 76 - .../tendermint/tendermint/state/tx_cache.go | 198 --- .../tendermint/state/tx_cache_test.go | 22 - .../tendermint/state/types/genesis.go | 61 - .../tendermint/tendermint/state/wtf | 68 + .../tendermint/tendermint/types/block.go | 40 +- .../tendermint/tendermint/types/config.go | 2 +- .../tendermint/tendermint/types/events.go | 81 +- .../tendermint/tendermint/types/genesis.go | 48 + .../tendermint/tendermint/types/keys.go | 6 + .../tendermint/tendermint/types/log.go | 2 +- .../tendermint/tendermint/types/myfile | Bin 0 -> 598 bytes .../tendermint/tendermint/types/names.go | 55 - .../tendermint/tendermint/types/node.go | 67 - .../tendermint/tendermint/types/part_set.go | 10 +- .../tendermint/types/part_set_test.go | 2 +- .../tendermint/types/priv_validator.go | 67 +- .../tendermint/tendermint/types/proposal.go | 19 +- .../tendermint/types/proposal_test.go | 7 +- .../tendermint/tendermint/types/signable.go | 30 + .../tendermint/tendermint/types/stats.go | 46 + .../tendermint/tendermint/types/tx.go | 374 +---- .../tendermint/tendermint/types/tx_test.go | 178 --- .../tendermint/tendermint/types/tx_utils.go | 260 ---- .../tendermint/tendermint/types/validator.go | 58 +- .../tendermint/types/validator_set.go | 14 +- .../tendermint/types/validator_set_test.go | 120 +- .../tendermint/tendermint/types/vote.go | 20 +- .../{vm/.ethtest => types/vote_set} | 0 .../tendermint/tendermint/types/vote_set.go | 38 +- .../tendermint/types/vote_set_test.go | 8 +- .../tendermint/tendermint/vm/common.go | 26 - .../tendermint/tendermint/vm/gas.go | 18 - .../tendermint/tendermint/vm/log.go | 7 - .../tendermint/tendermint/vm/native.go | 104 -- .../tendermint/tendermint/vm/opcodes.go | 354 ----- .../tendermint/vm/randentropy/rand_entropy.go | 35 - .../tendermint/tendermint/vm/sha3/keccakf.go | 171 --- .../tendermint/tendermint/vm/sha3/sha3.go | 224 --- .../tendermint/tendermint/vm/snative.go | 233 --- .../tendermint/tendermint/vm/stack.go | 126 -- .../tendermint/vm/test/fake_app_state.go | 79 - .../tendermint/vm/test/log_event_test.go | 90 -- .../tendermint/tendermint/vm/test/vm_test.go | 207 --- .../tendermint/tendermint/vm/types.go | 49 - .../github.com/tendermint/tendermint/vm/vm.go | 918 ------------ .../tendermint/tendermint/wire/log.go | 18 - .../tendermint/tmsp/server/server.go | 163 +++ .../tendermint/tmsp/types/application.go | 40 + .../tendermint/tmsp/types/events.go | 6 + .../tendermint/tmsp/types/messages.go | 184 +++ .../tendermint/tmsp/types/retcode.go | 32 + .../tendermint/tmsp/types/retcode_string.go | 16 + .../src/github.com/tommy351/gin-cors/cors.go | 2 +- .../github.com/tommy351/gin-cors/cors_test.go | 4 +- .../x/crypto/curve25519/const_amd64.s | 2 +- .../x/crypto/curve25519/cswap_amd64.s | 2 +- .../x/crypto/curve25519/curve25519.go | 2 +- .../x/crypto/curve25519/freeze_amd64.s | 2 +- .../x/crypto/curve25519/ladderstep_amd64.s | 2 +- .../x/crypto/curve25519/mont25519_amd64.go | 2 +- .../x/crypto/curve25519/mul_amd64.s | 2 +- .../x/crypto/curve25519/square_amd64.s | 2 +- .../src/golang.org/x/crypto/nacl/box/box.go | 6 +- .../golang.org/x/crypto/nacl/box/box_test.go | 2 +- .../x/crypto/nacl/secretbox/secretbox.go | 4 +- .../x/crypto/poly1305/const_amd64.s | 2 +- .../x/crypto/poly1305/poly1305_amd64.s | 2 +- .../x/crypto/poly1305/poly1305_arm.s | 331 ----- .../golang.org/x/crypto/poly1305/sum_amd64.go | 2 +- .../golang.org/x/crypto/poly1305/sum_arm.go | 24 - .../golang.org/x/crypto/poly1305/sum_ref.go | 2 +- .../x/net/context/withtimeout_test.go | 2 +- .../gopkg.in/tylerb/graceful.v1/graceful.go | 2 +- account/account.go | 6 +- account/priv_account.go | 6 +- account/priv_key.go | 8 +- account/pub_key.go | 10 +- account/signature.go | 4 +- account/signature_test.go | 6 +- client/ws_client.go | 2 +- cmd/erisdbss/main.go | 2 +- erisdb/codec.go | 2 +- erisdb/config.go | 2 +- erisdb/erisdbss/http.go | 10 +- erisdb/erisdbss/log.go | 2 +- erisdb/erisdbss/server_manager.go | 6 +- erisdb/event_cache.go | 2 +- erisdb/event_cache_test.go | 4 +- erisdb/json_service.go | 2 +- erisdb/middleware_test.go | 2 +- erisdb/pipe/accounts.go | 2 +- erisdb/pipe/blockchain.go | 4 +- erisdb/pipe/config.go | 4 +- erisdb/pipe/consensus.go | 2 +- erisdb/pipe/events.go | 4 +- erisdb/pipe/pipe.go | 4 +- erisdb/pipe/transactor.go | 6 +- erisdb/pipe/types.go | 6 +- erisdb/restServer.go | 2 +- erisdb/serve.go | 20 +- erisdb/wsService.go | 2 +- evm/log.go | 2 +- evm/native.go | 4 +- evm/opcodes.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/files_test.go | 2 +- files/log.go | 2 +- permission/types/permissions.go | 2 +- permission/types/snatives.go | 2 +- rpc/rpc_test.go | 2 +- server/config.go | 2 +- server/log.go | 2 +- server/logging.go | 2 +- server/server.go | 6 +- server/server_test.go | 2 +- server/websocket.go | 26 +- state/block_cache.go | 8 +- 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 | 12 +- state/state_test.go | 4 +- state/test.go | 6 +- state/tx_cache.go | 2 +- state/tx_cache_test.go | 2 +- state/types/genesis.go | 6 +- test/filters/filter_test.go | 2 +- test/mock/mock_web_api_test.go | 10 +- test/mock/pipe.go | 4 +- test/server/http_burst_test.go | 2 +- test/server/scumbag.go | 4 +- test/server/ws_burst_test.go | 6 +- test/transacting/transacting_tes.go | 10 +- test/web_api/query_test.go | 4 +- test/web_api/shared.go | 4 +- test/web_api/web_api_test.go | 4 +- tmsp/erisdb.go | 6 +- txs/config.go | 2 +- txs/events.go | 6 +- txs/log.go | 2 +- txs/tx.go | 8 +- txs/tx_test.go | 4 +- util/util_test.go | 2 +- 449 files changed, 8605 insertions(+), 14702 deletions(-) delete mode 100644 Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_compaction.go rename Godeps/_workspace/src/github.com/{google/go-snappy => syndtr/gosnappy}/snappy/decode.go (100%) rename Godeps/_workspace/src/github.com/{google/go-snappy => syndtr/gosnappy}/snappy/encode.go (100%) rename Godeps/_workspace/src/github.com/{google/go-snappy => syndtr/gosnappy}/snappy/snappy.go (100%) rename Godeps/_workspace/src/github.com/{google/go-snappy => syndtr/gosnappy}/snappy/snappy_test.go (100%) rename Godeps/_workspace/src/{code.google.com/p/mxk/go1 => github.com/tendermint}/flowcontrol/flowcontrol.go (100%) rename Godeps/_workspace/src/{code.google.com/p/mxk/go1 => github.com/tendermint}/flowcontrol/io.go (100%) rename Godeps/_workspace/src/{code.google.com/p/mxk/go1 => github.com/tendermint}/flowcontrol/io_test.go (100%) rename Godeps/_workspace/src/{code.google.com/p/mxk/go1 => github.com/tendermint}/flowcontrol/util.go (100%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-clist/LICENSE.md create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-clist/clist.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-clist/clist_test.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-common/LICENSE.md rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/array.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/async.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/bit_array.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/bit_array_test.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/byteslice.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/cmap.go (100%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-common/cmap_int.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-common/cmap_test.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/colors.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/errors.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/heap.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/int.go (100%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-common/io.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/math.go (100%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-common/net.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/os.go (88%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/random.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/repeat_timer.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/service.go (96%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/string.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/test/assert.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/test/mutate.go (87%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/throttle_timer.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/common => go-common}/word.go (100%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-config/LICENSE.md rename Godeps/_workspace/src/github.com/tendermint/{tendermint/config => go-config}/config.go (53%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-crypto/LICENSE.md rename Godeps/_workspace/src/github.com/tendermint/{tendermint/account => go-crypto}/priv_key.go (71%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/account => go-crypto}/pub_key.go (80%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/account => go-crypto}/signature.go (77%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/account => go-crypto}/signature_test.go (78%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-db/LICENSE.md rename Godeps/_workspace/src/github.com/tendermint/{tendermint/db => go-db}/config.go (60%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/db => go-db}/db.go (90%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/db => go-db}/level_db.go (78%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/db => go-db}/mem_db.go (100%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-logger/LICENSE.md rename Godeps/_workspace/src/github.com/tendermint/{tendermint/logger => go-logger}/config.go (67%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/logger => go-logger}/log.go (68%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-merkle/LICENSE.md rename Godeps/_workspace/src/github.com/tendermint/{tendermint/merkle => go-merkle}/README.md (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/merkle => go-merkle}/iavl_node.go (94%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/merkle => go-merkle}/iavl_proof.go (91%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/merkle => go-merkle}/iavl_test.go (92%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/merkle => go-merkle}/iavl_tree.go (95%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/merkle => go-merkle}/simple_tree.go (95%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/merkle => go-merkle}/simple_tree_test.go (93%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/merkle => go-merkle}/types.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/merkle => go-merkle}/util.go (100%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-p2p/LICENSE.md rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/README.md (93%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/addrbook.go (98%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/addrbook_test.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/connection.go (88%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-p2p/ip_range_counter.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/listener.go (93%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/netaddress.go (98%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/peer.go (74%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/pex_reactor.go (92%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/secret_connection.go (85%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/secret_connection_test.go (92%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/switch.go (89%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/switch_test.go (89%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/upnp/README.md (100%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/upnp/probe.go (96%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/upnp/upnp.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/util.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/p2p => go-p2p}/version.go (100%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-wire/LICENSE.md rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/README.md (94%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/byteslice.go (63%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice_test.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/codec.go (89%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/int.go (70%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/int_test.go (95%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-wire/log.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/reflect.go (91%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/reflect_test.go (91%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/string.go (58%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/go-wire/string_test.go rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/time.go (65%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/util.go (60%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/version.go (100%) rename Godeps/_workspace/src/github.com/tendermint/{tendermint/wire => go-wire}/wire.go (70%) delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/account/account.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/account/priv_account.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/common/io.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/config/log.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/common_test.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/test.go rename Godeps/_workspace/src/github.com/tendermint/tendermint/{p2p => mempool}/config.go (54%) create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer_set.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer_set_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/errors.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/permissions.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/snatives.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/app_context.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/local_app_context.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/log.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context.go create 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/core/accounts.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/names.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/txs.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/client.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/client_methods.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/ws_client.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/client_rpc_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/client_ws_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/config.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/helpers.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/tests.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/ws_helpers.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/block_cache.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/common.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/genesis_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/permissions_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/state_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/tx_cache.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/tx_cache_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/types/genesis.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/genesis.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/keys.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/myfile delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/names.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/node.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/stats.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx_utils.go rename Godeps/_workspace/src/github.com/tendermint/tendermint/{vm/.ethtest => types/vote_set} (100%) delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/common.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/gas.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/log.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/native.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/randentropy/rand_entropy.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/sha3/keccakf.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/sha3/sha3.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/snative.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/stack.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/fake_app_state.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/log_event_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/types.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go delete mode 100644 Godeps/_workspace/src/github.com/tendermint/tendermint/wire/log.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tmsp/types/application.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tmsp/types/events.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tmsp/types/retcode.go create mode 100644 Godeps/_workspace/src/github.com/tendermint/tmsp/types/retcode_string.go delete mode 100644 Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_arm.s delete mode 100644 Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_arm.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 2ec0e90d..b3a9d001 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,6 +1,6 @@ { "ImportPath": "github.com/eris-ltd/eris-db", - "GoVersion": "go1.4.2", + "GoVersion": "go1.5.2", "Packages": [ "./..." ], @@ -10,11 +10,6 @@ "Comment": "null-236", "Rev": "69e2a90ed92d03812364aeb947b7068dc42e561e" }, - { - "ImportPath": "code.google.com/p/mxk/go1/flowcontrol", - "Comment": "null-12", - "Rev": "5ff2502e25566863e8a0136c7aae8838e4c7de39" - }, { "ImportPath": "github.com/agl/ed25519/edwards25519", "Rev": "d2b94fd789ea21d12fac1a4443dd3a3f79cda72c" @@ -24,10 +19,6 @@ "Comment": "v1.0rc1-104-g1a7ab6e", "Rev": "1a7ab6e4d5fdc72d6df30ef562102ae6e0d18518" }, - { - "ImportPath": "github.com/google/go-snappy/snappy", - "Rev": "eaa750b9bf4dcb7cb20454be850613b66cda3273" - }, { "ImportPath": "github.com/gorilla/websocket", "Rev": "a3ec486e6a7a41858210b0fc5d7b5df593b3c4a3" @@ -79,111 +70,128 @@ }, { "ImportPath": "github.com/syndtr/goleveldb/leveldb", - "Rev": "a06509502ca32565bdf74afc1e573050023f261c" + "Rev": "4875955338b0a434238a31165cb87255ab6e9e4a" + }, + { + "ImportPath": "github.com/syndtr/gosnappy/snappy", + "Rev": "156a073208e131d7d2e212cb749feae7c339e846" }, { "ImportPath": "github.com/tendermint/ed25519", "Rev": "533fb6548e2071076888eda3c38749d707ba49bc" }, { - "ImportPath": "github.com/tendermint/log15", - "Comment": "v2.3-36-gc65281b", - "Rev": "c65281bb703b7612f60558e75b07c434c06e2636" + "ImportPath": "github.com/tendermint/flowcontrol", + "Rev": "84d9671090430e8ec80e35b339907e0579b999eb" }, { - "ImportPath": "github.com/tendermint/tendermint/account", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/go-clist", + "Rev": "e3d88d2d7964e5f6a98bf27267f34c2e9f1737d2" }, { - "ImportPath": "github.com/tendermint/tendermint/alert", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/go-common", + "Rev": "3b50efbe025fae9be5c7efa01ad1781ac4221e85" }, { - "ImportPath": "github.com/tendermint/tendermint/blockchain", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/go-config", + "Rev": "3b895c7ce4999ee6fff7b7ca6253f0b41d9bf85c" }, { - "ImportPath": "github.com/tendermint/tendermint/common", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/go-crypto", + "Rev": "32b3a27a9a7a4c3c94c406cc10fc7749e639bdd3" }, { - "ImportPath": "github.com/tendermint/tendermint/config", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/go-db", + "Rev": "28d39f8726c76b163e881c3d05dad227c93200ae" }, { - "ImportPath": "github.com/tendermint/tendermint/consensus", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/go-logger", + "Rev": "b072ed317354e6b507d6abde4c0cfbb516f31ab5" }, { - "ImportPath": "github.com/tendermint/tendermint/db", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/go-merkle", + "Rev": "57679f46d7faf8017d112f6948bd605a83094c1f" }, { - "ImportPath": "github.com/tendermint/tendermint/events", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/go-p2p", + "Rev": "4347b91b89fb93bf37e1d233468f0d879df941ba" }, { - "ImportPath": "github.com/tendermint/tendermint/logger", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/go-wire", + "Rev": "7effba5ee3e0c4ca611f9e0227843c863d05cd02" }, { - "ImportPath": "github.com/tendermint/tendermint/mempool", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/log15", + "Comment": "v2.3-36-gc65281b", + "Rev": "c65281bb703b7612f60558e75b07c434c06e2636" }, { - "ImportPath": "github.com/tendermint/tendermint/merkle", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/tendermint/alert", + "Comment": "0.2-19-g12c7f00", + "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" }, { - "ImportPath": "github.com/tendermint/tendermint/node", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "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/p2p", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "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/permission/types", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/tendermint/proxy", + "Comment": "0.2-19-g12c7f00", + "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" }, { "ImportPath": "github.com/tendermint/tendermint/rpc", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "Comment": "0.2-19-g12c7f00", + "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" }, { "ImportPath": "github.com/tendermint/tendermint/state", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "Comment": "0.2-19-g12c7f00", + "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" }, { "ImportPath": "github.com/tendermint/tendermint/types", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "Comment": "0.2-19-g12c7f00", + "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" }, { - "ImportPath": "github.com/tendermint/tendermint/vm", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/tmsp/server", + "Rev": "1b7ca808beb0d1be7bc9a606f6aa46cc1f65fd93" }, { - "ImportPath": "github.com/tendermint/tendermint/wire", - "Comment": "0.1-26-g85d5b16", - "Rev": "85d5b16dbc610a6a27f6c3d4ece0316907babec6" + "ImportPath": "github.com/tendermint/tmsp/types", + "Rev": "1b7ca808beb0d1be7bc9a606f6aa46cc1f65fd93" }, { "ImportPath": "github.com/tommy351/gin-cors", @@ -191,35 +199,35 @@ }, { "ImportPath": "golang.org/x/crypto/curve25519", - "Rev": "4d8f0cfeca8290cfc0091edf678a138ce669b1bb" + "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" }, { "ImportPath": "golang.org/x/crypto/nacl/box", - "Rev": "4d8f0cfeca8290cfc0091edf678a138ce669b1bb" + "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" }, { "ImportPath": "golang.org/x/crypto/nacl/secretbox", - "Rev": "4d8f0cfeca8290cfc0091edf678a138ce669b1bb" + "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" }, { "ImportPath": "golang.org/x/crypto/poly1305", - "Rev": "4d8f0cfeca8290cfc0091edf678a138ce669b1bb" + "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" }, { "ImportPath": "golang.org/x/crypto/ripemd160", - "Rev": "4d8f0cfeca8290cfc0091edf678a138ce669b1bb" + "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" }, { "ImportPath": "golang.org/x/crypto/salsa20/salsa", - "Rev": "4d8f0cfeca8290cfc0091edf678a138ce669b1bb" + "Rev": "4ed45ec682102c643324fae5dff8dab085b6c300" }, { "ImportPath": "golang.org/x/net/context", - "Rev": "10576091dc82c9c109dddfb5ed77bdbbc87a9af8" + "Rev": "e0403b4e005737430c05a57aac078479844f919c" }, { "ImportPath": "golang.org/x/net/netutil", - "Rev": "10576091dc82c9c109dddfb5ed77bdbbc87a9af8" + "Rev": "e0403b4e005737430c05a57aac078479844f919c" }, { "ImportPath": "gopkg.in/bluesuncorp/validator.v5", diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/auth_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/auth_test.go index b22d9ced..8fc2f233 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/auth_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/auth_test.go @@ -10,7 +10,7 @@ import ( "net/http/httptest" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) func TestBasicAuth(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/binding_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/binding_test.go index db1678e4..8c25afd9 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/binding_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/binding_test.go @@ -9,7 +9,7 @@ import ( "net/http" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) type FooStruct struct { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/default_validator.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/default_validator.go index 7f12152b..d5a6f2e9 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/default_validator.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/default_validator.go @@ -4,7 +4,7 @@ import ( "reflect" "sync" - "gopkg.in/bluesuncorp/validator.v5" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/gopkg.in/bluesuncorp/validator.v5" ) type defaultValidator struct { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/validate_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/validate_test.go index 27ba7b66..8ab0bc52 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/validate_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/binding/validate_test.go @@ -7,7 +7,7 @@ package binding import ( "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) type struct1 struct { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/context.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/context.go index f5f0de4a..a5e946cc 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/context.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/context.go @@ -12,10 +12,10 @@ import ( "strings" "time" - "github.com/gin-gonic/gin/binding" - "github.com/gin-gonic/gin/render" - "github.com/manucorporat/sse" - "golang.org/x/net/context" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin/binding" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin/render" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/manucorporat/sse" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/net/context" ) const ( diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/context_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/context_test.go index a638d6dd..9e9f3dda 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/context_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/context_test.go @@ -14,8 +14,8 @@ import ( "testing" "time" - "github.com/manucorporat/sse" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/manucorporat/sse" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) // Unit tests TODO diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/debug_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/debug_test.go index 425aff0f..ea589616 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/debug_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/debug_test.go @@ -12,7 +12,7 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) // TODO diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/errors_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/errors_test.go index 748e3fe0..aa7cc3dd 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/errors_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/errors_test.go @@ -9,7 +9,7 @@ import ( "errors" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) func TestError(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/hello.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/hello.go index a5e17962..2b098410 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/hello.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/app-engine/hello.go @@ -1,7 +1,7 @@ package hello import ( - "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" "net/http" ) diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/basic/main.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/basic/main.go index 80f2bd3c..b0f1ece7 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/basic/main.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/basic/main.go @@ -1,7 +1,7 @@ package main import ( - "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" ) var DB = make(map[string]string) diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/main.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/main.go index 1f3c8585..538cea74 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/main.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/main.go @@ -4,7 +4,7 @@ import ( "fmt" "runtime" - "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" ) func main() { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/routes.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/routes.go index b1877565..cc7c0087 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/routes.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-advanced/routes.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" ) func rateLimit(c *gin.Context) { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/main.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/main.go index e4b55a0f..8f7f473f 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/main.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/examples/realtime-chat/main.go @@ -5,7 +5,7 @@ import ( "io" "math/rand" - "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" ) func main() { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/gin.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/gin.go index e18d5b6d..05369c61 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/gin.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/gin.go @@ -11,7 +11,7 @@ import ( "os" "sync" - "github.com/gin-gonic/gin/render" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin/render" ) const Version = "v1.0rc2" diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/gin_integration_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/gin_integration_test.go index f7ae0758..fe2fe754 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/gin_integration_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/gin_integration_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) func TestRun(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/gin_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/gin_test.go index fc9e8212..96cbf572 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/gin_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/gin_test.go @@ -8,7 +8,7 @@ import ( "reflect" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) //TODO diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/githubapi_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/githubapi_test.go index 2227fa6a..fe232824 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/githubapi_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/githubapi_test.go @@ -12,7 +12,7 @@ import ( "net/http/httptest" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) type route struct { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/logger_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/logger_test.go index 1cdaa94c..1d4755ec 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/logger_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/logger_test.go @@ -8,7 +8,7 @@ import ( "bytes" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) //TODO diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/middleware_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/middleware_test.go index 7876c7ef..8af80d33 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/middleware_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/middleware_test.go @@ -9,8 +9,8 @@ import ( "testing" - "github.com/manucorporat/sse" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/manucorporat/sse" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) func TestMiddlewareGeneralCase(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/mode.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/mode.go index 15efaeb8..5dcf4e85 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/mode.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/mode.go @@ -8,8 +8,8 @@ import ( "io" "os" - "github.com/gin-gonic/gin/binding" - "github.com/mattn/go-colorable" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin/binding" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/mattn/go-colorable" ) const ENV_GIN_MODE = "GIN_MODE" diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/mode_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/mode_test.go index 2a23d85e..8fd7a43b 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/mode_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/mode_test.go @@ -7,7 +7,7 @@ package gin import ( "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) func init() { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/path_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/path_test.go index 01cb758a..16eb439b 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/path_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/path_test.go @@ -9,7 +9,7 @@ import ( "runtime" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) var cleanTests = []struct { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/recovery_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/recovery_test.go index 39e71e81..aae0ef2c 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/recovery_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/recovery_test.go @@ -8,7 +8,7 @@ import ( "bytes" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) // TestPanicInHandler assert that panic has been recovered. diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/render/render_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/render/render_test.go index 7a6ffb7d..8be5220c 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/render/render_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/render/render_test.go @@ -10,7 +10,7 @@ import ( "net/http/httptest" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) // TODO unit tests diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/response_writer_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/response_writer_test.go index 7306d192..ec7133a8 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/response_writer_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/response_writer_test.go @@ -9,7 +9,7 @@ import ( "net/http/httptest" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) // TODO diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/routergroup_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/routergroup_test.go index 14c7421b..67f7f8e6 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/routergroup_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/routergroup_test.go @@ -7,7 +7,7 @@ package gin import ( "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) func init() { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/routes_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/routes_test.go index 2f451f84..3f5d23ed 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/routes_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/routes_test.go @@ -13,7 +13,7 @@ import ( "path/filepath" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) func performRequest(r http.Handler, method, path string) *httptest.ResponseRecorder { diff --git a/Godeps/_workspace/src/github.com/gin-gonic/gin/utils_test.go b/Godeps/_workspace/src/github.com/gin-gonic/gin/utils_test.go index ba0cc20d..e2fcf4f4 100644 --- a/Godeps/_workspace/src/github.com/gin-gonic/gin/utils_test.go +++ b/Godeps/_workspace/src/github.com/gin-gonic/gin/utils_test.go @@ -9,7 +9,7 @@ import ( "net/http" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) func init() { diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go index d96ac84d..b7eed0da 100644 --- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/server.go @@ -8,7 +8,7 @@ package main import ( "errors" "flag" - "github.com/gorilla/websocket" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gorilla/websocket" "io" "log" "net/http" diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go index 7cc0496c..00b4645a 100644 --- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/conn.go @@ -5,7 +5,7 @@ package main import ( - "github.com/gorilla/websocket" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gorilla/websocket" "log" "net/http" "time" diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go index a2c7b85f..37d7433e 100644 --- a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go +++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/main.go @@ -14,7 +14,7 @@ import ( "text/template" "time" - "github.com/gorilla/websocket" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gorilla/websocket" ) const ( diff --git a/Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_test.go b/Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_test.go index 52371b1e..64cd7d08 100644 --- a/Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_test.go +++ b/Godeps/_workspace/src/github.com/inconshreveable/log15/stack/stack_test.go @@ -9,7 +9,7 @@ import ( "runtime" "testing" - "github.com/inconshreveable/log15/stack" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/inconshreveable/log15/stack" ) type testType struct{} diff --git a/Godeps/_workspace/src/github.com/manucorporat/sse/sse_test.go b/Godeps/_workspace/src/github.com/manucorporat/sse/sse_test.go index b1c2d9bc..f1e15440 100644 --- a/Godeps/_workspace/src/github.com/manucorporat/sse/sse_test.go +++ b/Godeps/_workspace/src/github.com/manucorporat/sse/sse_test.go @@ -9,7 +9,7 @@ import ( "net/http/httptest" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) func TestEncodeOnlyData(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_bench_test.go b/Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_bench_test.go index 90c280bd..9e9dbc45 100644 --- a/Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_bench_test.go +++ b/Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_bench_test.go @@ -3,7 +3,7 @@ package stringutil_test import ( "testing" - "github.com/naoina/go-stringutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/go-stringutil" ) var benchcaseForCamelCase = "the_quick_brown_fox_jumps_over_the_lazy_dog" diff --git a/Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_test.go b/Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_test.go index 69c831e1..89384c2c 100644 --- a/Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_test.go +++ b/Godeps/_workspace/src/github.com/naoina/go-stringutil/strings_test.go @@ -4,7 +4,7 @@ import ( "reflect" "testing" - "github.com/naoina/go-stringutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/go-stringutil" ) func TestToUpperCamelCase(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/naoina/toml/decode.go b/Godeps/_workspace/src/github.com/naoina/toml/decode.go index c5446fe9..d9cb8624 100644 --- a/Godeps/_workspace/src/github.com/naoina/toml/decode.go +++ b/Godeps/_workspace/src/github.com/naoina/toml/decode.go @@ -8,7 +8,7 @@ import ( "strconv" "strings" - "github.com/naoina/toml/ast" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/toml/ast" ) const ( diff --git a/Godeps/_workspace/src/github.com/naoina/toml/decode_bench_test.go b/Godeps/_workspace/src/github.com/naoina/toml/decode_bench_test.go index b85c1c68..94ffdfb3 100644 --- a/Godeps/_workspace/src/github.com/naoina/toml/decode_bench_test.go +++ b/Godeps/_workspace/src/github.com/naoina/toml/decode_bench_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/naoina/toml" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/toml" ) func BenchmarkUnmarshal(b *testing.B) { diff --git a/Godeps/_workspace/src/github.com/naoina/toml/decode_test.go b/Godeps/_workspace/src/github.com/naoina/toml/decode_test.go index 1fcae9b7..17dd2e79 100644 --- a/Godeps/_workspace/src/github.com/naoina/toml/decode_test.go +++ b/Godeps/_workspace/src/github.com/naoina/toml/decode_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/naoina/toml" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/toml" ) const ( diff --git a/Godeps/_workspace/src/github.com/naoina/toml/encode.go b/Godeps/_workspace/src/github.com/naoina/toml/encode.go index 1932538e..94302f44 100644 --- a/Godeps/_workspace/src/github.com/naoina/toml/encode.go +++ b/Godeps/_workspace/src/github.com/naoina/toml/encode.go @@ -9,7 +9,7 @@ import ( "go/ast" - "github.com/naoina/go-stringutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/go-stringutil" ) const ( diff --git a/Godeps/_workspace/src/github.com/naoina/toml/encode_test.go b/Godeps/_workspace/src/github.com/naoina/toml/encode_test.go index 17e04fd0..3445c879 100644 --- a/Godeps/_workspace/src/github.com/naoina/toml/encode_test.go +++ b/Godeps/_workspace/src/github.com/naoina/toml/encode_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/naoina/toml" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/toml" ) func TestMarshal(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/naoina/toml/parse.go b/Godeps/_workspace/src/github.com/naoina/toml/parse.go index e0186662..f7a3c83c 100644 --- a/Godeps/_workspace/src/github.com/naoina/toml/parse.go +++ b/Godeps/_workspace/src/github.com/naoina/toml/parse.go @@ -3,7 +3,7 @@ package toml import ( "fmt" - "github.com/naoina/toml/ast" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/toml/ast" ) // Parse returns an AST representation of TOML. diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/require/forward_requirements.go b/Godeps/_workspace/src/github.com/stretchr/testify/require/forward_requirements.go index 069d4198..62c75b9c 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/require/forward_requirements.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/require/forward_requirements.go @@ -3,7 +3,7 @@ package require import ( "time" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) type Assertions struct { diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/require/requirements.go b/Godeps/_workspace/src/github.com/stretchr/testify/require/requirements.go index 122a3f3a..6b10a611 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/require/requirements.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/require/requirements.go @@ -3,7 +3,7 @@ package require import ( "time" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) type TestingT interface { diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/suite/suite.go b/Godeps/_workspace/src/github.com/stretchr/testify/suite/suite.go index ac6744d4..4dbe6eca 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/suite/suite.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/suite/suite.go @@ -8,8 +8,8 @@ import ( "regexp" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "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/stretchr/testify/require" ) var matchMethod = flag.String("m", "", "regular expression to select tests of the suite to run") diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/suite/suite_test.go b/Godeps/_workspace/src/github.com/stretchr/testify/suite/suite_test.go index 6a1bb2c6..630c5869 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/suite/suite_test.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/suite/suite_test.go @@ -6,7 +6,7 @@ import ( "os" "testing" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ) // This suite is intended to store values to make sure that only diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch.go index ccf390c9..354ebe4f 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch.go @@ -10,8 +10,8 @@ import ( "encoding/binary" "fmt" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/memdb" + "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/memdb" ) type ErrBatchCorrupted struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch_test.go index 7fc842f4..e98b683c 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/batch_test.go @@ -10,8 +10,8 @@ import ( "bytes" "testing" - "github.com/syndtr/goleveldb/leveldb/comparer" - "github.com/syndtr/goleveldb/leveldb/memdb" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb" ) type tbRec struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go index 91b42670..621e52db 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/bench_test.go @@ -15,9 +15,9 @@ import ( "runtime" "testing" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "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/syndtr/goleveldb/leveldb/storage" ) func randomString(r *rand.Rand, n int) []byte { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache.go index c9670de5..9ae49931 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache/cache.go @@ -12,7 +12,7 @@ import ( "sync/atomic" "unsafe" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) // Cacher provides interface to implements a caching functionality. diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer.go index d33d5e9c..6e57fab7 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer.go @@ -6,7 +6,7 @@ package leveldb -import "github.com/syndtr/goleveldb/leveldb/comparer" +import "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" type iComparer struct { ucmp comparer.Comparer diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/corrupt_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/corrupt_test.go index a351874e..f1ef0743 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/corrupt_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/corrupt_test.go @@ -9,9 +9,9 @@ package leveldb import ( "bytes" "fmt" - "github.com/syndtr/goleveldb/leveldb/filter" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter" + "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/syndtr/goleveldb/leveldb/storage" "io" "math/rand" "testing" diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db.go index def86bc1..5e03cc33 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db.go @@ -17,14 +17,14 @@ import ( "sync/atomic" "time" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/journal" - "github.com/syndtr/goleveldb/leveldb/memdb" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/storage" - "github.com/syndtr/goleveldb/leveldb/table" - "github.com/syndtr/goleveldb/leveldb/util" + "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/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/journal" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb" + "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/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) // DB is a LevelDB database. @@ -63,14 +63,13 @@ type DB struct { journalAckC chan error // Compaction. - tcompCmdC chan cCmd - tcompPauseC chan chan<- struct{} - mcompCmdC chan cCmd - compErrC chan error - compPerErrC chan error - compErrSetC chan error - compWriteLocking bool - compStats []cStats + tcompCmdC chan cCmd + tcompPauseC chan chan<- struct{} + mcompCmdC chan cCmd + compErrC chan error + compPerErrC chan error + compErrSetC chan error + compStats []cStats // Close. closeW sync.WaitGroup @@ -109,44 +108,28 @@ func openDB(s *session) (*DB, error) { closeC: make(chan struct{}), } - // Read-only mode. - readOnly := s.o.GetReadOnly() - - if readOnly { - // Recover journals (read-only mode). - if err := db.recoverJournalRO(); err != nil { - return nil, err - } - } else { - // Recover journals. - if err := db.recoverJournal(); err != nil { - return nil, err - } + if err := db.recoverJournal(); err != nil { + return nil, err + } - // Remove any obsolete files. - if err := db.checkAndCleanFiles(); err != nil { - // Close journal. - if db.journal != nil { - db.journal.Close() - db.journalWriter.Close() - } - return nil, err + // Remove any obsolete files. + if err := db.checkAndCleanFiles(); err != nil { + // Close journal. + if db.journal != nil { + db.journal.Close() + db.journalWriter.Close() } - + return nil, err } // Doesn't need to be included in the wait group. go db.compactionError() go db.mpoolDrain() - if readOnly { - db.SetReadOnly() - } else { - db.closeW.Add(3) - go db.tCompaction() - go db.mCompaction() - go db.jWriter() - } + db.closeW.Add(3) + go db.tCompaction() + go db.mCompaction() + go db.jWriter() s.logf("db@open done T·%v", time.Since(start)) @@ -292,7 +275,7 @@ func recoverTable(s *session, o *opt.Options) error { // We will drop corrupted table. strict = o.GetStrict(opt.StrictRecovery) - rec = &sessionRecord{} + rec = &sessionRecord{numLevel: o.GetNumLevel()} bpool = util.NewBufferPool(o.GetBlockSize() + 5) ) buildTable := func(iter iterator.Iterator) (tmp storage.File, size int64, err error) { @@ -467,136 +450,132 @@ func recoverTable(s *session, o *opt.Options) error { } func (db *DB) recoverJournal() error { - // Get all journals and sort it by file number. - allJournalFiles, err := db.s.getFiles(storage.TypeJournal) + // Get all tables and sort it by file number. + journalFiles_, err := db.s.getFiles(storage.TypeJournal) if err != nil { return err } - files(allJournalFiles).sort() + journalFiles := files(journalFiles_) + journalFiles.sort() - // Journals that will be recovered. - var recJournalFiles []storage.File - for _, jf := range allJournalFiles { - if jf.Num() >= db.s.stJournalNum || jf.Num() == db.s.stPrevJournalNum { - recJournalFiles = append(recJournalFiles, jf) + // Discard older journal. + prev := -1 + for i, file := range journalFiles { + if file.Num() >= db.s.stJournalNum { + if prev >= 0 { + i-- + journalFiles[i] = journalFiles[prev] + } + journalFiles = journalFiles[i:] + break + } else if file.Num() == db.s.stPrevJournalNum { + prev = i + } + } + + var jr *journal.Reader + var of storage.File + var mem *memdb.DB + batch := new(Batch) + cm := newCMem(db.s) + buf := new(util.Buffer) + // Options. + strict := db.s.o.GetStrict(opt.StrictJournal) + checksum := db.s.o.GetStrict(opt.StrictJournalChecksum) + writeBuffer := db.s.o.GetWriteBuffer() + recoverJournal := func(file storage.File) error { + db.logf("journal@recovery recovering @%d", file.Num()) + reader, err := file.Open() + if err != nil { + return err } - } + defer reader.Close() - var ( - of storage.File // Obsolete file. - rec = &sessionRecord{} - ) - - // Recover journals. - if len(recJournalFiles) > 0 { - db.logf("journal@recovery F·%d", len(recJournalFiles)) - - // Mark file number as used. - db.s.markFileNum(recJournalFiles[len(recJournalFiles)-1].Num()) - - var ( - // Options. - strict = db.s.o.GetStrict(opt.StrictJournal) - checksum = db.s.o.GetStrict(opt.StrictJournalChecksum) - writeBuffer = db.s.o.GetWriteBuffer() - - jr *journal.Reader - mdb = memdb.New(db.s.icmp, writeBuffer) - buf = &util.Buffer{} - batch = &Batch{} - ) - - for _, jf := range recJournalFiles { - db.logf("journal@recovery recovering @%d", jf.Num()) + // Create/reset journal reader instance. + if jr == nil { + jr = journal.NewReader(reader, dropper{db.s, file}, strict, checksum) + } else { + jr.Reset(reader, dropper{db.s, file}, strict, checksum) + } - fr, err := jf.Open() - if err != nil { + // Flush memdb and remove obsolete journal file. + if of != nil { + if mem.Len() > 0 { + if err := cm.flush(mem, 0); err != nil { + return err + } + } + if err := cm.commit(file.Num(), db.seq); err != nil { return err } + cm.reset() + of.Remove() + of = nil + } - // Create or reset journal reader instance. - if jr == nil { - jr = journal.NewReader(fr, dropper{db.s, jf}, strict, checksum) - } else { - jr.Reset(fr, dropper{db.s, jf}, strict, checksum) + // Replay journal to memdb. + mem.Reset() + for { + r, err := jr.Next() + if err != nil { + if err == io.EOF { + break + } + return errors.SetFile(err, file) } - // Flush memdb and remove obsolete journal file. - if of != nil { - if mdb.Len() > 0 { - if _, err := db.s.flushMemdb(rec, mdb, -1); err != nil { - fr.Close() - return err - } + buf.Reset() + if _, err := buf.ReadFrom(r); err != nil { + if err == io.ErrUnexpectedEOF { + // This is error returned due to corruption, with strict == false. + continue + } else { + return errors.SetFile(err, file) } - - rec.setJournalNum(jf.Num()) - rec.setSeqNum(db.seq) - if err := db.s.commit(rec); err != nil { - fr.Close() - return err + } + if err := batch.memDecodeAndReplay(db.seq, buf.Bytes(), mem); err != nil { + if strict || !errors.IsCorrupted(err) { + return errors.SetFile(err, file) + } else { + db.s.logf("journal error: %v (skipped)", err) + // We won't apply sequence number as it might be corrupted. + continue } - rec.resetAddedTables() - - of.Remove() - of = nil } - // Replay journal to memdb. - mdb.Reset() - for { - r, err := jr.Next() - if err != nil { - if err == io.EOF { - break - } + // Save sequence number. + db.seq = batch.seq + uint64(batch.Len()) - fr.Close() - return errors.SetFile(err, jf) + // Flush it if large enough. + if mem.Size() >= writeBuffer { + if err := cm.flush(mem, 0); err != nil { + return err } + mem.Reset() + } + } - buf.Reset() - if _, err := buf.ReadFrom(r); err != nil { - if err == io.ErrUnexpectedEOF { - // This is error returned due to corruption, with strict == false. - continue - } - - fr.Close() - return errors.SetFile(err, jf) - } - if err := batch.memDecodeAndReplay(db.seq, buf.Bytes(), mdb); err != nil { - if !strict && errors.IsCorrupted(err) { - db.s.logf("journal error: %v (skipped)", err) - // We won't apply sequence number as it might be corrupted. - continue - } - - fr.Close() - return errors.SetFile(err, jf) - } + of = file + return nil + } - // Save sequence number. - db.seq = batch.seq + uint64(batch.Len()) + // Recover all journals. + if len(journalFiles) > 0 { + db.logf("journal@recovery F·%d", len(journalFiles)) - // Flush it if large enough. - if mdb.Size() >= writeBuffer { - if _, err := db.s.flushMemdb(rec, mdb, 0); err != nil { - fr.Close() - return err - } + // Mark file number as used. + db.s.markFileNum(journalFiles[len(journalFiles)-1].Num()) - mdb.Reset() - } + mem = memdb.New(db.s.icmp, writeBuffer) + for _, file := range journalFiles { + if err := recoverJournal(file); err != nil { + return err } - - fr.Close() - of = jf } - // Flush the last memdb. - if mdb.Len() > 0 { - if _, err := db.s.flushMemdb(rec, mdb, 0); err != nil { + // Flush the last journal. + if mem.Len() > 0 { + if err := cm.flush(mem, 0); err != nil { return err } } @@ -608,10 +587,8 @@ func (db *DB) recoverJournal() error { } // Commit. - rec.setJournalNum(db.journalFile.Num()) - rec.setSeqNum(db.seq) - if err := db.s.commit(rec); err != nil { - // Close journal on error. + if err := cm.commit(db.journalFile.Num(), db.seq); err != nil { + // Close journal. if db.journal != nil { db.journal.Close() db.journalWriter.Close() @@ -627,103 +604,6 @@ func (db *DB) recoverJournal() error { return nil } -func (db *DB) recoverJournalRO() error { - // Get all journals and sort it by file number. - allJournalFiles, err := db.s.getFiles(storage.TypeJournal) - if err != nil { - return err - } - files(allJournalFiles).sort() - - // Journals that will be recovered. - var recJournalFiles []storage.File - for _, jf := range allJournalFiles { - if jf.Num() >= db.s.stJournalNum || jf.Num() == db.s.stPrevJournalNum { - recJournalFiles = append(recJournalFiles, jf) - } - } - - var ( - // Options. - strict = db.s.o.GetStrict(opt.StrictJournal) - checksum = db.s.o.GetStrict(opt.StrictJournalChecksum) - writeBuffer = db.s.o.GetWriteBuffer() - - mdb = memdb.New(db.s.icmp, writeBuffer) - ) - - // Recover journals. - if len(recJournalFiles) > 0 { - db.logf("journal@recovery RO·Mode F·%d", len(recJournalFiles)) - - var ( - jr *journal.Reader - buf = &util.Buffer{} - batch = &Batch{} - ) - - for _, jf := range recJournalFiles { - db.logf("journal@recovery recovering @%d", jf.Num()) - - fr, err := jf.Open() - if err != nil { - return err - } - - // Create or reset journal reader instance. - if jr == nil { - jr = journal.NewReader(fr, dropper{db.s, jf}, strict, checksum) - } else { - jr.Reset(fr, dropper{db.s, jf}, strict, checksum) - } - - // Replay journal to memdb. - for { - r, err := jr.Next() - if err != nil { - if err == io.EOF { - break - } - - fr.Close() - return errors.SetFile(err, jf) - } - - buf.Reset() - if _, err := buf.ReadFrom(r); err != nil { - if err == io.ErrUnexpectedEOF { - // This is error returned due to corruption, with strict == false. - continue - } - - fr.Close() - return errors.SetFile(err, jf) - } - if err := batch.memDecodeAndReplay(db.seq, buf.Bytes(), mdb); err != nil { - if !strict && errors.IsCorrupted(err) { - db.s.logf("journal error: %v (skipped)", err) - // We won't apply sequence number as it might be corrupted. - continue - } - - fr.Close() - return errors.SetFile(err, jf) - } - - // Save sequence number. - db.seq = batch.seq + uint64(batch.Len()) - } - - fr.Close() - } - } - - // Set memDB. - db.mem = &memDB{db: db, DB: mdb, ref: 1} - - return nil -} - func (db *DB) get(key []byte, seq uint64, ro *opt.ReadOptions) (value []byte, err error) { ikey := newIkey(key, seq, ktSeek) @@ -734,7 +614,7 @@ func (db *DB) get(key []byte, seq uint64, ro *opt.ReadOptions) (value []byte, er } defer m.decref() - mk, mv, me := m.Find(ikey) + mk, mv, me := m.mdb.Find(ikey) if me == nil { ukey, _, kt, kerr := parseIkey(mk) if kerr != nil { @@ -772,7 +652,7 @@ func (db *DB) has(key []byte, seq uint64, ro *opt.ReadOptions) (ret bool, err er } defer m.decref() - mk, _, me := m.Find(ikey) + mk, _, me := m.mdb.Find(ikey) if me == nil { ukey, _, kt, kerr := parseIkey(mk) if kerr != nil { @@ -904,7 +784,7 @@ func (db *DB) GetProperty(name string) (value string, err error) { const prefix = "leveldb." if !strings.HasPrefix(name, prefix) { - return "", ErrNotFound + return "", errors.New("leveldb: GetProperty: unknown property: " + name) } p := name[len(prefix):] @@ -918,7 +798,7 @@ func (db *DB) GetProperty(name string) (value string, err error) { var rest string n, _ := fmt.Sscanf(p[len(numFilesPrefix):], "%d%s", &level, &rest) if n != 1 || int(level) >= db.s.o.GetNumLevel() { - err = ErrNotFound + err = errors.New("leveldb: GetProperty: invalid property: " + name) } else { value = fmt.Sprint(v.tLen(int(level))) } @@ -957,7 +837,7 @@ func (db *DB) GetProperty(name string) (value string, err error) { case p == "aliveiters": value = fmt.Sprintf("%d", atomic.LoadInt32(&db.aliveIters)) default: - err = ErrNotFound + err = errors.New("leveldb: GetProperty: unknown property: " + name) } return @@ -1020,9 +900,6 @@ func (db *DB) Close() error { var err error select { case err = <-db.compErrC: - if err == ErrReadOnly { - err = nil - } default: } diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_compaction.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_compaction.go index 26003106..2f14a588 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_compaction.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_compaction.go @@ -10,8 +10,9 @@ import ( "sync" "time" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/opt" + "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/memdb" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt" ) var ( @@ -61,8 +62,58 @@ func (p *cStatsStaging) stopTimer() { } } +type cMem struct { + s *session + level int + rec *sessionRecord +} + +func newCMem(s *session) *cMem { + return &cMem{s: s, rec: &sessionRecord{numLevel: s.o.GetNumLevel()}} +} + +func (c *cMem) flush(mem *memdb.DB, level int) error { + s := c.s + + // Write memdb to table. + iter := mem.NewIterator(nil) + defer iter.Release() + t, n, err := s.tops.createFrom(iter) + if err != nil { + return err + } + + // Pick level. + if level < 0 { + v := s.version() + level = v.pickLevel(t.imin.ukey(), t.imax.ukey()) + v.release() + } + c.rec.addTableFile(level, t) + + s.logf("mem@flush created L%d@%d N·%d S·%s %q:%q", level, t.file.Num(), n, shortenb(int(t.size)), t.imin, t.imax) + + c.level = level + return nil +} + +func (c *cMem) reset() { + c.rec = &sessionRecord{numLevel: c.s.o.GetNumLevel()} +} + +func (c *cMem) commit(journal, seq uint64) error { + c.rec.setJournalNum(journal) + c.rec.setSeqNum(seq) + + // Commit changes. + return c.s.commit(c.rec) +} + func (db *DB) compactionError() { - var err error + var ( + err error + wlocked bool + ) noerr: // No error. for { @@ -70,7 +121,7 @@ noerr: case err = <-db.compErrSetC: switch { case err == nil: - case err == ErrReadOnly, errors.IsCorrupted(err): + case errors.IsCorrupted(err): goto hasperr default: goto haserr @@ -88,7 +139,7 @@ haserr: switch { case err == nil: goto noerr - case err == ErrReadOnly, errors.IsCorrupted(err): + case errors.IsCorrupted(err): goto hasperr default: } @@ -104,9 +155,9 @@ hasperr: case db.compPerErrC <- err: case db.writeLockC <- struct{}{}: // Hold write lock, so that write won't pass-through. - db.compWriteLocking = true + wlocked = true case _, _ = <-db.closeC: - if db.compWriteLocking { + if wlocked { // We should release the lock or Close will hang. <-db.writeLockC } @@ -236,18 +287,21 @@ func (db *DB) compactionExitTransact() { } func (db *DB) memCompaction() { - mdb := db.getFrozenMem() - if mdb == nil { + mem := db.getFrozenMem() + if mem == nil { return } - defer mdb.decref() + defer mem.decref() + + c := newCMem(db.s) + stats := new(cStatsStaging) - db.logf("memdb@flush N·%d S·%s", mdb.Len(), shortenb(mdb.Size())) + db.logf("mem@flush N·%d S·%s", mem.mdb.Len(), shortenb(mem.mdb.Size())) // Don't compact empty memdb. - if mdb.Len() == 0 { - db.logf("memdb@flush skipping") - // drop frozen memdb + if mem.mdb.Len() == 0 { + db.logf("mem@flush skipping") + // drop frozen mem db.dropFrozenMem() return } @@ -263,20 +317,13 @@ func (db *DB) memCompaction() { return } - var ( - rec = &sessionRecord{} - stats = &cStatsStaging{} - flushLevel int - ) - - db.compactionTransactFunc("memdb@flush", func(cnt *compactionTransactCounter) (err error) { + db.compactionTransactFunc("mem@flush", func(cnt *compactionTransactCounter) (err error) { stats.startTimer() - flushLevel, err = db.s.flushMemdb(rec, mdb.DB, -1) - stats.stopTimer() - return + defer stats.stopTimer() + return c.flush(mem.mdb, -1) }, func() error { - for _, r := range rec.addedTables { - db.logf("memdb@flush revert @%d", r.num) + for _, r := range c.rec.addedTables { + db.logf("mem@flush revert @%d", r.num) f := db.s.getTableFile(r.num) if err := f.Remove(); err != nil { return err @@ -285,23 +332,20 @@ func (db *DB) memCompaction() { return nil }) - db.compactionTransactFunc("memdb@commit", func(cnt *compactionTransactCounter) (err error) { + db.compactionTransactFunc("mem@commit", func(cnt *compactionTransactCounter) (err error) { stats.startTimer() - rec.setJournalNum(db.journalFile.Num()) - rec.setSeqNum(db.frozenSeq) - err = db.s.commit(rec) - stats.stopTimer() - return + defer stats.stopTimer() + return c.commit(db.journalFile.Num(), db.frozenSeq) }, nil) - db.logf("memdb@flush committed F·%d T·%v", len(rec.addedTables), stats.duration) + db.logf("mem@flush committed F·%d T·%v", len(c.rec.addedTables), stats.duration) - for _, r := range rec.addedTables { + for _, r := range c.rec.addedTables { stats.write += r.size } - db.compStats[flushLevel].add(stats) + db.compStats[c.level].add(stats) - // Drop frozen memdb. + // Drop frozen mem. db.dropFrozenMem() // Resume table compaction. @@ -513,7 +557,7 @@ func (b *tableCompactionBuilder) revert() error { func (db *DB) tableCompaction(c *compaction, noTrivial bool) { defer c.release() - rec := &sessionRecord{} + rec := &sessionRecord{numLevel: db.s.o.GetNumLevel()} rec.addCompPtr(c.level, c.imax) if !noTrivial && c.trivial() { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_iter.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_iter.go index 656ae985..884598d4 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_iter.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_iter.go @@ -13,9 +13,9 @@ import ( "sync" "sync/atomic" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "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/syndtr/goleveldb/leveldb/util" ) var ( @@ -40,11 +40,11 @@ func (db *DB) newRawIterator(slice *util.Range, ro *opt.ReadOptions) iterator.It ti := v.getIterators(slice, ro) n := len(ti) + 2 i := make([]iterator.Iterator, 0, n) - emi := em.NewIterator(slice) + emi := em.mdb.NewIterator(slice) emi.SetReleaser(&memdbReleaser{m: em}) i = append(i, emi) if fm != nil { - fmi := fm.NewIterator(slice) + fmi := fm.mdb.NewIterator(slice) fmi.SetReleaser(&memdbReleaser{m: fm}) i = append(i, fmi) } diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_snapshot.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_snapshot.go index 0372848f..4af74033 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_snapshot.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_snapshot.go @@ -13,9 +13,9 @@ import ( "sync" "sync/atomic" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "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/syndtr/goleveldb/leveldb/util" ) type snapshotElement struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_state.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_state.go index 24671dd3..87421ff2 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_state.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_state.go @@ -10,13 +10,13 @@ import ( "sync/atomic" "time" - "github.com/syndtr/goleveldb/leveldb/journal" - "github.com/syndtr/goleveldb/leveldb/memdb" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/journal" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb" ) type memDB struct { - db *DB - *memdb.DB + db *DB + mdb *memdb.DB ref int32 } @@ -27,12 +27,12 @@ func (m *memDB) incref() { func (m *memDB) decref() { if ref := atomic.AddInt32(&m.ref, -1); ref == 0 { // Only put back memdb with std capacity. - if m.Capacity() == m.db.s.o.GetWriteBuffer() { - m.Reset() - m.db.mpoolPut(m.DB) + if m.mdb.Capacity() == m.db.s.o.GetWriteBuffer() { + m.mdb.Reset() + m.db.mpoolPut(m.mdb) } m.db = nil - m.DB = nil + m.mdb = nil } else if ref < 0 { panic("negative memdb ref") } @@ -126,7 +126,7 @@ func (db *DB) newMem(n int) (mem *memDB, err error) { } mem = &memDB{ db: db, - DB: mdb, + mdb: mdb, ref: 2, } db.mem = mem diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_test.go index 9d91ebf1..1dce7704 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_test.go @@ -23,13 +23,13 @@ import ( "time" "unsafe" - "github.com/syndtr/goleveldb/leveldb/comparer" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/filter" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/storage" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + "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/filter" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "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/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) func tkey(i int) []byte { @@ -2445,7 +2445,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) { if err != nil { t.Fatal(err) } - rec := &sessionRecord{} + rec := &sessionRecord{numLevel: s.o.GetNumLevel()} rec.addTableFile(i, tf) if err := s.commit(rec); err != nil { t.Fatal(err) @@ -2455,7 +2455,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) { // Build grandparent. v := s.version() c := newCompaction(s, v, 1, append(tFiles{}, v.tables[1]...)) - rec := &sessionRecord{} + rec := &sessionRecord{numLevel: s.o.GetNumLevel()} b := &tableCompactionBuilder{ s: s, c: c, @@ -2479,7 +2479,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) { // Build level-1. v = s.version() c = newCompaction(s, v, 0, append(tFiles{}, v.tables[0]...)) - rec = &sessionRecord{} + rec = &sessionRecord{numLevel: s.o.GetNumLevel()} b = &tableCompactionBuilder{ s: s, c: c, @@ -2523,7 +2523,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) { // Compaction with transient error. v = s.version() c = newCompaction(s, v, 1, append(tFiles{}, v.tables[1]...)) - rec = &sessionRecord{} + rec = &sessionRecord{numLevel: s.o.GetNumLevel()} b = &tableCompactionBuilder{ s: s, c: c, @@ -2663,39 +2663,3 @@ func TestDB_IterTriggeredCompaction(t *testing.T) { func TestDB_IterTriggeredCompactionHalf(t *testing.T) { testDB_IterTriggeredCompaction(t, 2) } - -func TestDB_ReadOnly(t *testing.T) { - h := newDbHarness(t) - defer h.close() - - h.put("foo", "v1") - h.put("bar", "v2") - h.compactMem() - - h.put("xfoo", "v1") - h.put("xbar", "v2") - - t.Log("Trigger read-only") - if err := h.db.SetReadOnly(); err != nil { - h.close() - t.Fatalf("SetReadOnly error: %v", err) - } - - h.stor.SetEmuErr(storage.TypeAll, tsOpCreate, tsOpReplace, tsOpRemove, tsOpWrite, tsOpWrite, tsOpSync) - - ro := func(key, value, wantValue string) { - if err := h.db.Put([]byte(key), []byte(value), h.wo); err != ErrReadOnly { - t.Fatalf("unexpected error: %v", err) - } - h.getVal(key, wantValue) - } - - ro("foo", "vx", "v1") - - h.o.ReadOnly = true - h.reopenDB() - - ro("foo", "vx", "v1") - ro("bar", "vx", "v2") - h.assertNumKeys(4) -} diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_util.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_util.go index a8a2bdf7..0cd4a99e 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_util.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_util.go @@ -7,11 +7,11 @@ package leveldb import ( - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/storage" - "github.com/syndtr/goleveldb/leveldb/util" + "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/iterator" + "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/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) // Reader is the interface that wraps basic Get and NewIterator methods. diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_write.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_write.go index 176ee893..0f7ba298 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_write.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/db_write.go @@ -9,9 +9,9 @@ package leveldb import ( "time" - "github.com/syndtr/goleveldb/leveldb/memdb" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb" + "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/syndtr/goleveldb/leveldb/util" ) func (db *DB) writeJournal(b *Batch) error { @@ -63,24 +63,24 @@ func (db *DB) rotateMem(n int) (mem *memDB, err error) { return } -func (db *DB) flush(n int) (mdb *memDB, mdbFree int, err error) { +func (db *DB) flush(n int) (mem *memDB, nn int, err error) { delayed := false flush := func() (retry bool) { v := db.s.version() defer v.release() - mdb = db.getEffectiveMem() + mem = db.getEffectiveMem() defer func() { if retry { - mdb.decref() - mdb = nil + mem.decref() + mem = nil } }() - mdbFree = mdb.Free() + nn = mem.mdb.Free() switch { case v.tLen(0) >= db.s.o.GetWriteL0SlowdownTrigger() && !delayed: delayed = true time.Sleep(time.Millisecond) - case mdbFree >= n: + case nn >= n: return false case v.tLen(0) >= db.s.o.GetWriteL0PauseTrigger(): delayed = true @@ -90,15 +90,15 @@ func (db *DB) flush(n int) (mdb *memDB, mdbFree int, err error) { } default: // Allow memdb to grow if it has no entry. - if mdb.Len() == 0 { - mdbFree = n + if mem.mdb.Len() == 0 { + nn = n } else { - mdb.decref() - mdb, err = db.rotateMem(n) + mem.decref() + mem, err = db.rotateMem(n) if err == nil { - mdbFree = mdb.Free() + nn = mem.mdb.Free() } else { - mdbFree = 0 + nn = 0 } } return false @@ -157,18 +157,18 @@ func (db *DB) Write(b *Batch, wo *opt.WriteOptions) (err error) { } }() - mdb, mdbFree, err := db.flush(b.size()) + mem, memFree, err := db.flush(b.size()) if err != nil { return } - defer mdb.decref() + defer mem.decref() // Calculate maximum size of the batch. m := 1 << 20 if x := b.size(); x <= 128<<10 { m = x + (128 << 10) } - m = minInt(m, mdbFree) + m = minInt(m, memFree) // Merge with other batch. drain: @@ -197,7 +197,7 @@ drain: select { case db.journalC <- b: // Write into memdb - if berr := b.memReplay(mdb.DB); berr != nil { + if berr := b.memReplay(mem.mdb); berr != nil { panic(berr) } case err = <-db.compPerErrC: @@ -211,7 +211,7 @@ drain: case err = <-db.journalAckC: if err != nil { // Revert memdb if error detected - if berr := b.revertMemReplay(mdb.DB); berr != nil { + if berr := b.revertMemReplay(mem.mdb); berr != nil { panic(berr) } return @@ -225,7 +225,7 @@ drain: if err != nil { return } - if berr := b.memReplay(mdb.DB); berr != nil { + if berr := b.memReplay(mem.mdb); berr != nil { panic(berr) } } @@ -233,7 +233,7 @@ drain: // Set last seq number. db.addSeq(uint64(b.Len())) - if b.size() >= mdbFree { + if b.size() >= memFree { db.rotateMem(0) } return @@ -249,7 +249,8 @@ func (db *DB) Put(key, value []byte, wo *opt.WriteOptions) error { return db.Write(b, wo) } -// Delete deletes the value for the given key. +// Delete deletes the value for the given key. It returns ErrNotFound if +// the DB does not contain the key. // // It is safe to modify the contents of the arguments after Delete returns. func (db *DB) Delete(key []byte, wo *opt.WriteOptions) error { @@ -289,9 +290,9 @@ func (db *DB) CompactRange(r util.Range) error { } // Check for overlaps in memdb. - mdb := db.getEffectiveMem() - defer mdb.decref() - if isMemOverlaps(db.s.icmp, mdb.DB, r.Start, r.Limit) { + mem := db.getEffectiveMem() + defer mem.decref() + if isMemOverlaps(db.s.icmp, mem.mdb, r.Start, r.Limit) { // Memdb compaction. if _, err := db.rotateMem(0); err != nil { <-db.writeLockC @@ -308,31 +309,3 @@ func (db *DB) CompactRange(r util.Range) error { // Table compaction. return db.compSendRange(db.tcompCmdC, -1, r.Start, r.Limit) } - -// SetReadOnly makes DB read-only. It will stay read-only until reopened. -func (db *DB) SetReadOnly() error { - if err := db.ok(); err != nil { - return err - } - - // Lock writer. - select { - case db.writeLockC <- struct{}{}: - db.compWriteLocking = true - case err := <-db.compPerErrC: - return err - case _, _ = <-db.closeC: - return ErrClosed - } - - // Set compaction read-only. - select { - case db.compErrSetC <- ErrReadOnly: - case perr := <-db.compPerErrC: - return perr - case _, _ = <-db.closeC: - return ErrClosed - } - - return nil -} diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors.go index c8bd66a5..d5ba7684 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors.go @@ -7,12 +7,11 @@ package leveldb import ( - "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors" ) var ( ErrNotFound = errors.ErrNotFound - ErrReadOnly = errors.New("leveldb: read-only mode") ErrSnapshotReleased = errors.New("leveldb: snapshot released") ErrIterReleased = errors.New("leveldb: iterator released") ErrClosed = errors.New("leveldb: closed") diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors/errors.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors/errors.go index 84b5d6b7..a22b4b9d 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors/errors.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors/errors.go @@ -11,8 +11,8 @@ import ( "errors" "fmt" - "github.com/syndtr/goleveldb/leveldb/storage" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) var ( diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/external_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/external_test.go index b328ece4..8ae2e50e 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/external_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/external_test.go @@ -10,8 +10,8 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/testutil" + "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/syndtr/goleveldb/leveldb/testutil" ) var _ = testutil.Defer(func() { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter.go index 37c1e146..fcad1fbf 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter.go @@ -7,7 +7,7 @@ package leveldb import ( - "github.com/syndtr/goleveldb/leveldb/filter" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter" ) type iFilter struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter/bloom.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter/bloom.go index bab0e997..68c92552 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter/bloom.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter/bloom.go @@ -7,7 +7,7 @@ package filter import ( - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) func bloomHash(key []byte) uint32 { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter/bloom_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter/bloom_test.go index 1fb56f07..70bfdaa5 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter/bloom_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter/bloom_test.go @@ -8,7 +8,7 @@ package filter import ( "encoding/binary" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" "testing" ) diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/array_iter.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/array_iter.go index a23ab05f..3050fb86 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/array_iter.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/array_iter.go @@ -7,7 +7,7 @@ package iterator import ( - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) // BasicArray is the interface that wraps basic Len and Search method. diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/array_iter_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/array_iter_test.go index 1ed6d07c..9c9c27a6 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/array_iter_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/array_iter_test.go @@ -9,8 +9,8 @@ package iterator_test import ( . "github.com/onsi/ginkgo" - . "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/testutil" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil" ) var _ = testutil.Defer(func() { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter.go index 939adbb9..71843607 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter.go @@ -7,8 +7,8 @@ package iterator import ( - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/util" + "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/util" ) // IteratorIndexer is the interface that wraps CommonIterator and basic Get diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter_test.go index 72a79789..8d64ed8b 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter_test.go @@ -11,9 +11,9 @@ import ( . "github.com/onsi/ginkgo" - "github.com/syndtr/goleveldb/leveldb/comparer" - . "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil" ) type keyValue struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/iter.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/iter.go index c2522860..f6876eea 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/iter.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/iter.go @@ -11,7 +11,7 @@ package iterator import ( "errors" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) var ( diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/iter_suite_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/iter_suite_test.go index 5ef8d5ba..3e54f8b1 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/iter_suite_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/iter_suite_test.go @@ -3,7 +3,7 @@ package iterator_test import ( "testing" - "github.com/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil" ) func TestIterator(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter.go index 1a7e29df..df1daffa 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter.go @@ -7,9 +7,9 @@ package iterator import ( - "github.com/syndtr/goleveldb/leveldb/comparer" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + "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/util" ) type dir int diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter_test.go index e523b63e..8ef775f3 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter_test.go @@ -10,9 +10,9 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/comparer" - . "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil" ) var _ = testutil.Defer(func() { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/journal/journal.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/journal/journal.go index 6519ec66..4e4aae98 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/journal/journal.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/journal/journal.go @@ -82,8 +82,8 @@ import ( "fmt" "io" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/util" + "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/util" ) // These constants are part of the wire format and should not be changed. diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/key.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/key.go index 572ae815..eeff5332 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/key.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/key.go @@ -10,7 +10,7 @@ import ( "encoding/binary" "fmt" - "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors" ) type ErrIkeyCorrupted struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/key_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/key_test.go index 30eadf78..eb9526f7 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/key_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/key_test.go @@ -10,7 +10,7 @@ import ( "bytes" "testing" - "github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" ) var defaultIComparer = &iComparer{comparer.DefaultComparer} diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/leveldb_suite_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/leveldb_suite_test.go index fefa007a..33be15d6 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/leveldb_suite_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/leveldb_suite_test.go @@ -3,7 +3,7 @@ package leveldb import ( "testing" - "github.com/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil" ) func TestLevelDB(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/bench_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/bench_test.go index b05084ca..51ca66ba 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/bench_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/bench_test.go @@ -11,7 +11,7 @@ import ( "math/rand" "testing" - "github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" ) func BenchmarkPut(b *testing.B) { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go index 1395bd92..67c7254c 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go @@ -11,10 +11,10 @@ import ( "math/rand" "sync" - "github.com/syndtr/goleveldb/leveldb/comparer" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + "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/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) var ( @@ -206,7 +206,6 @@ func (p *DB) randHeight() (h int) { return } -// Must hold RW-lock if prev == true, as it use shared prevNode slice. func (p *DB) findGE(key []byte, prev bool) (int, bool) { node := 0 h := p.maxHeight - 1 @@ -303,7 +302,7 @@ func (p *DB) Put(key []byte, value []byte) error { node := len(p.nodeData) p.nodeData = append(p.nodeData, kvOffset, len(key), len(value), h) for i, n := range p.prevNode[:h] { - m := n + nNext + i + m := n + 4 + i p.nodeData = append(p.nodeData, p.nodeData[m]) p.nodeData[m] = node } @@ -435,22 +434,20 @@ func (p *DB) Len() int { // Reset resets the DB to initial empty state. Allows reuse the buffer. func (p *DB) Reset() { - p.mu.Lock() p.rnd = rand.New(rand.NewSource(0xdeadbeef)) p.maxHeight = 1 p.n = 0 p.kvSize = 0 p.kvData = p.kvData[:0] - p.nodeData = p.nodeData[:nNext+tMaxHeight] + p.nodeData = p.nodeData[:4+tMaxHeight] p.nodeData[nKV] = 0 p.nodeData[nKey] = 0 p.nodeData[nVal] = 0 p.nodeData[nHeight] = tMaxHeight for n := 0; n < tMaxHeight; n++ { - p.nodeData[nNext+n] = 0 + p.nodeData[4+n] = 0 p.prevNode[n] = 0 } - p.mu.Unlock() } // New creates a new initalized in-memory key/value DB. The capacity diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb_suite_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb_suite_test.go index 18c304b7..7be1214f 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb_suite_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb_suite_test.go @@ -3,7 +3,7 @@ package memdb import ( "testing" - "github.com/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil" ) func TestMemDB(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb_test.go index 5dd6dbc7..131333c1 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb_test.go @@ -10,10 +10,10 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/comparer" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/testutil" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) func (p *DB) TestFindLT(key []byte) (rkey, value []byte, err error) { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt/options.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt/options.go index f9a309da..0e244d4a 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt/options.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt/options.go @@ -8,9 +8,9 @@ package opt import ( - "github.com/syndtr/goleveldb/leveldb/cache" - "github.com/syndtr/goleveldb/leveldb/comparer" - "github.com/syndtr/goleveldb/leveldb/filter" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter" "math" ) @@ -250,11 +250,6 @@ type Options struct { // The default value (DefaultCompression) uses snappy compression. Compression Compression - // DisableBufferPool allows disable use of util.BufferPool functionality. - // - // The default value is false. - DisableBufferPool bool - // DisableBlockCache allows disable use of cache.Cache functionality on // 'sorted table' block. // @@ -326,11 +321,6 @@ type Options struct { // The default value is 500. OpenFilesCacheCapacity int - // If true then opens DB in read-only mode. - // - // The default value is false. - ReadOnly bool - // Strict defines the DB strict level. Strict Strict @@ -482,20 +472,6 @@ func (o *Options) GetCompression() Compression { return o.Compression } -func (o *Options) GetDisableBufferPool() bool { - if o == nil { - return false - } - return o.DisableBufferPool -} - -func (o *Options) GetDisableBlockCache() bool { - if o == nil { - return false - } - return o.DisableBlockCache -} - func (o *Options) GetDisableCompactionBackoff() bool { if o == nil { return false @@ -572,13 +548,6 @@ func (o *Options) GetOpenFilesCacheCapacity() int { return o.OpenFilesCacheCapacity } -func (o *Options) GetReadOnly() bool { - if o == nil { - return false - } - return o.ReadOnly -} - func (o *Options) GetStrict(strict Strict) bool { if o == nil || o.Strict == 0 { return DefaultStrict&strict != 0 diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/options.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/options.go index a3d84ef6..a13abb67 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/options.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/options.go @@ -7,8 +7,8 @@ package leveldb import ( - "github.com/syndtr/goleveldb/leveldb/filter" - "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt" ) func dupOptions(o *opt.Options) *opt.Options { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session.go index f0bba460..e8c81572 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session.go @@ -11,12 +11,14 @@ import ( "io" "os" "sync" + "sync/atomic" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/journal" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/storage" - "github.com/syndtr/goleveldb/leveldb/util" + "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/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/journal" + "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/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) type ErrManifestCorrupted struct { @@ -125,16 +127,11 @@ func (s *session) recover() (err error) { return } defer reader.Close() + strict := s.o.GetStrict(opt.StrictManifest) + jr := journal.NewReader(reader, dropper{s, m}, strict, true) - var ( - // Options. - numLevel = s.o.GetNumLevel() - strict = s.o.GetStrict(opt.StrictManifest) - - jr = journal.NewReader(reader, dropper{s, m}, strict, true) - rec = &sessionRecord{} - staging = s.stVersion.newStaging() - ) + staging := s.stVersion.newStaging() + rec := &sessionRecord{numLevel: s.o.GetNumLevel()} for { var r io.Reader r, err = jr.Next() @@ -146,7 +143,7 @@ func (s *session) recover() (err error) { return errors.SetFile(err, m) } - err = rec.decode(r, numLevel) + err = rec.decode(r) if err == nil { // save compact pointers for _, r := range rec.compPtrs { @@ -209,3 +206,250 @@ func (s *session) commit(r *sessionRecord) (err error) { return } + +// Pick a compaction based on current state; need external synchronization. +func (s *session) pickCompaction() *compaction { + v := s.version() + + var level int + var t0 tFiles + if v.cScore >= 1 { + level = v.cLevel + cptr := s.stCompPtrs[level] + tables := v.tables[level] + for _, t := range tables { + if cptr == nil || s.icmp.Compare(t.imax, cptr) > 0 { + t0 = append(t0, t) + break + } + } + if len(t0) == 0 { + t0 = append(t0, tables[0]) + } + } else { + if p := atomic.LoadPointer(&v.cSeek); p != nil { + ts := (*tSet)(p) + level = ts.level + t0 = append(t0, ts.table) + } else { + v.release() + return nil + } + } + + return newCompaction(s, v, level, t0) +} + +// Create compaction from given level and range; need external synchronization. +func (s *session) getCompactionRange(level int, umin, umax []byte) *compaction { + v := s.version() + + t0 := v.tables[level].getOverlaps(nil, s.icmp, umin, umax, level == 0) + if len(t0) == 0 { + v.release() + return nil + } + + // Avoid compacting too much in one shot in case the range is large. + // But we cannot do this for level-0 since level-0 files can overlap + // and we must not pick one file and drop another older file if the + // two files overlap. + if level > 0 { + limit := uint64(v.s.o.GetCompactionSourceLimit(level)) + total := uint64(0) + for i, t := range t0 { + total += t.size + if total >= limit { + s.logf("table@compaction limiting F·%d -> F·%d", len(t0), i+1) + t0 = t0[:i+1] + break + } + } + } + + return newCompaction(s, v, level, t0) +} + +func newCompaction(s *session, v *version, level int, t0 tFiles) *compaction { + c := &compaction{ + s: s, + v: v, + level: level, + tables: [2]tFiles{t0, nil}, + maxGPOverlaps: uint64(s.o.GetCompactionGPOverlaps(level)), + tPtrs: make([]int, s.o.GetNumLevel()), + } + c.expand() + c.save() + return c +} + +// compaction represent a compaction state. +type compaction struct { + s *session + v *version + + level int + tables [2]tFiles + maxGPOverlaps uint64 + + gp tFiles + gpi int + seenKey bool + gpOverlappedBytes uint64 + imin, imax iKey + tPtrs []int + released bool + + snapGPI int + snapSeenKey bool + snapGPOverlappedBytes uint64 + snapTPtrs []int +} + +func (c *compaction) save() { + c.snapGPI = c.gpi + c.snapSeenKey = c.seenKey + c.snapGPOverlappedBytes = c.gpOverlappedBytes + c.snapTPtrs = append(c.snapTPtrs[:0], c.tPtrs...) +} + +func (c *compaction) restore() { + c.gpi = c.snapGPI + c.seenKey = c.snapSeenKey + c.gpOverlappedBytes = c.snapGPOverlappedBytes + c.tPtrs = append(c.tPtrs[:0], c.snapTPtrs...) +} + +func (c *compaction) release() { + if !c.released { + c.released = true + c.v.release() + } +} + +// Expand compacted tables; need external synchronization. +func (c *compaction) expand() { + limit := uint64(c.s.o.GetCompactionExpandLimit(c.level)) + vt0, vt1 := c.v.tables[c.level], c.v.tables[c.level+1] + + t0, t1 := c.tables[0], c.tables[1] + imin, imax := t0.getRange(c.s.icmp) + // We expand t0 here just incase ukey hop across tables. + t0 = vt0.getOverlaps(t0, c.s.icmp, imin.ukey(), imax.ukey(), c.level == 0) + if len(t0) != len(c.tables[0]) { + imin, imax = t0.getRange(c.s.icmp) + } + t1 = vt1.getOverlaps(t1, c.s.icmp, imin.ukey(), imax.ukey(), false) + // Get entire range covered by compaction. + amin, amax := append(t0, t1...).getRange(c.s.icmp) + + // See if we can grow the number of inputs in "level" without + // changing the number of "level+1" files we pick up. + if len(t1) > 0 { + exp0 := vt0.getOverlaps(nil, c.s.icmp, amin.ukey(), amax.ukey(), c.level == 0) + if len(exp0) > len(t0) && t1.size()+exp0.size() < limit { + xmin, xmax := exp0.getRange(c.s.icmp) + exp1 := vt1.getOverlaps(nil, c.s.icmp, xmin.ukey(), xmax.ukey(), false) + if len(exp1) == len(t1) { + c.s.logf("table@compaction expanding L%d+L%d (F·%d S·%s)+(F·%d S·%s) -> (F·%d S·%s)+(F·%d S·%s)", + c.level, c.level+1, len(t0), shortenb(int(t0.size())), len(t1), shortenb(int(t1.size())), + len(exp0), shortenb(int(exp0.size())), len(exp1), shortenb(int(exp1.size()))) + imin, imax = xmin, xmax + t0, t1 = exp0, exp1 + amin, amax = append(t0, t1...).getRange(c.s.icmp) + } + } + } + + // Compute the set of grandparent files that overlap this compaction + // (parent == level+1; grandparent == level+2) + if c.level+2 < c.s.o.GetNumLevel() { + c.gp = c.v.tables[c.level+2].getOverlaps(c.gp, c.s.icmp, amin.ukey(), amax.ukey(), false) + } + + c.tables[0], c.tables[1] = t0, t1 + c.imin, c.imax = imin, imax +} + +// Check whether compaction is trivial. +func (c *compaction) trivial() bool { + return len(c.tables[0]) == 1 && len(c.tables[1]) == 0 && c.gp.size() <= c.maxGPOverlaps +} + +func (c *compaction) baseLevelForKey(ukey []byte) bool { + for level, tables := range c.v.tables[c.level+2:] { + for c.tPtrs[level] < len(tables) { + t := tables[c.tPtrs[level]] + if c.s.icmp.uCompare(ukey, t.imax.ukey()) <= 0 { + // We've advanced far enough. + if c.s.icmp.uCompare(ukey, t.imin.ukey()) >= 0 { + // Key falls in this file's range, so definitely not base level. + return false + } + break + } + c.tPtrs[level]++ + } + } + return true +} + +func (c *compaction) shouldStopBefore(ikey iKey) bool { + for ; c.gpi < len(c.gp); c.gpi++ { + gp := c.gp[c.gpi] + if c.s.icmp.Compare(ikey, gp.imax) <= 0 { + break + } + if c.seenKey { + c.gpOverlappedBytes += gp.size + } + } + c.seenKey = true + + if c.gpOverlappedBytes > c.maxGPOverlaps { + // Too much overlap for current output; start new output. + c.gpOverlappedBytes = 0 + return true + } + return false +} + +// Creates an iterator. +func (c *compaction) newIterator() iterator.Iterator { + // Creates iterator slice. + icap := len(c.tables) + if c.level == 0 { + // Special case for level-0 + icap = len(c.tables[0]) + 1 + } + its := make([]iterator.Iterator, 0, icap) + + // Options. + ro := &opt.ReadOptions{ + DontFillCache: true, + Strict: opt.StrictOverride, + } + strict := c.s.o.GetStrict(opt.StrictCompaction) + if strict { + ro.Strict |= opt.StrictReader + } + + for i, tables := range c.tables { + if len(tables) == 0 { + continue + } + + // Level-0 is not sorted and may overlaps each other. + if c.level+i == 0 { + for _, t := range tables { + its = append(its, c.s.tops.newIterator(t, nil, ro)) + } + } else { + it := iterator.NewIndexedIterator(tables.newIndexIterator(c.s.tops, c.s.icmp, nil, ro), strict) + its = append(its, it) + } + } + + return iterator.NewMergedIterator(its, c.s.icmp, strict) +} diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_compaction.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_compaction.go deleted file mode 100644 index 7c5a7941..00000000 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_compaction.go +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com> -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package leveldb - -import ( - "sync/atomic" - - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/memdb" - "github.com/syndtr/goleveldb/leveldb/opt" -) - -func (s *session) pickMemdbLevel(umin, umax []byte) int { - v := s.version() - defer v.release() - return v.pickMemdbLevel(umin, umax) -} - -func (s *session) flushMemdb(rec *sessionRecord, mdb *memdb.DB, level int) (level_ int, err error) { - // Create sorted table. - iter := mdb.NewIterator(nil) - defer iter.Release() - t, n, err := s.tops.createFrom(iter) - if err != nil { - return level, err - } - - // Pick level and add to record. - if level < 0 { - level = s.pickMemdbLevel(t.imin.ukey(), t.imax.ukey()) - } - rec.addTableFile(level, t) - - s.logf("memdb@flush created L%d@%d N·%d S·%s %q:%q", level, t.file.Num(), n, shortenb(int(t.size)), t.imin, t.imax) - return level, nil -} - -// Pick a compaction based on current state; need external synchronization. -func (s *session) pickCompaction() *compaction { - v := s.version() - - var level int - var t0 tFiles - if v.cScore >= 1 { - level = v.cLevel - cptr := s.stCompPtrs[level] - tables := v.tables[level] - for _, t := range tables { - if cptr == nil || s.icmp.Compare(t.imax, cptr) > 0 { - t0 = append(t0, t) - break - } - } - if len(t0) == 0 { - t0 = append(t0, tables[0]) - } - } else { - if p := atomic.LoadPointer(&v.cSeek); p != nil { - ts := (*tSet)(p) - level = ts.level - t0 = append(t0, ts.table) - } else { - v.release() - return nil - } - } - - return newCompaction(s, v, level, t0) -} - -// Create compaction from given level and range; need external synchronization. -func (s *session) getCompactionRange(level int, umin, umax []byte) *compaction { - v := s.version() - - t0 := v.tables[level].getOverlaps(nil, s.icmp, umin, umax, level == 0) - if len(t0) == 0 { - v.release() - return nil - } - - // Avoid compacting too much in one shot in case the range is large. - // But we cannot do this for level-0 since level-0 files can overlap - // and we must not pick one file and drop another older file if the - // two files overlap. - if level > 0 { - limit := uint64(v.s.o.GetCompactionSourceLimit(level)) - total := uint64(0) - for i, t := range t0 { - total += t.size - if total >= limit { - s.logf("table@compaction limiting F·%d -> F·%d", len(t0), i+1) - t0 = t0[:i+1] - break - } - } - } - - return newCompaction(s, v, level, t0) -} - -func newCompaction(s *session, v *version, level int, t0 tFiles) *compaction { - c := &compaction{ - s: s, - v: v, - level: level, - tables: [2]tFiles{t0, nil}, - maxGPOverlaps: uint64(s.o.GetCompactionGPOverlaps(level)), - tPtrs: make([]int, s.o.GetNumLevel()), - } - c.expand() - c.save() - return c -} - -// compaction represent a compaction state. -type compaction struct { - s *session - v *version - - level int - tables [2]tFiles - maxGPOverlaps uint64 - - gp tFiles - gpi int - seenKey bool - gpOverlappedBytes uint64 - imin, imax iKey - tPtrs []int - released bool - - snapGPI int - snapSeenKey bool - snapGPOverlappedBytes uint64 - snapTPtrs []int -} - -func (c *compaction) save() { - c.snapGPI = c.gpi - c.snapSeenKey = c.seenKey - c.snapGPOverlappedBytes = c.gpOverlappedBytes - c.snapTPtrs = append(c.snapTPtrs[:0], c.tPtrs...) -} - -func (c *compaction) restore() { - c.gpi = c.snapGPI - c.seenKey = c.snapSeenKey - c.gpOverlappedBytes = c.snapGPOverlappedBytes - c.tPtrs = append(c.tPtrs[:0], c.snapTPtrs...) -} - -func (c *compaction) release() { - if !c.released { - c.released = true - c.v.release() - } -} - -// Expand compacted tables; need external synchronization. -func (c *compaction) expand() { - limit := uint64(c.s.o.GetCompactionExpandLimit(c.level)) - vt0, vt1 := c.v.tables[c.level], c.v.tables[c.level+1] - - t0, t1 := c.tables[0], c.tables[1] - imin, imax := t0.getRange(c.s.icmp) - // We expand t0 here just incase ukey hop across tables. - t0 = vt0.getOverlaps(t0, c.s.icmp, imin.ukey(), imax.ukey(), c.level == 0) - if len(t0) != len(c.tables[0]) { - imin, imax = t0.getRange(c.s.icmp) - } - t1 = vt1.getOverlaps(t1, c.s.icmp, imin.ukey(), imax.ukey(), false) - // Get entire range covered by compaction. - amin, amax := append(t0, t1...).getRange(c.s.icmp) - - // See if we can grow the number of inputs in "level" without - // changing the number of "level+1" files we pick up. - if len(t1) > 0 { - exp0 := vt0.getOverlaps(nil, c.s.icmp, amin.ukey(), amax.ukey(), c.level == 0) - if len(exp0) > len(t0) && t1.size()+exp0.size() < limit { - xmin, xmax := exp0.getRange(c.s.icmp) - exp1 := vt1.getOverlaps(nil, c.s.icmp, xmin.ukey(), xmax.ukey(), false) - if len(exp1) == len(t1) { - c.s.logf("table@compaction expanding L%d+L%d (F·%d S·%s)+(F·%d S·%s) -> (F·%d S·%s)+(F·%d S·%s)", - c.level, c.level+1, len(t0), shortenb(int(t0.size())), len(t1), shortenb(int(t1.size())), - len(exp0), shortenb(int(exp0.size())), len(exp1), shortenb(int(exp1.size()))) - imin, imax = xmin, xmax - t0, t1 = exp0, exp1 - amin, amax = append(t0, t1...).getRange(c.s.icmp) - } - } - } - - // Compute the set of grandparent files that overlap this compaction - // (parent == level+1; grandparent == level+2) - if c.level+2 < c.s.o.GetNumLevel() { - c.gp = c.v.tables[c.level+2].getOverlaps(c.gp, c.s.icmp, amin.ukey(), amax.ukey(), false) - } - - c.tables[0], c.tables[1] = t0, t1 - c.imin, c.imax = imin, imax -} - -// Check whether compaction is trivial. -func (c *compaction) trivial() bool { - return len(c.tables[0]) == 1 && len(c.tables[1]) == 0 && c.gp.size() <= c.maxGPOverlaps -} - -func (c *compaction) baseLevelForKey(ukey []byte) bool { - for level, tables := range c.v.tables[c.level+2:] { - for c.tPtrs[level] < len(tables) { - t := tables[c.tPtrs[level]] - if c.s.icmp.uCompare(ukey, t.imax.ukey()) <= 0 { - // We've advanced far enough. - if c.s.icmp.uCompare(ukey, t.imin.ukey()) >= 0 { - // Key falls in this file's range, so definitely not base level. - return false - } - break - } - c.tPtrs[level]++ - } - } - return true -} - -func (c *compaction) shouldStopBefore(ikey iKey) bool { - for ; c.gpi < len(c.gp); c.gpi++ { - gp := c.gp[c.gpi] - if c.s.icmp.Compare(ikey, gp.imax) <= 0 { - break - } - if c.seenKey { - c.gpOverlappedBytes += gp.size - } - } - c.seenKey = true - - if c.gpOverlappedBytes > c.maxGPOverlaps { - // Too much overlap for current output; start new output. - c.gpOverlappedBytes = 0 - return true - } - return false -} - -// Creates an iterator. -func (c *compaction) newIterator() iterator.Iterator { - // Creates iterator slice. - icap := len(c.tables) - if c.level == 0 { - // Special case for level-0. - icap = len(c.tables[0]) + 1 - } - its := make([]iterator.Iterator, 0, icap) - - // Options. - ro := &opt.ReadOptions{ - DontFillCache: true, - Strict: opt.StrictOverride, - } - strict := c.s.o.GetStrict(opt.StrictCompaction) - if strict { - ro.Strict |= opt.StrictReader - } - - for i, tables := range c.tables { - if len(tables) == 0 { - continue - } - - // Level-0 is not sorted and may overlaps each other. - if c.level+i == 0 { - for _, t := range tables { - its = append(its, c.s.tops.newIterator(t, nil, ro)) - } - } else { - it := iterator.NewIndexedIterator(tables.newIndexIterator(c.s.tops, c.s.icmp, nil, ro), strict) - its = append(its, it) - } - } - - return iterator.NewMergedIterator(its, c.s.icmp, strict) -} diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_record.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_record.go index 405e07be..5fad6105 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_record.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_record.go @@ -12,7 +12,7 @@ import ( "io" "strings" - "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors" ) type byteReader interface { @@ -52,6 +52,8 @@ type dtRecord struct { } type sessionRecord struct { + numLevel int + hasRec int comparer string journalNum uint64 @@ -228,7 +230,7 @@ func (p *sessionRecord) readBytes(field string, r byteReader) []byte { return x } -func (p *sessionRecord) readLevel(field string, r io.ByteReader, numLevel int) int { +func (p *sessionRecord) readLevel(field string, r io.ByteReader) int { if p.err != nil { return 0 } @@ -236,14 +238,14 @@ func (p *sessionRecord) readLevel(field string, r io.ByteReader, numLevel int) i if p.err != nil { return 0 } - if x >= uint64(numLevel) { + if x >= uint64(p.numLevel) { p.err = errors.NewErrCorrupted(nil, &ErrManifestCorrupted{field, "invalid level number"}) return 0 } return int(x) } -func (p *sessionRecord) decode(r io.Reader, numLevel int) error { +func (p *sessionRecord) decode(r io.Reader) error { br, ok := r.(byteReader) if !ok { br = bufio.NewReader(r) @@ -284,13 +286,13 @@ func (p *sessionRecord) decode(r io.Reader, numLevel int) error { p.setSeqNum(x) } case recCompPtr: - level := p.readLevel("comp-ptr.level", br, numLevel) + level := p.readLevel("comp-ptr.level", br) ikey := p.readBytes("comp-ptr.ikey", br) if p.err == nil { p.addCompPtr(level, iKey(ikey)) } case recAddTable: - level := p.readLevel("add-table.level", br, numLevel) + level := p.readLevel("add-table.level", br) num := p.readUvarint("add-table.num", br) size := p.readUvarint("add-table.size", br) imin := p.readBytes("add-table.imin", br) @@ -299,7 +301,7 @@ func (p *sessionRecord) decode(r io.Reader, numLevel int) error { p.addTable(level, num, size, imin, imax) } case recDelTable: - level := p.readLevel("del-table.level", br, numLevel) + level := p.readLevel("del-table.level", br) num := p.readUvarint("del-table.num", br) if p.err == nil { p.delTable(level, num) diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_record_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_record_test.go index 33c14875..ba3864b2 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_record_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_record_test.go @@ -10,7 +10,7 @@ import ( "bytes" "testing" - "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt" ) func decodeEncode(v *sessionRecord) (res bool, err error) { @@ -19,8 +19,8 @@ func decodeEncode(v *sessionRecord) (res bool, err error) { if err != nil { return } - v2 := &sessionRecord{} - err = v.decode(b, opt.DefaultNumLevel) + v2 := &sessionRecord{numLevel: opt.DefaultNumLevel} + err = v.decode(b) if err != nil { return } @@ -34,7 +34,7 @@ func decodeEncode(v *sessionRecord) (res bool, err error) { func TestSessionRecord_EncodeDecode(t *testing.T) { big := uint64(1) << 50 - v := &sessionRecord{} + v := &sessionRecord{numLevel: opt.DefaultNumLevel} i := uint64(0) test := func() { res, err := decodeEncode(v) diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_util.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_util.go index 399a788b..23f3d80f 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_util.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/session_util.go @@ -10,8 +10,8 @@ import ( "fmt" "sync/atomic" - "github.com/syndtr/goleveldb/leveldb/journal" - "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/journal" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage" ) // Logging. @@ -182,7 +182,7 @@ func (s *session) newManifest(rec *sessionRecord, v *version) (err error) { defer v.release() } if rec == nil { - rec = &sessionRecord{} + rec = &sessionRecord{numLevel: s.o.GetNumLevel()} } s.fillRecord(rec, true) v.fillRecord(rec) diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go index 46cc9d07..9329faf7 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go @@ -18,7 +18,7 @@ import ( "sync" "time" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) var errFileOpen = errors.New("leveldb/storage: file still open") diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/mem_storage.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/mem_storage.go index fc1c8165..89521931 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/mem_storage.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/mem_storage.go @@ -11,7 +11,7 @@ import ( "os" "sync" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) const typeShift = 3 diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/storage.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/storage.go index 85dd70b0..bdda8c44 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/storage.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage/storage.go @@ -12,7 +12,7 @@ import ( "fmt" "io" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) type FileType uint32 diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go index 08be0bab..768dfc88 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go @@ -17,8 +17,8 @@ import ( "sync" "testing" - "github.com/syndtr/goleveldb/leveldb/storage" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) const typeShift = 4 @@ -42,8 +42,6 @@ type tsOp uint const ( tsOpOpen tsOp = iota tsOpCreate - tsOpReplace - tsOpRemove tsOpRead tsOpReadAt tsOpWrite @@ -243,10 +241,6 @@ func (tf tsFile) Replace(newfile storage.File) (err error) { if err != nil { return } - if tf.shouldErr(tsOpReplace) { - err = errors.New("leveldb.testStorage: emulated create error") - return - } err = tf.File.Replace(newfile.(tsFile).File) if err != nil { ts.t.Errorf("E: cannot replace file, num=%d type=%v: %v", tf.Num(), tf.Type(), err) @@ -264,10 +258,6 @@ func (tf tsFile) Remove() (err error) { if err != nil { return } - if tf.shouldErr(tsOpRemove) { - err = errors.New("leveldb.testStorage: emulated create error") - return - } err = tf.File.Remove() if err != nil { ts.t.Errorf("E: cannot remove file, num=%d type=%v: %v", tf.Num(), tf.Type(), err) diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table.go index db386f3b..357e5184 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table.go @@ -11,12 +11,12 @@ import ( "sort" "sync/atomic" - "github.com/syndtr/goleveldb/leveldb/cache" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/storage" - "github.com/syndtr/goleveldb/leveldb/table" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "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/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) // tFile holds basic information about a table. @@ -441,26 +441,22 @@ func newTableOps(s *session) *tOps { var ( cacher cache.Cacher bcache *cache.Cache - bpool *util.BufferPool ) if s.o.GetOpenFilesCacheCapacity() > 0 { cacher = cache.NewLRU(s.o.GetOpenFilesCacheCapacity()) } - if !s.o.GetDisableBlockCache() { + if !s.o.DisableBlockCache { var bcacher cache.Cacher if s.o.GetBlockCacheCapacity() > 0 { bcacher = cache.NewLRU(s.o.GetBlockCacheCapacity()) } bcache = cache.NewCache(bcacher) } - if !s.o.GetDisableBufferPool() { - bpool = util.NewBufferPool(s.o.GetBlockSize() + 5) - } return &tOps{ s: s, cache: cache.NewCache(cacher), bcache: bcache, - bpool: bpool, + bpool: util.NewBufferPool(s.o.GetBlockSize() + 5), } } diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/block_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/block_test.go index 00e6f9ee..a8580cf3 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/block_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/block_test.go @@ -13,10 +13,10 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/comparer" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/testutil" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) type blockTesting struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/reader.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/reader.go index 95c369d1..1bfc3978 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/reader.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/reader.go @@ -14,16 +14,16 @@ import ( "strings" "sync" - "github.com/google/go-snappy/snappy" - - "github.com/syndtr/goleveldb/leveldb/cache" - "github.com/syndtr/goleveldb/leveldb/comparer" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/filter" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/storage" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy" + + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/cache" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + "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/filter" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "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/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) var ( diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/table_suite_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/table_suite_test.go index 6465da6e..d35a1305 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/table_suite_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/table_suite_test.go @@ -3,7 +3,7 @@ package table import ( "testing" - "github.com/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil" ) func TestTable(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/table_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/table_test.go index 4b59b31f..5429c465 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/table_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/table_test.go @@ -12,10 +12,10 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/testutil" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "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/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) type tableWrapper struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/writer.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/writer.go index 45819282..51f9fc71 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/writer.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/table/writer.go @@ -12,12 +12,12 @@ import ( "fmt" "io" - "github.com/google/go-snappy/snappy" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy" - "github.com/syndtr/goleveldb/leveldb/comparer" - "github.com/syndtr/goleveldb/leveldb/filter" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/filter" + "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/syndtr/goleveldb/leveldb/util" ) func sharedPrefixLen(a, b []byte) int { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/db.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/db.go index ec3f177a..a0995a4b 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/db.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/db.go @@ -12,9 +12,9 @@ import ( . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/util" + "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/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) type DB interface{} diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go index df6d9db6..5e3cbb16 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go @@ -12,7 +12,7 @@ import ( . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" ) type IterAct int diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/kv.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/kv.go index 471d5708..83a01a47 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/kv.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/kv.go @@ -12,7 +12,7 @@ import ( "sort" "strings" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) type KeyValueEntry struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/kvtest.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/kvtest.go index a0b58f0e..78d981c7 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/kvtest.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/kvtest.go @@ -13,8 +13,8 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/util" + "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/util" ) func KeyValueTesting(rnd *rand.Rand, kv KeyValue, p DB, setup func(KeyValue) DB, teardown func(DB)) { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/storage.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/storage.go index 59c496d5..d515438b 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/storage.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/storage.go @@ -18,8 +18,8 @@ import ( . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/storage" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) var ( diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/util.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/util.go index 97c5294b..7ac261dd 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/util.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/util.go @@ -15,7 +15,7 @@ import ( "github.com/onsi/ginkgo/config" - "github.com/syndtr/goleveldb/leveldb/comparer" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/comparer" ) var ( diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil_test.go index 25bf2b29..868f7ffa 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil_test.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil_test.go @@ -9,10 +9,10 @@ package leveldb import ( . "github.com/onsi/gomega" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/testutil" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "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/syndtr/goleveldb/leveldb/testutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util" ) type testingDB struct { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util.go index 1a5bf71a..7de9260d 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/util.go @@ -10,7 +10,7 @@ import ( "fmt" "sort" - "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage" ) func shorten(str string) string { diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/version.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/version.go index 011d982d..39468b73 100644 --- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/version.go +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/version.go @@ -10,9 +10,9 @@ import ( "sync/atomic" "unsafe" - "github.com/syndtr/goleveldb/leveldb/iterator" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/util" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/iterator" + "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/syndtr/goleveldb/leveldb/util" ) type tSet struct { @@ -300,7 +300,7 @@ func (v *version) offsetOf(ikey iKey) (n uint64, err error) { return } -func (v *version) pickMemdbLevel(umin, umax []byte) (level int) { +func (v *version) pickLevel(umin, umax []byte) (level int) { if !v.tables[0].overlaps(v.s.icmp, umin, umax, true) { var overlaps tFiles maxLevel := v.s.o.GetMaxMemCompationLevel() diff --git a/Godeps/_workspace/src/github.com/google/go-snappy/snappy/decode.go b/Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy/decode.go similarity index 100% rename from Godeps/_workspace/src/github.com/google/go-snappy/snappy/decode.go rename to Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy/decode.go diff --git a/Godeps/_workspace/src/github.com/google/go-snappy/snappy/encode.go b/Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy/encode.go similarity index 100% rename from Godeps/_workspace/src/github.com/google/go-snappy/snappy/encode.go rename to Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy/encode.go diff --git a/Godeps/_workspace/src/github.com/google/go-snappy/snappy/snappy.go b/Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy/snappy.go similarity index 100% rename from Godeps/_workspace/src/github.com/google/go-snappy/snappy/snappy.go rename to Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy/snappy.go diff --git a/Godeps/_workspace/src/github.com/google/go-snappy/snappy/snappy_test.go b/Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy/snappy_test.go similarity index 100% rename from Godeps/_workspace/src/github.com/google/go-snappy/snappy/snappy_test.go rename to Godeps/_workspace/src/github.com/syndtr/gosnappy/snappy/snappy_test.go diff --git a/Godeps/_workspace/src/github.com/tendermint/ed25519/ed25519.go b/Godeps/_workspace/src/github.com/tendermint/ed25519/ed25519.go index 48ac4a42..6c7e5cbc 100644 --- a/Godeps/_workspace/src/github.com/tendermint/ed25519/ed25519.go +++ b/Godeps/_workspace/src/github.com/tendermint/ed25519/ed25519.go @@ -14,7 +14,7 @@ import ( "crypto/subtle" "io" - "github.com/agl/ed25519/edwards25519" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/agl/ed25519/edwards25519" ) const ( diff --git a/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519/extra25519.go b/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519/extra25519.go index 571218f5..bbda9168 100644 --- a/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519/extra25519.go +++ b/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519/extra25519.go @@ -7,7 +7,7 @@ package extra25519 import ( "crypto/sha512" - "github.com/agl/ed25519/edwards25519" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/agl/ed25519/edwards25519" ) // PrivateKeyToCurve25519 converts an ed25519 private key into a corresponding diff --git a/Godeps/_workspace/src/code.google.com/p/mxk/go1/flowcontrol/flowcontrol.go b/Godeps/_workspace/src/github.com/tendermint/flowcontrol/flowcontrol.go similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/mxk/go1/flowcontrol/flowcontrol.go rename to Godeps/_workspace/src/github.com/tendermint/flowcontrol/flowcontrol.go diff --git a/Godeps/_workspace/src/code.google.com/p/mxk/go1/flowcontrol/io.go b/Godeps/_workspace/src/github.com/tendermint/flowcontrol/io.go similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/mxk/go1/flowcontrol/io.go rename to Godeps/_workspace/src/github.com/tendermint/flowcontrol/io.go diff --git a/Godeps/_workspace/src/code.google.com/p/mxk/go1/flowcontrol/io_test.go b/Godeps/_workspace/src/github.com/tendermint/flowcontrol/io_test.go similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/mxk/go1/flowcontrol/io_test.go rename to Godeps/_workspace/src/github.com/tendermint/flowcontrol/io_test.go diff --git a/Godeps/_workspace/src/code.google.com/p/mxk/go1/flowcontrol/util.go b/Godeps/_workspace/src/github.com/tendermint/flowcontrol/util.go similarity index 100% rename from Godeps/_workspace/src/code.google.com/p/mxk/go1/flowcontrol/util.go rename to Godeps/_workspace/src/github.com/tendermint/flowcontrol/util.go diff --git a/Godeps/_workspace/src/github.com/tendermint/go-clist/LICENSE.md b/Godeps/_workspace/src/github.com/tendermint/go-clist/LICENSE.md new file mode 100644 index 00000000..57cfcf41 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-clist/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint Go-CList +Copyright (C) 2015 Tendermint + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS diff --git a/Godeps/_workspace/src/github.com/tendermint/go-clist/clist.go b/Godeps/_workspace/src/github.com/tendermint/go-clist/clist.go new file mode 100644 index 00000000..5295dd99 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-clist/clist.go @@ -0,0 +1,285 @@ +package clist + +/* +The purpose of CList is to provide a goroutine-safe linked-list. +This list can be traversed concurrently by any number of goroutines. +However, removed CElements cannot be added back. +NOTE: Not all methods of container/list are (yet) implemented. +NOTE: Removed elements need to DetachPrev or DetachNext consistently +to ensure garbage collection of removed elements. +*/ + +import ( + "sync" + "sync/atomic" + "unsafe" +) + +// CElement is an element of a linked-list +// Traversal from a CElement are goroutine-safe. +type CElement struct { + prev unsafe.Pointer + prevWg *sync.WaitGroup + next unsafe.Pointer + nextWg *sync.WaitGroup + removed uint32 + Value interface{} +} + +// Blocking implementation of Next(). +// May return nil iff CElement was tail and got removed. +func (e *CElement) NextWait() *CElement { + for { + e.nextWg.Wait() + next := e.Next() + if next == nil { + if e.Removed() { + return nil + } else { + continue + } + } else { + return next + } + } +} + +// Blocking implementation of Prev(). +// May return nil iff CElement was head and got removed. +func (e *CElement) PrevWait() *CElement { + for { + e.prevWg.Wait() + prev := e.Prev() + if prev == nil { + if e.Removed() { + return nil + } else { + continue + } + } else { + return prev + } + } +} + +// Nonblocking, may return nil if at the end. +func (e *CElement) Next() *CElement { + return (*CElement)(atomic.LoadPointer(&e.next)) +} + +// Nonblocking, may return nil if at the end. +func (e *CElement) Prev() *CElement { + return (*CElement)(atomic.LoadPointer(&e.prev)) +} + +func (e *CElement) Removed() bool { + return atomic.LoadUint32(&(e.removed)) > 0 +} + +func (e *CElement) DetachNext() { + if !e.Removed() { + panic("DetachNext() must be called after Remove(e)") + } + atomic.StorePointer(&e.next, nil) +} + +func (e *CElement) DetachPrev() { + if !e.Removed() { + panic("DetachPrev() must be called after Remove(e)") + } + atomic.StorePointer(&e.prev, nil) +} + +func (e *CElement) setNextAtomic(next *CElement) { + for { + oldNext := atomic.LoadPointer(&e.next) + if !atomic.CompareAndSwapPointer(&(e.next), oldNext, unsafe.Pointer(next)) { + continue + } + if next == nil && oldNext != nil { // We for-loop in NextWait() so race is ok + e.nextWg.Add(1) + } + if next != nil && oldNext == nil { + e.nextWg.Done() + } + return + } +} + +func (e *CElement) setPrevAtomic(prev *CElement) { + for { + oldPrev := atomic.LoadPointer(&e.prev) + if !atomic.CompareAndSwapPointer(&(e.prev), oldPrev, unsafe.Pointer(prev)) { + continue + } + if prev == nil && oldPrev != nil { // We for-loop in PrevWait() so race is ok + e.prevWg.Add(1) + } + if prev != nil && oldPrev == nil { + e.prevWg.Done() + } + return + } +} + +func (e *CElement) setRemovedAtomic() { + atomic.StoreUint32(&(e.removed), 1) +} + +//-------------------------------------------------------------------------------- + +// CList represents a linked list. +// The zero value for CList is an empty list ready to use. +// Operations are goroutine-safe. +type CList struct { + mtx sync.Mutex + wg *sync.WaitGroup + head *CElement // first element + tail *CElement // last element + len int // list length +} + +func (l *CList) Init() *CList { + l.mtx.Lock() + defer l.mtx.Unlock() + l.wg = waitGroup1() + l.head = nil + l.tail = nil + l.len = 0 + return l +} + +func New() *CList { return new(CList).Init() } + +func (l *CList) Len() int { + l.mtx.Lock() + defer l.mtx.Unlock() + return l.len +} + +func (l *CList) Front() *CElement { + l.mtx.Lock() + defer l.mtx.Unlock() + return l.head +} + +func (l *CList) FrontWait() *CElement { + for { + l.mtx.Lock() + head := l.head + wg := l.wg + l.mtx.Unlock() + if head == nil { + wg.Wait() + } else { + return head + } + } +} + +func (l *CList) Back() *CElement { + l.mtx.Lock() + defer l.mtx.Unlock() + return l.tail +} + +func (l *CList) BackWait() *CElement { + for { + l.mtx.Lock() + tail := l.tail + wg := l.wg + l.mtx.Unlock() + if tail == nil { + wg.Wait() + } else { + return tail + } + } +} + +func (l *CList) PushBack(v interface{}) *CElement { + l.mtx.Lock() + defer l.mtx.Unlock() + + // Construct a new element + e := &CElement{ + prev: nil, + prevWg: waitGroup1(), + next: nil, + nextWg: waitGroup1(), + Value: v, + } + + // Release waiters on FrontWait/BackWait maybe + if l.len == 0 { + l.wg.Done() + } + l.len += 1 + + // Modify the tail + if l.tail == nil { + l.head = e + l.tail = e + } else { + l.tail.setNextAtomic(e) + e.setPrevAtomic(l.tail) + l.tail = e + } + + return e +} + +// CONTRACT: Caller must call e.DetachPrev() and/or e.DetachNext() to avoid memory leaks. +// NOTE: As per the contract of CList, removed elements cannot be added back. +func (l *CList) Remove(e *CElement) interface{} { + l.mtx.Lock() + defer l.mtx.Unlock() + + prev := e.Prev() + next := e.Next() + + if l.head == nil || l.tail == nil { + panic("Remove(e) on empty CList") + } + if prev == nil && l.head != e { + panic("Remove(e) with false head") + } + if next == nil && l.tail != e { + panic("Remove(e) with false tail") + } + + // If we're removing the only item, make CList FrontWait/BackWait wait. + if l.len == 1 { + l.wg.Add(1) + } + l.len -= 1 + + // Connect next/prev and set head/tail + if prev == nil { + l.head = next + } else { + prev.setNextAtomic(next) + } + if next == nil { + l.tail = prev + } else { + next.setPrevAtomic(prev) + } + + // Set .Done() on e, otherwise waiters will wait forever. + e.setRemovedAtomic() + if prev == nil { + e.prevWg.Done() + } + if next == nil { + e.nextWg.Done() + } + + return e.Value +} + +func waitGroup1() (wg *sync.WaitGroup) { + wg = &sync.WaitGroup{} + wg.Add(1) + return +} diff --git a/Godeps/_workspace/src/github.com/tendermint/go-clist/clist_test.go b/Godeps/_workspace/src/github.com/tendermint/go-clist/clist_test.go new file mode 100644 index 00000000..d5a3f8ed --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-clist/clist_test.go @@ -0,0 +1,213 @@ +package clist + +import ( + "fmt" + "math/rand" + "runtime" + "testing" + "time" +) + +func TestSmall(t *testing.T) { + l := New() + el1 := l.PushBack(1) + el2 := l.PushBack(2) + el3 := l.PushBack(3) + if l.Len() != 3 { + t.Error("Expected len 3, got ", l.Len()) + } + + //fmt.Printf("%p %v\n", el1, el1) + //fmt.Printf("%p %v\n", el2, el2) + //fmt.Printf("%p %v\n", el3, el3) + + r1 := l.Remove(el1) + + //fmt.Printf("%p %v\n", el1, el1) + //fmt.Printf("%p %v\n", el2, el2) + //fmt.Printf("%p %v\n", el3, el3) + + r2 := l.Remove(el2) + + //fmt.Printf("%p %v\n", el1, el1) + //fmt.Printf("%p %v\n", el2, el2) + //fmt.Printf("%p %v\n", el3, el3) + + r3 := l.Remove(el3) + + if r1 != 1 { + t.Error("Expected 1, got ", r1) + } + if r2 != 2 { + t.Error("Expected 2, got ", r2) + } + if r3 != 3 { + t.Error("Expected 3, got ", r3) + } + if l.Len() != 0 { + t.Error("Expected len 0, got ", l.Len()) + } + +} + +/* +This test is quite hacky because it relies on SetFinalizer +which isn't guaranteed to run at all. +*/ +func TestGCFifo(t *testing.T) { + + const numElements = 1000000 + l := New() + gcCount := 0 + + // SetFinalizer doesn't work well with circular structures, + // so we construct a trivial non-circular structure to + // track. + type value struct { + Int int + } + + for i := 0; i < numElements; i++ { + v := new(value) + v.Int = i + l.PushBack(v) + runtime.SetFinalizer(v, func(v *value) { + gcCount += 1 + }) + } + + for el := l.Front(); el != nil; { + l.Remove(el) + //oldEl := el + el = el.Next() + //oldEl.DetachPrev() + //oldEl.DetachNext() + } + + runtime.GC() + time.Sleep(time.Second * 3) + + if gcCount != numElements { + t.Errorf("Expected gcCount to be %v, got %v", numElements, + gcCount) + } +} + +/* +This test is quite hacky because it relies on SetFinalizer +which isn't guaranteed to run at all. +*/ +func TestGCRandom(t *testing.T) { + + const numElements = 1000000 + l := New() + gcCount := 0 + + // SetFinalizer doesn't work well with circular structures, + // so we construct a trivial non-circular structure to + // track. + type value struct { + Int int + } + + for i := 0; i < numElements; i++ { + v := new(value) + v.Int = i + l.PushBack(v) + runtime.SetFinalizer(v, func(v *value) { + gcCount += 1 + }) + } + + els := make([]*CElement, 0, numElements) + for el := l.Front(); el != nil; el = el.Next() { + els = append(els, el) + } + + for _, i := range rand.Perm(numElements) { + el := els[i] + l.Remove(el) + el = el.Next() + } + + runtime.GC() + time.Sleep(time.Second * 3) + + if gcCount != numElements { + t.Errorf("Expected gcCount to be %v, got %v", numElements, + gcCount) + } +} + +func TestScanRightDeleteRandom(t *testing.T) { + + const numElements = 10000 + const numTimes = 10000000 + const numScanners = 10 + + l := New() + stop := make(chan struct{}) + + els := make([]*CElement, numElements, numElements) + for i := 0; i < numElements; i++ { + el := l.PushBack(i) + els[i] = el + } + + // Launch scanner routines that will rapidly iterate over elements. + for i := 0; i < numScanners; i++ { + go func(scannerID int) { + var el *CElement + restartCounter := 0 + counter := 0 + FOR_LOOP: + for { + select { + case <-stop: + fmt.Println("stopped") + break FOR_LOOP + default: + } + if el == nil { + el = l.FrontWait() + restartCounter += 1 + } + el = el.Next() + counter += 1 + } + fmt.Printf("Scanner %v restartCounter: %v counter: %v\n", scannerID, restartCounter, counter) + }(i) + } + + // Remove an element, push back an element. + for i := 0; i < numTimes; i++ { + // Pick an element to remove + rmElIdx := rand.Intn(len(els)) + rmEl := els[rmElIdx] + + // Remove it + l.Remove(rmEl) + //fmt.Print(".") + + // Insert a new element + newEl := l.PushBack(-1*i - 1) + els[rmElIdx] = newEl + + if i%100000 == 0 { + fmt.Printf("Pushed %vK elements so far...\n", i/1000) + } + + } + + // Stop scanners + close(stop) + time.Sleep(time.Second * 1) + + // And remove all the elements. + for el := l.Front(); el != nil; el = el.Next() { + l.Remove(el) + } + if l.Len() != 0 { + t.Fatal("Failed to remove all elements from CList") + } +} diff --git a/Godeps/_workspace/src/github.com/tendermint/go-common/LICENSE.md b/Godeps/_workspace/src/github.com/tendermint/go-common/LICENSE.md new file mode 100644 index 00000000..aaf0cf06 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint Go-Common +Copyright (C) 2015 Tendermint + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/array.go b/Godeps/_workspace/src/github.com/tendermint/go-common/array.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/array.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/array.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/async.go b/Godeps/_workspace/src/github.com/tendermint/go-common/async.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/async.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/async.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/bit_array.go b/Godeps/_workspace/src/github.com/tendermint/go-common/bit_array.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/bit_array.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/bit_array.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/bit_array_test.go b/Godeps/_workspace/src/github.com/tendermint/go-common/bit_array_test.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/bit_array_test.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/bit_array_test.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/byteslice.go b/Godeps/_workspace/src/github.com/tendermint/go-common/byteslice.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/byteslice.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/byteslice.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/cmap.go b/Godeps/_workspace/src/github.com/tendermint/go-common/cmap.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/cmap.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/cmap.go diff --git a/Godeps/_workspace/src/github.com/tendermint/go-common/cmap_int.go b/Godeps/_workspace/src/github.com/tendermint/go-common/cmap_int.go new file mode 100644 index 00000000..dc7987a6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/cmap_int.go @@ -0,0 +1,62 @@ +package common + +import "sync" + +// CMapInt is a goroutine-safe map +type CMapInt struct { + m map[int]interface{} + l sync.Mutex +} + +func NewCMapInt() *CMapInt { + return &CMapInt{ + m: make(map[int]interface{}, 0), + } +} + +func (cm *CMapInt) Set(key int, value interface{}) { + cm.l.Lock() + defer cm.l.Unlock() + cm.m[key] = value +} + +func (cm *CMapInt) Get(key int) interface{} { + cm.l.Lock() + defer cm.l.Unlock() + return cm.m[key] +} + +func (cm *CMapInt) Has(key int) bool { + cm.l.Lock() + defer cm.l.Unlock() + _, ok := cm.m[key] + return ok +} + +func (cm *CMapInt) Delete(key int) { + cm.l.Lock() + defer cm.l.Unlock() + delete(cm.m, key) +} + +func (cm *CMapInt) Size() int { + cm.l.Lock() + defer cm.l.Unlock() + return len(cm.m) +} + +func (cm *CMapInt) Clear() { + cm.l.Lock() + defer cm.l.Unlock() + cm.m = make(map[int]interface{}, 0) +} + +func (cm *CMapInt) Values() []interface{} { + cm.l.Lock() + defer cm.l.Unlock() + items := []interface{}{} + for _, v := range cm.m { + items = append(items, v) + } + return items +} diff --git a/Godeps/_workspace/src/github.com/tendermint/go-common/cmap_test.go b/Godeps/_workspace/src/github.com/tendermint/go-common/cmap_test.go new file mode 100644 index 00000000..8822415c --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/cmap_test.go @@ -0,0 +1,71 @@ +package common + +import ( + "fmt" + "math/rand" + "testing" +) + +func TestMap(t *testing.T) { + + const numElements = 10000 + const numTimes = 10000000 + const numScanners = 10 + + els := make(map[int]struct{}) + for i := 0; i < numElements; i++ { + els[i] = struct{}{} + } + + // Remove an element, push back an element. + for i := 0; i < numTimes; i++ { + // Pick an element to remove + rmElIdx := rand.Intn(len(els)) + delete(els, rmElIdx) + + // Insert a new element + els[rmElIdx] = struct{}{} + + if i%100000 == 0 { + fmt.Printf("Pushed %vK elements so far...\n", i/1000) + } + + } +} + +func TestCMap(t *testing.T) { + + const numElements = 10000 + const numTimes = 10000000 + const numScanners = 10 + + els := NewCMapInt() + for i := 0; i < numElements; i++ { + els.Set(i, struct{}{}) + } + + // Launch scanner routines that will rapidly iterate over elements. + for i := 0; i < numScanners; i++ { + go func(scannerID int) { + counter := 0 + for { + els.Get(counter) + counter = (counter + 1) % numElements + } + }(i) + } + + // Remove an element, push back an element. + for i := 0; i < numTimes; i++ { + // Pick an element to remove + rmElIdx := rand.Intn(els.Size()) + els.Delete(rmElIdx) + + // Insert a new element + els.Set(rmElIdx, struct{}{}) + + if i%100000 == 0 { + fmt.Printf("Pushed %vK elements so far...\n", i/1000) + } + } +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/colors.go b/Godeps/_workspace/src/github.com/tendermint/go-common/colors.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/colors.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/colors.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/errors.go b/Godeps/_workspace/src/github.com/tendermint/go-common/errors.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/errors.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/errors.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/heap.go b/Godeps/_workspace/src/github.com/tendermint/go-common/heap.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/heap.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/heap.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/int.go b/Godeps/_workspace/src/github.com/tendermint/go-common/int.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/int.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/int.go diff --git a/Godeps/_workspace/src/github.com/tendermint/go-common/io.go b/Godeps/_workspace/src/github.com/tendermint/go-common/io.go new file mode 100644 index 00000000..378c19fc --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/io.go @@ -0,0 +1,75 @@ +package common + +import ( + "bytes" + "errors" + "io" +) + +type PrefixedReader struct { + Prefix []byte + reader io.Reader +} + +func NewPrefixedReader(prefix []byte, reader io.Reader) *PrefixedReader { + return &PrefixedReader{prefix, reader} +} + +func (pr *PrefixedReader) Read(p []byte) (n int, err error) { + if len(pr.Prefix) > 0 { + read := copy(p, pr.Prefix) + pr.Prefix = pr.Prefix[read:] + return read, nil + } else { + return pr.reader.Read(p) + } +} + +// NOTE: Not goroutine safe +type BufferCloser struct { + bytes.Buffer + Closed bool +} + +func NewBufferCloser(buf []byte) *BufferCloser { + return &BufferCloser{ + *bytes.NewBuffer(buf), + false, + } +} + +func (bc *BufferCloser) Close() error { + if bc.Closed { + return errors.New("BufferCloser already closed") + } + bc.Closed = true + return nil +} + +func (bc *BufferCloser) Write(p []byte) (n int, err error) { + if bc.Closed { + return 0, errors.New("Cannot write to closed BufferCloser") + } + return bc.Buffer.Write(p) +} + +func (bc *BufferCloser) WriteByte(c byte) error { + if bc.Closed { + return errors.New("Cannot write to closed BufferCloser") + } + return bc.Buffer.WriteByte(c) +} + +func (bc *BufferCloser) WriteRune(r rune) (n int, err error) { + if bc.Closed { + return 0, errors.New("Cannot write to closed BufferCloser") + } + return bc.Buffer.WriteRune(r) +} + +func (bc *BufferCloser) WriteString(s string) (n int, err error) { + if bc.Closed { + return 0, errors.New("Cannot write to closed BufferCloser") + } + return bc.Buffer.WriteString(s) +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/math.go b/Godeps/_workspace/src/github.com/tendermint/go-common/math.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/math.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/math.go diff --git a/Godeps/_workspace/src/github.com/tendermint/go-common/net.go b/Godeps/_workspace/src/github.com/tendermint/go-common/net.go new file mode 100644 index 00000000..2f9c9c8c --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/net.go @@ -0,0 +1,14 @@ +package common + +import ( + "net" + "strings" +) + +// protoAddr: e.g. "tcp://127.0.0.1:8080" or "unix:///tmp/test.sock" +func Connect(protoAddr string) (net.Conn, error) { + parts := strings.SplitN(protoAddr, "://", 2) + proto, address := parts[0], parts[1] + conn, err := net.Dial(proto, address) + return conn, err +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/os.go b/Godeps/_workspace/src/github.com/tendermint/go-common/os.go similarity index 88% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/os.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/os.go index 170c6f82..1d0b538d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/os.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/os.go @@ -36,9 +36,9 @@ func Exit(s string) { os.Exit(1) } -func EnsureDir(dir string) error { +func EnsureDir(dir string, mode os.FileMode) error { if _, err := os.Stat(dir); os.IsNotExist(err) { - err := os.MkdirAll(dir, 0700) + err := os.MkdirAll(dir, mode) if err != nil { return fmt.Errorf("Could not create directory %v. %v", dir, err) } @@ -64,8 +64,8 @@ func MustReadFile(filePath string) []byte { return fileBytes } -func WriteFile(filePath string, contents []byte) error { - err := ioutil.WriteFile(filePath, contents, 0600) +func WriteFile(filePath string, contents []byte, mode os.FileMode) error { + err := ioutil.WriteFile(filePath, contents, mode) if err != nil { return err } @@ -73,8 +73,8 @@ func WriteFile(filePath string, contents []byte) error { return nil } -func MustWriteFile(filePath string, contents []byte) { - err := WriteFile(filePath, contents) +func MustWriteFile(filePath string, contents []byte, mode os.FileMode) { + err := WriteFile(filePath, contents, mode) if err != nil { Exit(Fmt("MustWriteFile failed: %v", err)) } @@ -83,20 +83,20 @@ func MustWriteFile(filePath string, contents []byte) { // Writes to newBytes to filePath. // Guaranteed not to lose *both* oldBytes and newBytes, // (assuming that the OS is perfect) -func WriteFileAtomic(filePath string, newBytes []byte) error { +func WriteFileAtomic(filePath string, newBytes []byte, mode os.FileMode) error { // If a file already exists there, copy to filePath+".bak" (overwrite anything) if _, err := os.Stat(filePath); !os.IsNotExist(err) { fileBytes, err := ioutil.ReadFile(filePath) if err != nil { return fmt.Errorf("Could not read file %v. %v", filePath, err) } - err = ioutil.WriteFile(filePath+".bak", fileBytes, 0600) + err = ioutil.WriteFile(filePath+".bak", fileBytes, mode) if err != nil { return fmt.Errorf("Could not write file %v. %v", filePath+".bak", err) } } // Write newBytes to filePath.new - err := ioutil.WriteFile(filePath+".new", newBytes, 0600) + err := ioutil.WriteFile(filePath+".new", newBytes, mode) if err != nil { return fmt.Errorf("Could not write file %v. %v", filePath+".new", err) } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/random.go b/Godeps/_workspace/src/github.com/tendermint/go-common/random.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/random.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/random.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/repeat_timer.go b/Godeps/_workspace/src/github.com/tendermint/go-common/repeat_timer.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/repeat_timer.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/repeat_timer.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/service.go b/Godeps/_workspace/src/github.com/tendermint/go-common/service.go similarity index 96% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/service.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/service.go index 0c007f95..d2d8f2c1 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/service.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/service.go @@ -38,8 +38,11 @@ func (fs *FooService) OnStop() error { */ package common -import "sync/atomic" -import "github.com/tendermint/log15" +import ( + "sync/atomic" + + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" +) type Service interface { Start() (bool, error) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/string.go b/Godeps/_workspace/src/github.com/tendermint/go-common/string.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/string.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/string.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/test/assert.go b/Godeps/_workspace/src/github.com/tendermint/go-common/test/assert.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/test/assert.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/test/assert.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/test/mutate.go b/Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go similarity index 87% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/test/mutate.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go index 39bf9055..2c5a0156 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/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/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) // Contract: !bytes.Equal(input, output) && len(input) >= len(output) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/throttle_timer.go b/Godeps/_workspace/src/github.com/tendermint/go-common/throttle_timer.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/throttle_timer.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/throttle_timer.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/word.go b/Godeps/_workspace/src/github.com/tendermint/go-common/word.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/common/word.go rename to Godeps/_workspace/src/github.com/tendermint/go-common/word.go diff --git a/Godeps/_workspace/src/github.com/tendermint/go-config/LICENSE.md b/Godeps/_workspace/src/github.com/tendermint/go-config/LICENSE.md new file mode 100644 index 00000000..5315ab52 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-config/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint Go-Config +Copyright (C) 2015 Tendermint + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/config.go b/Godeps/_workspace/src/github.com/tendermint/go-config/config.go similarity index 53% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/config/config.go rename to Godeps/_workspace/src/github.com/tendermint/go-config/config.go index 43963e25..d0f2ccb3 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-config/config.go @@ -1,8 +1,11 @@ package config import ( + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/toml" "sync" "time" + + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) type Config interface { @@ -19,28 +22,66 @@ type Config interface { Set(key string, value interface{}) } -type MapConfig map[string]interface{} +type MapConfig struct { + required map[string]struct{} // blows up if trying to use before setting. + data map[string]interface{} +} + +func ReadMapConfigFromFile(filePath string) (MapConfig, error) { + var configData = make(map[string]interface{}) + fileBytes := MustReadFile(filePath) + err := toml.Unmarshal(fileBytes, configData) + if err != nil { + return MapConfig{}, err + } + return NewMapConfig(configData), nil +} + +func NewMapConfig(data map[string]interface{}) MapConfig { + if data == nil { + data = make(map[string]interface{}) + } + return MapConfig{ + required: make(map[string]struct{}), + data: data, + } +} -func (cfg MapConfig) Get(key string) interface{} { return cfg[key] } -func (cfg MapConfig) GetBool(key string) bool { return cfg[key].(bool) } -func (cfg MapConfig) GetFloat64(key string) float64 { return cfg[key].(float64) } -func (cfg MapConfig) GetInt(key string) int { return cfg[key].(int) } -func (cfg MapConfig) GetString(key string) string { return cfg[key].(string) } +func (cfg MapConfig) Get(key string) interface{} { + if _, ok := cfg.required[key]; ok { + PanicSanity(Fmt("config key %v is required but was not set.", key)) + } + return cfg.data[key] +} +func (cfg MapConfig) GetBool(key string) bool { return cfg.Get(key).(bool) } +func (cfg MapConfig) GetFloat64(key string) float64 { return cfg.Get(key).(float64) } +func (cfg MapConfig) GetInt(key string) int { return cfg.Get(key).(int) } +func (cfg MapConfig) GetString(key string) string { return cfg.Get(key).(string) } func (cfg MapConfig) GetStringMap(key string) map[string]interface{} { - return cfg[key].(map[string]interface{}) + return cfg.Get(key).(map[string]interface{}) } func (cfg MapConfig) GetStringMapString(key string) map[string]string { - return cfg[key].(map[string]string) + return cfg.Get(key).(map[string]string) +} +func (cfg MapConfig) GetStringSlice(key string) []string { return cfg.Get(key).([]string) } +func (cfg MapConfig) GetTime(key string) time.Time { return cfg.Get(key).(time.Time) } +func (cfg MapConfig) IsSet(key string) bool { _, ok := cfg.data[key]; return ok } +func (cfg MapConfig) Set(key string, value interface{}) { + delete(cfg.required, key) + cfg.data[key] = value } -func (cfg MapConfig) GetStringSlice(key string) []string { return cfg[key].([]string) } -func (cfg MapConfig) GetTime(key string) time.Time { return cfg[key].(time.Time) } -func (cfg MapConfig) IsSet(key string) bool { _, ok := cfg[key]; return ok } -func (cfg MapConfig) Set(key string, value interface{}) { cfg[key] = value } func (cfg MapConfig) SetDefault(key string, value interface{}) { + delete(cfg.required, key) + if cfg.IsSet(key) { + return + } + cfg.data[key] = value +} +func (cfg MapConfig) SetRequired(key string) { if cfg.IsSet(key) { return } - cfg[key] = value + cfg.required[key] = struct{}{} } //-------------------------------------------------------------------------------- diff --git a/Godeps/_workspace/src/github.com/tendermint/go-crypto/LICENSE.md b/Godeps/_workspace/src/github.com/tendermint/go-crypto/LICENSE.md new file mode 100644 index 00000000..25db84e6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint Go-Crypto +Copyright (C) 2015 Tendermint + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/priv_key.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go similarity index 71% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/account/priv_key.go rename to Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go index 5245a2d6..d81d5320 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/priv_key.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go @@ -1,10 +1,10 @@ -package account +package crypto import ( - "github.com/tendermint/ed25519" - "github.com/tendermint/ed25519/extra25519" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + "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. @@ -68,3 +68,10 @@ func GenPrivKeyEd25519() PrivKeyEd25519 { ed25519.MakePublicKey(privKeyBytes) return PrivKeyEd25519(*privKeyBytes) } + +func GenPrivKeyEd25519FromSecret(secret string) PrivKeyEd25519 { + privKey32 := wire.BinarySha256(secret) // Not Ripemd160 because we want 32 bytes. + privKeyBytes := new([64]byte) + copy(privKeyBytes[:32], privKey32) + return PrivKeyEd25519(*privKeyBytes) +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/pub_key.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go similarity index 80% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/account/pub_key.go rename to Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go index b5ee7dd8..cb9d368e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/pub_key.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go @@ -1,13 +1,13 @@ -package account +package crypto import ( "bytes" - "github.com/tendermint/ed25519" - "github.com/tendermint/ed25519/extra25519" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" - "golang.org/x/crypto/ripemd160" + "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. @@ -37,7 +37,7 @@ type PubKeyEd25519 [32]byte // 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(int64), new(error) + w, n, err := new(bytes.Buffer), new(int), new(error) wire.WriteBinary(pubKey[:], w, n, err) if *err != nil { PanicCrisis(*err) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/signature.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go similarity index 77% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/account/signature.go rename to Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go index 32dc8668..efa05793 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/signature.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go @@ -1,10 +1,10 @@ -package account +package crypto import ( "fmt" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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. diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/signature_test.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go similarity index 78% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/account/signature_test.go rename to Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go index 1d22cc69..daf6c1b3 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/signature_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go @@ -1,19 +1,18 @@ -package account +package crypto import ( "bytes" "testing" - "github.com/tendermint/ed25519" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + "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 + privKey := GenPrivKeyEd25519() + pubKey := privKey.PubKey() msg := CRandBytes(128) sig := privKey.Sign(msg) @@ -36,9 +35,8 @@ func TestSignAndValidate(t *testing.T) { func TestBinaryDecode(t *testing.T) { - privAccount := GenPrivAccount() - pubKey := privAccount.PubKey - privKey := privAccount.PrivKey + privKey := GenPrivKeyEd25519() + pubKey := privKey.PubKey() msg := CRandBytes(128) sig := privKey.Sign(msg) diff --git a/Godeps/_workspace/src/github.com/tendermint/go-db/LICENSE.md b/Godeps/_workspace/src/github.com/tendermint/go-db/LICENSE.md new file mode 100644 index 00000000..25c3191e --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint Go-DB +Copyright (C) 2015 Tendermint + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/db/config.go b/Godeps/_workspace/src/github.com/tendermint/go-db/config.go similarity index 60% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/db/config.go rename to Godeps/_workspace/src/github.com/tendermint/go-db/config.go index 8c24d2fd..fcd46e65 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/db/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/config.go @@ -1,7 +1,7 @@ package db import ( - cfg "github.com/tendermint/tendermint/config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/db/db.go b/Godeps/_workspace/src/github.com/tendermint/go-db/db.go similarity index 90% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/db/db.go rename to Godeps/_workspace/src/github.com/tendermint/go-db/db.go index 7c2bdaae..e60ac59a 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/db/db.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/db.go @@ -3,7 +3,7 @@ package db import ( "path" - . "github.com/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) type DB interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/db/level_db.go b/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go similarity index 78% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/db/level_db.go rename to Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go index 7dba5898..f0409b16 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/db/level_db.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go @@ -2,12 +2,13 @@ package db import ( "fmt" - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/opt" "path" - . "github.com/tendermint/tendermint/common" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb" + "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" ) type LevelDB struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/db/mem_db.go b/Godeps/_workspace/src/github.com/tendermint/go-db/mem_db.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/db/mem_db.go rename to Godeps/_workspace/src/github.com/tendermint/go-db/mem_db.go diff --git a/Godeps/_workspace/src/github.com/tendermint/go-logger/LICENSE.md b/Godeps/_workspace/src/github.com/tendermint/go-logger/LICENSE.md new file mode 100644 index 00000000..ee1d394d --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-logger/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint Go-Logger +Copyright (C) 2015 Tendermint + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/logger/config.go b/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go similarity index 67% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/logger/config.go rename to Godeps/_workspace/src/github.com/tendermint/go-logger/config.go index 88eb6b61..0c390168 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/logger/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go @@ -1,7 +1,7 @@ package logger import ( - cfg "github.com/tendermint/tendermint/config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/logger/log.go b/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go similarity index 68% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/logger/log.go rename to Godeps/_workspace/src/github.com/tendermint/go-logger/log.go index b2d0a5e3..663e4729 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/logger/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go @@ -3,8 +3,8 @@ package logger import ( "os" - "github.com/tendermint/log15" - . "github.com/tendermint/tendermint/common" + . "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" ) var rootHandler log15.Handler @@ -13,7 +13,7 @@ func init() { Reset() } -// You might want to call this after resetting tendermint/config. +// You might want to call this after resetting tendermint/go-config. func Reset() { var logLevel string = "debug" @@ -53,3 +53,12 @@ func getLevel(lvlString string) log15.Lvl { } return lvl } + +//---------------------------------------- +// Exported from log15 + +var LvlFilterHandler = log15.LvlFilterHandler +var LvlDebug = log15.LvlDebug +var LvlInfo = log15.LvlInfo +var LvlWarn = log15.LvlWarn +var LvlError = log15.LvlError diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/LICENSE.md b/Godeps/_workspace/src/github.com/tendermint/go-merkle/LICENSE.md new file mode 100644 index 00000000..e6e48bfd --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint Go-Merkle +Copyright (C) 2015 Tendermint + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/README.md b/Godeps/_workspace/src/github.com/tendermint/go-merkle/README.md similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/README.md rename to Godeps/_workspace/src/github.com/tendermint/go-merkle/README.md diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_node.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go similarity index 94% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_node.go rename to Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go index af9e7152..365b33b0 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_node.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go @@ -2,11 +2,11 @@ package merkle import ( "bytes" - "code.google.com/p/go.crypto/ripemd160" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" "io" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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" ) // Node @@ -35,7 +35,7 @@ func NewIAVLNode(key interface{}, value interface{}) *IAVLNode { // NOTE: The hash is not saved or set. The caller should set the hash afterwards. // (Presumably the caller already has the hash) -func ReadIAVLNode(t *IAVLTree, r io.Reader, n *int64, err *error) *IAVLNode { +func ReadIAVLNode(t *IAVLTree, r io.Reader, n *int, err *error) *IAVLNode { node := &IAVLNode{} // node header @@ -48,8 +48,8 @@ func ReadIAVLNode(t *IAVLTree, r io.Reader, n *int64, err *error) *IAVLNode { node.value = decodeByteSlice(t.valueCodec, r, n, err) } else { // children - node.leftHash = wire.ReadByteSlice(r, n, err) - node.rightHash = wire.ReadByteSlice(r, n, err) + node.leftHash = wire.ReadByteSlice(r, 0, n, err) + node.rightHash = wire.ReadByteSlice(r, 0, n, err) } return node } @@ -146,7 +146,7 @@ func (node *IAVLNode) hashWithCount(t *IAVLTree) ([]byte, int) { } // NOTE: sets hashes recursively -func (node *IAVLNode) writeHashBytes(t *IAVLTree, w io.Writer) (n int64, hashCount int, err error) { +func (node *IAVLNode) writeHashBytes(t *IAVLTree, w io.Writer) (n int, hashCount int, err error) { // height & size wire.WriteInt8(node.height, w, &n, &err) wire.WriteVarint(node.size, w, &n, &err) @@ -207,7 +207,7 @@ func (node *IAVLNode) save(t *IAVLTree) []byte { } // NOTE: sets hashes recursively -func (node *IAVLNode) writePersistBytes(t *IAVLTree, w io.Writer) (n int64, err error) { +func (node *IAVLNode) writePersistBytes(t *IAVLTree, w io.Writer) (n int, err error) { // node header wire.WriteInt8(node.height, w, &n, &err) wire.WriteVarint(node.size, w, &n, &err) @@ -439,18 +439,18 @@ func (node *IAVLNode) rmd(t *IAVLTree) *IAVLNode { //-------------------------------------------------------------------------------- // Read a (length prefixed) byteslice then decode the object using the codec -func decodeByteSlice(codec wire.Codec, r io.Reader, n *int64, err *error) interface{} { - bytez := wire.ReadByteSlice(r, n, err) +func decodeByteSlice(codec wire.Codec, r io.Reader, n *int, err *error) interface{} { + bytez := wire.ReadByteSlice(r, 0, n, err) if *err != nil { return nil } - n_ := new(int64) + n_ := new(int) return codec.Decode(bytes.NewBuffer(bytez), n_, err) } // Encode object using codec, then write a (length prefixed) byteslice. -func encodeByteSlice(o interface{}, codec wire.Codec, w io.Writer, n *int64, err *error) { - buf, n_ := new(bytes.Buffer), new(int64) +func encodeByteSlice(o interface{}, codec wire.Codec, w io.Writer, n *int, err *error) { + buf, n_ := new(bytes.Buffer), new(int) codec.Encode(o, buf, n_, err) if *err != nil { return diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_proof.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go similarity index 91% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_proof.go rename to Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go index 50cacdaf..b8a1b960 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_proof.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go @@ -3,10 +3,10 @@ package merkle import ( "bytes" - "code.google.com/p/go.crypto/ripemd160" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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" ) type IAVLProof struct { @@ -45,7 +45,7 @@ type IAVLProofInnerNode struct { func (branch IAVLProofInnerNode) Hash(childHash []byte) []byte { hasher := ripemd160.New() buf := new(bytes.Buffer) - n, err := int64(0), error(nil) + n, err := int(0), error(nil) wire.WriteInt8(branch.Height, buf, &n, &err) wire.WriteVarint(branch.Size, buf, &n, &err) if len(branch.Left) == 0 { @@ -71,7 +71,7 @@ type IAVLProofLeafNode struct { func (leaf IAVLProofLeafNode) Hash() []byte { hasher := ripemd160.New() buf := new(bytes.Buffer) - n, err := int64(0), error(nil) + n, err := int(0), error(nil) wire.WriteInt8(0, buf, &n, &err) wire.WriteVarint(1, buf, &n, &err) wire.WriteByteSlice(leaf.KeyBytes, buf, &n, &err) @@ -88,7 +88,7 @@ func (node *IAVLNode) constructProof(t *IAVLTree, key interface{}, proof *IAVLPr if node.height == 0 { if t.keyCodec.Compare(node.key, key) == 0 { keyBuf, valueBuf := new(bytes.Buffer), new(bytes.Buffer) - n, err := int64(0), error(nil) + n, err := int(0), error(nil) t.keyCodec.Encode(node.key, keyBuf, &n, &err) if err != nil { PanicCrisis(Fmt("Failed to encode node.key: %v", err)) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_test.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go similarity index 92% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_test.go rename to Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go index 457fe4fa..28679d7e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go @@ -4,15 +4,17 @@ import ( "bytes" "fmt" - . "github.com/tendermint/tendermint/common" - . "github.com/tendermint/tendermint/common/test" - "github.com/tendermint/tendermint/db" - "github.com/tendermint/tendermint/wire" + . "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" "runtime" "testing" ) +const testReadLimit = 1 << 20 // Some reasonable limit for wire.Read*() lmt + func randstr(length int) string { return RandStr(length) } @@ -246,8 +248,8 @@ func testProof(t *testing.T, proof *IAVLProof, keyBytes, valueBytes, rootHash [] } // Write/Read then verify. proofBytes := wire.BinaryBytes(proof) - n, err := int64(0), error(nil) - proof2 := wire.ReadBinary(&IAVLProof{}, bytes.NewBuffer(proofBytes), &n, &err).(*IAVLProof) + n, err := int(0), error(nil) + proof2 := wire.ReadBinary(&IAVLProof{}, bytes.NewBuffer(proofBytes), 0, &n, &err).(*IAVLProof) if err != nil { t.Errorf("Failed to read IAVLProof from bytes: %v", err) return @@ -260,8 +262,8 @@ func testProof(t *testing.T, proof *IAVLProof, keyBytes, valueBytes, rootHash [] // Random mutations must not verify for i := 0; i < 5; i++ { badProofBytes := MutateByteSlice(proofBytes) - n, err := int64(0), error(nil) - badProof := wire.ReadBinary(&IAVLProof{}, bytes.NewBuffer(badProofBytes), &n, &err).(*IAVLProof) + n, err := int(0), error(nil) + badProof := wire.ReadBinary(&IAVLProof{}, bytes.NewBuffer(badProofBytes), testReadLimit, &n, &err).(*IAVLProof) if err != nil { continue // This is fine. } @@ -275,7 +277,7 @@ func TestIAVLProof(t *testing.T) { // Convenient wrapper around wire.BasicCodec. toBytes := func(o interface{}) []byte { - buf, n, err := new(bytes.Buffer), int64(0), error(nil) + buf, n, err := new(bytes.Buffer), int(0), error(nil) wire.BasicCodec.Encode(o, buf, &n, &err) if err != nil { panic(Fmt("Failed to encode thing: %v", err)) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_tree.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go similarity index 95% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/iavl_tree.go rename to Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go index 4446f11d..7b9a2281 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/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/tendermint/tendermint/common" - dbm "github.com/tendermint/tendermint/db" - "github.com/tendermint/tendermint/wire" + . "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" ) /* @@ -210,11 +210,11 @@ func (ndb *nodeDB) GetNode(t *IAVLTree, hash []byte) *IAVLNode { // Doesn't exist, load. buf := ndb.db.Get(hash) if len(buf) == 0 { - ndb.db.(*dbm.LevelDB).Print() + ndb.db.Print() PanicSanity(Fmt("Value missing for key %X", hash)) } r := bytes.NewReader(buf) - var n int64 + var n int var err error node := ReadIAVLNode(t, r, &n, &err) if err != nil { diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/simple_tree.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go similarity index 95% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/simple_tree.go rename to Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go index ee65f401..7fd51a87 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/simple_tree.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go @@ -29,14 +29,14 @@ import ( "fmt" "sort" - "code.google.com/p/go.crypto/ripemd160" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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 SimpleHashFromTwoHashes(left []byte, right []byte) []byte { - var n int64 + var n int var err error var hasher = ripemd160.New() wire.WriteByteSlice(left, hasher, &n, &err) @@ -72,7 +72,7 @@ func SimpleHashFromBinaries(items []interface{}) []byte { // General Convenience func SimpleHashFromBinary(item interface{}) []byte { - hasher, n, err := ripemd160.New(), new(int64), new(error) + hasher, n, err := ripemd160.New(), new(int), new(error) wire.WriteBinary(item, hasher, n, err) if *err != nil { PanicCrisis(err) @@ -109,7 +109,7 @@ type KVPair struct { } func (kv KVPair) Hash() []byte { - hasher, n, err := ripemd160.New(), new(int64), new(error) + hasher, n, err := ripemd160.New(), new(int), new(error) wire.WriteString(kv.Key, hasher, n, err) if kvH, ok := kv.Value.(Hashable); ok { wire.WriteByteSlice(kvH.Hash(), hasher, n, err) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/simple_tree_test.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go similarity index 93% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/simple_tree_test.go rename to Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go index af6ff4df..5a1b0957 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/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/tendermint/tendermint/common" - . "github.com/tendermint/tendermint/common/test" + . "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" "fmt" "testing" diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/types.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/types.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/types.go rename to Godeps/_workspace/src/github.com/tendermint/go-merkle/types.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/util.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/util.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/merkle/util.go rename to Godeps/_workspace/src/github.com/tendermint/go-merkle/util.go diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/LICENSE.md b/Godeps/_workspace/src/github.com/tendermint/go-p2p/LICENSE.md new file mode 100644 index 00000000..ec02173e --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint P2P +Copyright (C) 2015 Tendermint + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/README.md b/Godeps/_workspace/src/github.com/tendermint/go-p2p/README.md similarity index 93% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/README.md rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/README.md index 6149d9c0..3fc02e2f 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/README.md +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/README.md @@ -1,6 +1,6 @@ -# `tendermint/p2p` +# `tendermint/go-p2p` -`tendermint/p2p` provides an abstraction around peer-to-peer communication.<br/> +`tendermint/go-p2p` provides an abstraction around peer-to-peer communication.<br/> ## Peer/MConnection/Channel @@ -70,7 +70,7 @@ for _, peer := range switch.Peers().List() { A `PEXReactor` reactor implementation is provided to automate peer discovery. ```go -book := p2p.NewAddrBook(config.App.GetString("AddrBookFile")) +book := p2p.NewAddrBook(addrBookFilePath) pexReactor := p2p.NewPEXReactor(book) ... switch := NewSwitch([]Reactor{pexReactor, myReactor, ...}) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/addrbook.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go similarity index 98% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/addrbook.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go index 9e244751..b827ae2c 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/addrbook.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go @@ -14,7 +14,7 @@ import ( "sync" "time" - . "github.com/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) const ( @@ -65,7 +65,8 @@ const ( minGetSelection = 32 // max addresses returned by GetSelection - maxGetSelection = 2500 + // NOTE: this must match "maxPexMessageSize" + maxGetSelection = 250 // current version of the on-disk format. serializationVersion = 1 @@ -317,7 +318,7 @@ func (a *AddrBook) saveToFile(filePath string) { log.Error("Failed to save AddrBook to file", "err", err) return } - err = WriteFileAtomic(filePath, jsonBytes) + err = WriteFileAtomic(filePath, jsonBytes, 0644) if err != nil { log.Error("Failed to save AddrBook to file", "file", filePath, "error", err) } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/addrbook_test.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook_test.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/addrbook_test.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook_test.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/connection.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go similarity index 88% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/connection.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go index f0c64178..adc64a10 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/connection.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go @@ -10,24 +10,25 @@ import ( "sync/atomic" "time" - flow "code.google.com/p/mxk/go1/flowcontrol" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" //"github.com/tendermint/log15" + 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" ) const ( - numBatchMsgPackets = 10 - minReadBufferSize = 1024 - minWriteBufferSize = 1024 - idleTimeoutMinutes = 5 - updateStatsSeconds = 2 - pingTimeoutSeconds = 40 - defaultSendRate = 51200 // 50Kb/s - defaultRecvRate = 51200 // 50Kb/s - flushThrottleMS = 100 - defaultSendQueueCapacity = 1 - defaultRecvBufferCapacity = 4096 - defaultSendTimeoutSeconds = 10 + numBatchMsgPackets = 10 + minReadBufferSize = 1024 + minWriteBufferSize = 1024 + idleTimeoutMinutes = 5 + updateStatsSeconds = 2 + pingTimeoutSeconds = 40 + defaultSendRate = 51200 // 50KB/s + defaultRecvRate = 51200 // 50KB/s + flushThrottleMS = 100 + defaultSendQueueCapacity = 1 + defaultRecvBufferCapacity = 4096 + defaultRecvMessageCapacity = 22020096 // 21MB + defaultSendTimeoutSeconds = 10 ) type receiveCbFunc func(chID byte, msgBytes []byte) @@ -259,7 +260,7 @@ func (c *MConnection) sendRoutine() { FOR_LOOP: for { - var n int64 + var n int var err error select { case <-c.flushTimer.Ch: @@ -313,7 +314,7 @@ func (c *MConnection) sendSomeMsgPackets() bool { // Block until .sendMonitor says we can write. // Once we're ready we send more than we asked for, // but amortized it should even out. - c.sendMonitor.Limit(maxMsgPacketSize, atomic.LoadInt64(&c.sendRate), true) + c.sendMonitor.Limit(maxMsgPacketTotalSize, atomic.LoadInt64(&c.sendRate), true) // Now send some msgPackets. for i := 0; i < numBatchMsgPackets; i++ { @@ -371,7 +372,7 @@ func (c *MConnection) recvRoutine() { FOR_LOOP: for { // Block until .recvMonitor says we can read. - c.recvMonitor.Limit(maxMsgPacketSize, atomic.LoadInt64(&c.recvRate), true) + c.recvMonitor.Limit(maxMsgPacketTotalSize, atomic.LoadInt64(&c.recvRate), true) /* // Peek into bufReader for debugging @@ -389,7 +390,7 @@ FOR_LOOP: */ // Read packet type - var n int64 + var n int var err error pktType := wire.ReadByte(c.bufReader, &n, &err) c.recvMonitor.Update(int(n)) @@ -411,8 +412,8 @@ FOR_LOOP: // do nothing log.Info("Receive Pong") case packetTypeMsg: - pkt, n, err := msgPacket{}, int64(0), error(nil) - wire.ReadBinaryPtr(&pkt, c.bufReader, &n, &err) + pkt, n, err := msgPacket{}, int(0), error(nil) + wire.ReadBinaryPtr(&pkt, c.bufReader, maxMsgPacketTotalSize, &n, &err) c.recvMonitor.Update(int(n)) if err != nil { if c.IsRunning() { @@ -456,10 +457,11 @@ FOR_LOOP: //----------------------------------------------------------------------------- type ChannelDescriptor struct { - ID byte - Priority int - SendQueueCapacity int - RecvBufferCapacity int + ID byte + Priority int + SendQueueCapacity int + RecvBufferCapacity int + RecvMessageCapacity int } func (chDesc *ChannelDescriptor) FillDefaults() { @@ -469,6 +471,9 @@ func (chDesc *ChannelDescriptor) FillDefaults() { if chDesc.RecvBufferCapacity == 0 { chDesc.RecvBufferCapacity = defaultRecvBufferCapacity } + if chDesc.RecvMessageCapacity == 0 { + chDesc.RecvMessageCapacity = defaultRecvMessageCapacity + } } // TODO: lowercase. @@ -557,27 +562,27 @@ func (ch *Channel) isSendPending() bool { func (ch *Channel) nextMsgPacket() msgPacket { packet := msgPacket{} packet.ChannelID = byte(ch.id) - packet.Bytes = ch.sending[:MinInt(maxMsgPacketSize, len(ch.sending))] - if len(ch.sending) <= maxMsgPacketSize { + packet.Bytes = ch.sending[:MinInt(maxMsgPacketPayloadSize, len(ch.sending))] + if len(ch.sending) <= maxMsgPacketPayloadSize { packet.EOF = byte(0x01) ch.sending = nil atomic.AddInt32(&ch.sendQueueSize, -1) // decrement sendQueueSize } else { packet.EOF = byte(0x00) - ch.sending = ch.sending[MinInt(maxMsgPacketSize, len(ch.sending)):] + ch.sending = ch.sending[MinInt(maxMsgPacketPayloadSize, len(ch.sending)):] } return packet } // Writes next msgPacket to w. // Not goroutine-safe -func (ch *Channel) writeMsgPacketTo(w io.Writer) (n int64, err error) { +func (ch *Channel) writeMsgPacketTo(w io.Writer) (n int, err error) { packet := ch.nextMsgPacket() log.Debug("Write Msg Packet", "conn", ch.conn, "packet", packet) wire.WriteByte(packetTypeMsg, w, &n, &err) wire.WriteBinary(packet, w, &n, &err) if err != nil { - ch.recentlySent += n + ch.recentlySent += int64(n) } return } @@ -586,7 +591,7 @@ func (ch *Channel) writeMsgPacketTo(w io.Writer) (n int64, err error) { // Not goroutine-safe func (ch *Channel) recvMsgPacket(packet msgPacket) ([]byte, error) { // log.Debug("Read Msg Packet", "conn", ch.conn, "packet", packet) - if wire.MaxBinaryReadSize < len(ch.recving)+len(packet.Bytes) { + if ch.desc.RecvMessageCapacity < len(ch.recving)+len(packet.Bytes) { return nil, wire.ErrBinaryReadSizeOverflow } ch.recving = append(ch.recving, packet.Bytes...) @@ -609,10 +614,12 @@ func (ch *Channel) updateStats() { //----------------------------------------------------------------------------- const ( - maxMsgPacketSize = 1024 - packetTypePing = byte(0x01) - packetTypePong = byte(0x02) - packetTypeMsg = byte(0x03) + maxMsgPacketPayloadSize = 1024 + maxMsgPacketOverheadSize = 10 // It's actually lower but good enough + maxMsgPacketTotalSize = maxMsgPacketPayloadSize + maxMsgPacketOverheadSize + packetTypePing = byte(0x01) + packetTypePong = byte(0x02) + packetTypeMsg = byte(0x03) ) // Messages in channels are chopped into smaller msgPackets for multiplexing. @@ -625,16 +632,3 @@ type msgPacket struct { func (p msgPacket) String() string { return fmt.Sprintf("MsgPacket{%X:%X T:%X}", p.ChannelID, p.Bytes, p.EOF) } - -//----------------------------------------------------------------------------- - -// Convenience struct for writing typed messages. -// Reading requires a custom decoder that switches on the first type byte of a byteslice. -type TypedMessage struct { - Type byte - Msg interface{} -} - -func (tm TypedMessage) String() string { - return fmt.Sprintf("TMsg{%X:%v}", tm.Type, tm.Msg) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/ip_range_counter.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/ip_range_counter.go new file mode 100644 index 00000000..85d9d407 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/ip_range_counter.go @@ -0,0 +1,29 @@ +package p2p + +import ( + "strings" +) + +// TODO Test +func AddToIPRangeCounts(counts map[string]int, ip string) map[string]int { + changes := make(map[string]int) + ipParts := strings.Split(ip, ":") + for i := 1; i < len(ipParts); i++ { + prefix := strings.Join(ipParts[:i], ":") + counts[prefix] += 1 + changes[prefix] = counts[prefix] + } + return changes +} + +// TODO Test +func CheckIPRangeCounts(counts map[string]int, limits []int) bool { + for prefix, count := range counts { + ipParts := strings.Split(prefix, ":") + numParts := len(ipParts) + if limits[numParts] < count { + return false + } + } + return true +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/listener.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go similarity index 93% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/listener.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go index 131d9695..9bb7c62d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/listener.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go @@ -6,8 +6,8 @@ import ( "strconv" "time" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/p2p/upnp" + . "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" ) type Listener interface { @@ -46,7 +46,8 @@ func splitHostPort(addr string) (host string, port int) { return host, port } -func NewDefaultListener(protocol string, lAddr string) Listener { +// skipUPNP: If true, does not try getUPNPExternalAddress() +func NewDefaultListener(protocol string, lAddr string, skipUPNP bool) Listener { // Local listen IP & port lAddrIP, lAddrPort := splitHostPort(lAddr) @@ -73,7 +74,7 @@ func NewDefaultListener(protocol string, lAddr string) Listener { // Determine external address... var extAddr *NetAddress - if !config.GetBool("skip_upnp") { + if !skipUPNP { // If the lAddrIP is INADDR_ANY, try UPnP if lAddrIP == "" || lAddrIP == "0.0.0.0" { extAddr = getUPNPExternalAddress(lAddrPort, listenerPort) diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go new file mode 100644 index 00000000..06f360e8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go @@ -0,0 +1,7 @@ +package p2p + +import ( + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" +) + +var log = logger.New("module", "p2p") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/netaddress.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go similarity index 98% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/netaddress.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go index 0730ab94..06615cd5 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/netaddress.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go @@ -10,7 +10,7 @@ import ( "strconv" "time" - . "github.com/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) type NetAddress struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go similarity index 74% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go index a03f8713..13f5d2a7 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go @@ -5,9 +5,8 @@ import ( "io" "net" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + . "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" ) type Peer struct { @@ -16,25 +15,25 @@ type Peer struct { outbound bool mconn *MConnection - *types.NodeInfo + *NodeInfo Key string Data *CMap // User data. } // NOTE: blocking // Before creating a peer with newPeer(), perform a handshake on connection. -func peerHandshake(conn net.Conn, ourNodeInfo *types.NodeInfo) (*types.NodeInfo, error) { - var peerNodeInfo = new(types.NodeInfo) +func peerHandshake(conn net.Conn, ourNodeInfo *NodeInfo) (*NodeInfo, error) { + var peerNodeInfo = new(NodeInfo) var err1 error var err2 error Parallel( func() { - var n int64 + var n int wire.WriteBinary(ourNodeInfo, conn, &n, &err1) }, func() { - var n int64 - wire.ReadBinary(peerNodeInfo, conn, &n, &err2) + var n int + wire.ReadBinary(peerNodeInfo, conn, maxNodeInfoSize, &n, &err2) log.Notice("Peer handshake", "peerNodeInfo", peerNodeInfo) }) if err1 != nil { @@ -43,11 +42,12 @@ func peerHandshake(conn net.Conn, ourNodeInfo *types.NodeInfo) (*types.NodeInfo, if err2 != nil { return nil, err2 } + peerNodeInfo.RemoteAddr = conn.RemoteAddr().String() return peerNodeInfo, nil } // NOTE: call peerHandshake on conn before calling newPeer(). -func newPeer(conn net.Conn, peerNodeInfo *types.NodeInfo, outbound bool, reactorsByCh map[byte]Reactor, chDescs []*ChannelDescriptor, onPeerError func(*Peer, interface{})) *Peer { +func newPeer(conn net.Conn, peerNodeInfo *NodeInfo, outbound bool, reactorsByCh map[byte]Reactor, chDescs []*ChannelDescriptor, onPeerError func(*Peer, interface{})) *Peer { var p *Peer onReceive := func(chID byte, msgBytes []byte) { reactor := reactorsByCh[chID] @@ -113,7 +113,9 @@ func (p *Peer) CanSend(chID byte) bool { } func (p *Peer) WriteTo(w io.Writer) (n int64, err error) { - wire.WriteString(p.Key, w, &n, &err) + var n_ int + wire.WriteString(p.Key, w, &n_, &err) + n += int64(n_) return } @@ -128,3 +130,7 @@ func (p *Peer) String() string { func (p *Peer) Equals(other *Peer) bool { return p.Key == other.Key } + +func (p *Peer) Get(key string) interface{} { + return p.Data.Get(key) +} diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set.go new file mode 100644 index 00000000..f3bc1eda --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set.go @@ -0,0 +1,115 @@ +package p2p + +import ( + "sync" +) + +// IPeerSet has a (immutable) subset of the methods of PeerSet. +type IPeerSet interface { + Has(key string) bool + Get(key string) *Peer + List() []*Peer + Size() int +} + +//----------------------------------------------------------------------------- + +// PeerSet is a special structure for keeping a table of peers. +// Iteration over the peers is super fast and thread-safe. +// We also track how many peers per IP range and avoid too many +type PeerSet struct { + mtx sync.Mutex + lookup map[string]*peerSetItem + list []*Peer +} + +type peerSetItem struct { + peer *Peer + index int +} + +func NewPeerSet() *PeerSet { + return &PeerSet{ + lookup: make(map[string]*peerSetItem), + list: make([]*Peer, 0, 256), + } +} + +// Returns false if peer with key (PubKeyEd25519) is already in set +// or if we have too many peers from the peer's IP range +func (ps *PeerSet) Add(peer *Peer) error { + ps.mtx.Lock() + defer ps.mtx.Unlock() + if ps.lookup[peer.Key] != nil { + return ErrSwitchDuplicatePeer + } + + index := len(ps.list) + // Appending is safe even with other goroutines + // iterating over the ps.list slice. + ps.list = append(ps.list, peer) + ps.lookup[peer.Key] = &peerSetItem{peer, index} + return nil +} + +func (ps *PeerSet) Has(peerKey string) bool { + ps.mtx.Lock() + defer ps.mtx.Unlock() + _, ok := ps.lookup[peerKey] + return ok +} + +func (ps *PeerSet) Get(peerKey string) *Peer { + ps.mtx.Lock() + defer ps.mtx.Unlock() + item, ok := ps.lookup[peerKey] + if ok { + return item.peer + } else { + return nil + } +} + +func (ps *PeerSet) Remove(peer *Peer) { + ps.mtx.Lock() + defer ps.mtx.Unlock() + item := ps.lookup[peer.Key] + if item == nil { + return + } + + index := item.index + // Copy the list but without the last element. + // (we must copy because we're mutating the list) + newList := make([]*Peer, len(ps.list)-1) + copy(newList, ps.list) + // If it's the last peer, that's an easy special case. + if index == len(ps.list)-1 { + ps.list = newList + delete(ps.lookup, peer.Key) + return + } + + // Move the last item from ps.list to "index" in list. + lastPeer := ps.list[len(ps.list)-1] + lastPeerKey := lastPeer.Key + lastPeerItem := ps.lookup[lastPeerKey] + newList[index] = lastPeer + lastPeerItem.index = index + ps.list = newList + delete(ps.lookup, peer.Key) + +} + +func (ps *PeerSet) Size() int { + ps.mtx.Lock() + defer ps.mtx.Unlock() + return len(ps.list) +} + +// threadsafe list of peers. +func (ps *PeerSet) List() []*Peer { + ps.mtx.Lock() + defer ps.mtx.Unlock() + return ps.list +} 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 new file mode 100644 index 00000000..50454369 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go @@ -0,0 +1,67 @@ +package p2p + +import ( + "math/rand" + "testing" + + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" +) + +// Returns an empty dummy peer +func randPeer() *Peer { + return &Peer{ + Key: RandStr(12), + NodeInfo: &NodeInfo{ + RemoteAddr: Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256), + ListenAddr: Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256), + }, + } +} + +func TestAddRemoveOne(t *testing.T) { + peerSet := NewPeerSet() + + peer := randPeer() + err := peerSet.Add(peer) + if err != nil { + t.Errorf("Failed to add new peer") + } + if peerSet.Size() != 1 { + t.Errorf("Failed to add new peer and increment size") + } + + peerSet.Remove(peer) + if peerSet.Has(peer.Key) { + t.Errorf("Failed to remove peer") + } + if peerSet.Size() != 0 { + t.Errorf("Failed to remove peer and decrement size") + } +} + +func TestAddRemoveMany(t *testing.T) { + peerSet := NewPeerSet() + + peers := []*Peer{} + N := 100 + for i := 0; i < N; i++ { + peer := randPeer() + if err := peerSet.Add(peer); err != nil { + t.Errorf("Failed to add new peer") + } + if peerSet.Size() != i+1 { + t.Errorf("Failed to add new peer and increment size") + } + peers = append(peers, peer) + } + + for i, peer := range peers { + peerSet.Remove(peer) + if peerSet.Has(peer.Key) { + t.Errorf("Failed to remove peer") + } + if peerSet.Size() != len(peers)-i-1 { + t.Errorf("Failed to remove peer and decrement size") + } + } +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/pex_reactor.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go similarity index 92% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/pex_reactor.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go index e203063c..0e28156b 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/pex_reactor.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go @@ -8,9 +8,8 @@ import ( "reflect" "time" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/wire" + . "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" ) var pexErrInvalidMessage = errors.New("Invalid PEX message") @@ -19,6 +18,7 @@ const ( PexChannel = byte(0x00) ensurePeersPeriodSeconds = 30 minNumOutboundPeers = 10 + maxPexMessageSize = 1048576 // 1MB ) /* @@ -30,7 +30,6 @@ type PEXReactor struct { sw *Switch book *AddrBook - evsw events.Fireable } func NewPEXReactor(book *AddrBook) *PEXReactor { @@ -65,7 +64,7 @@ func (pexR *PEXReactor) GetChannels() []*ChannelDescriptor { // Implements Reactor func (pexR *PEXReactor) AddPeer(peer *Peer) { // Add the peer to the address book - netAddr := NewNetAddressString(fmt.Sprintf("%s:%d", peer.Host, peer.P2PPort)) + netAddr := NewNetAddressString(peer.ListenAddr) if peer.IsOutbound() { if pexR.book.NeedMoreAddrs() { pexR.RequestPEX(peer) @@ -211,11 +210,6 @@ func (pexR *PEXReactor) ensurePeers() { } } -// implements events.Eventable -func (pexR *PEXReactor) SetFireable(evsw events.Fireable) { - pexR.evsw = evsw -} - //----------------------------------------------------------------------------- // Messages @@ -234,9 +228,9 @@ var _ = wire.RegisterInterface( func DecodeMessage(bz []byte) (msgType byte, msg PexMessage, err error) { msgType = bz[0] - n := new(int64) + n := new(int) r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ PexMessage }{}, r, n, &err).(struct{ PexMessage }).PexMessage + msg = wire.ReadBinary(struct{ PexMessage }{}, r, maxPexMessageSize, n, &err).(struct{ PexMessage }).PexMessage return } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/secret_connection.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go similarity index 85% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/secret_connection.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go index 732521f4..fe319ace 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/secret_connection.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go @@ -16,13 +16,13 @@ import ( "net" "time" - "golang.org/x/crypto/nacl/box" - "golang.org/x/crypto/nacl/secretbox" - "golang.org/x/crypto/ripemd160" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/nacl/box" + "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" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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" ) // 2 + 1024 == 1026 total frame size @@ -38,7 +38,7 @@ type SecretConnection struct { recvBuffer []byte recvNonce *[24]byte sendNonce *[24]byte - remPubKey acm.PubKeyEd25519 + remPubKey crypto.PubKeyEd25519 shrSecret *[32]byte // shared secret } @@ -46,9 +46,9 @@ type SecretConnection struct { // Returns nil if error in handshake. // Caller should call conn.Close() // See docs/sts-final.pdf for more information. -func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey acm.PrivKeyEd25519) (*SecretConnection, error) { +func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKeyEd25519) (*SecretConnection, error) { - locPubKey := locPrivKey.PubKey().(acm.PubKeyEd25519) + locPubKey := locPrivKey.PubKey().(crypto.PubKeyEd25519) // Generate ephemeral keys for perfect forward secrecy. locEphPub, locEphPriv := genEphKeys() @@ -101,7 +101,7 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey acm.PrivKeyEd25519 } // Returns authenticated remote pubkey -func (sc *SecretConnection) RemotePubKey() acm.PubKeyEd25519 { +func (sc *SecretConnection) RemotePubKey() crypto.PubKeyEd25519 { return sc.remPubKey } @@ -254,17 +254,17 @@ func genChallenge(loPubKey, hiPubKey *[32]byte) (challenge *[32]byte) { return hash32(append(loPubKey[:], hiPubKey[:]...)) } -func signChallenge(challenge *[32]byte, locPrivKey acm.PrivKeyEd25519) (signature acm.SignatureEd25519) { - signature = locPrivKey.Sign(challenge[:]).(acm.SignatureEd25519) +func signChallenge(challenge *[32]byte, locPrivKey crypto.PrivKeyEd25519) (signature crypto.SignatureEd25519) { + signature = locPrivKey.Sign(challenge[:]).(crypto.SignatureEd25519) return } type authSigMessage struct { - Key acm.PubKeyEd25519 - Sig acm.SignatureEd25519 + Key crypto.PubKeyEd25519 + Sig crypto.SignatureEd25519 } -func shareAuthSignature(sc *SecretConnection, pubKey acm.PubKeyEd25519, signature acm.SignatureEd25519) (*authSigMessage, error) { +func shareAuthSignature(sc *SecretConnection, pubKey crypto.PubKeyEd25519, signature crypto.SignatureEd25519) (*authSigMessage, error) { var recvMsg authSigMessage var err1, err2 error @@ -279,8 +279,8 @@ func shareAuthSignature(sc *SecretConnection, pubKey acm.PubKeyEd25519, signatur if err2 != nil { return } - n := int64(0) // not used. - recvMsg = wire.ReadBinary(authSigMessage{}, bytes.NewBuffer(readBuffer), &n, &err2).(authSigMessage) + n := int(0) // not used. + recvMsg = wire.ReadBinary(authSigMessage{}, bytes.NewBuffer(readBuffer), authSigMsgSize, &n, &err2).(authSigMessage) }) if err1 != nil { @@ -293,7 +293,7 @@ func shareAuthSignature(sc *SecretConnection, pubKey acm.PubKeyEd25519, signatur return &recvMsg, nil } -func verifyChallengeSignature(challenge *[32]byte, remPubKey acm.PubKeyEd25519, remSignature acm.SignatureEd25519) bool { +func verifyChallengeSignature(challenge *[32]byte, remPubKey crypto.PubKeyEd25519, remSignature crypto.SignatureEd25519) bool { return remPubKey.VerifyBytes(challenge[:], remSignature) } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/secret_connection_test.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go similarity index 92% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/secret_connection_test.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go index 28921ff7..9f40250b 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/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" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" + . "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" ) type dummyConn struct { @@ -32,10 +32,10 @@ func makeDummyConnPair() (fooConn, barConn dummyConn) { func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection) { fooConn, barConn := makeDummyConnPair() - fooPrvKey := acm.GenPrivKeyEd25519() - fooPubKey := fooPrvKey.PubKey().(acm.PubKeyEd25519) - barPrvKey := acm.GenPrivKeyEd25519() - barPubKey := barPrvKey.PubKey().(acm.PubKeyEd25519) + fooPrvKey := crypto.GenPrivKeyEd25519() + fooPubKey := fooPrvKey.PubKey().(crypto.PubKeyEd25519) + barPrvKey := crypto.GenPrivKeyEd25519() + barPubKey := barPrvKey.PubKey().(crypto.PubKeyEd25519) Parallel( func() { @@ -89,7 +89,7 @@ func TestSecretConnectionReadWrite(t *testing.T) { genNodeRunner := func(nodeConn dummyConn, nodeWrites []string, nodeReads *[]string) func() { return func() { // Node handskae - nodePrvKey := acm.GenPrivKeyEd25519() + nodePrvKey := crypto.GenPrivKeyEd25519() nodeSecretConn, err := MakeSecretConnection(nodeConn, nodePrvKey) if err != nil { t.Errorf("Failed to establish SecretConnection for node: %v", err) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/switch.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go similarity index 89% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/switch.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go index d260cf03..486b8999 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/switch.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go @@ -4,13 +4,11 @@ import ( "errors" "fmt" "net" - "strconv" "time" - "github.com/tendermint/log15" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" + . "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" ) type Reactor interface { @@ -62,8 +60,8 @@ type Switch struct { reactorsByCh map[byte]Reactor peers *PeerSet dialing *CMap - nodeInfo *types.NodeInfo // our node info - nodePrivKey acm.PrivKeyEd25519 // our node privkey + nodeInfo *NodeInfo // our node info + nodePrivKey crypto.PrivKeyEd25519 // our node privkey } var ( @@ -134,21 +132,21 @@ func (sw *Switch) IsListening() bool { } // Not goroutine safe. -func (sw *Switch) SetNodeInfo(nodeInfo *types.NodeInfo) { +func (sw *Switch) SetNodeInfo(nodeInfo *NodeInfo) { sw.nodeInfo = nodeInfo } // Not goroutine safe. -func (sw *Switch) NodeInfo() *types.NodeInfo { +func (sw *Switch) NodeInfo() *NodeInfo { return sw.nodeInfo } // Not goroutine safe. // NOTE: Overwrites sw.nodeInfo.PubKey -func (sw *Switch) SetNodePrivKey(nodePrivKey acm.PrivKeyEd25519) { +func (sw *Switch) SetNodePrivKey(nodePrivKey crypto.PrivKeyEd25519) { sw.nodePrivKey = nodePrivKey if sw.nodeInfo != nil { - sw.nodeInfo.PubKey = nodePrivKey.PubKey().(acm.PubKeyEd25519) + sw.nodeInfo.PubKey = nodePrivKey.PubKey().(crypto.PubKeyEd25519) } } @@ -226,15 +224,6 @@ func (sw *Switch) AddPeerWithConnection(conn net.Conn, outbound bool) (*Peer, er return nil, err } - // The peerNodeInfo is not verified, so overwrite - // the IP, and the port too if we dialed out - // Everything else we just have to trust - ip, port, _ := net.SplitHostPort(sconn.RemoteAddr().String()) - peerNodeInfo.Host = ip - if outbound { - porti, _ := strconv.Atoi(port) - peerNodeInfo.P2PPort = uint16(porti) - } peer := newPeer(sconn, peerNodeInfo, outbound, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError) // Add the peer to .peers @@ -358,12 +347,6 @@ func (sw *Switch) listenerRoutine(l Listener) { continue } - // Ignore connections from IP ranges for which we have too many - if sw.peers.HasMaxForIPRange(inConn) { - log.Info("Ignoring inbound connection: already have enough peers for that IP range", "address", inConn.RemoteAddr().String()) - continue - } - // New inbound connection! _, err := sw.AddPeerWithConnection(inConn, false) if err != nil { diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/switch_test.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go similarity index 89% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/switch_test.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go index ac4d35cf..93e3a7df 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/switch_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go @@ -6,11 +6,9 @@ import ( "testing" "time" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - _ "github.com/tendermint/tendermint/config/tendermint_test" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + . "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" ) type PeerMessage struct { @@ -72,24 +70,24 @@ func (tr *TestReactor) Receive(chID byte, peer *Peer, msgBytes []byte) { // convenience method for creating two switches connected to each other. func makeSwitchPair(t testing.TB, initSwitch func(*Switch) *Switch) (*Switch, *Switch) { - s1PrivKey := acm.GenPrivKeyEd25519() - s2PrivKey := acm.GenPrivKeyEd25519() + s1PrivKey := crypto.GenPrivKeyEd25519() + s2PrivKey := crypto.GenPrivKeyEd25519() // Create two switches that will be interconnected. s1 := initSwitch(NewSwitch()) - s1.SetNodeInfo(&types.NodeInfo{ - PubKey: s1PrivKey.PubKey().(acm.PubKeyEd25519), + s1.SetNodeInfo(&NodeInfo{ + PubKey: s1PrivKey.PubKey().(crypto.PubKeyEd25519), Moniker: "switch1", - ChainID: "testing", - Version: types.Versions{Tendermint: "123.123.123"}, + Network: "testing", + Version: "123.123.123", }) s1.SetNodePrivKey(s1PrivKey) s2 := initSwitch(NewSwitch()) - s2.SetNodeInfo(&types.NodeInfo{ - PubKey: s2PrivKey.PubKey().(acm.PubKeyEd25519), + s2.SetNodeInfo(&NodeInfo{ + PubKey: s2PrivKey.PubKey().(crypto.PubKeyEd25519), Moniker: "switch2", - ChainID: "testing", - Version: types.Versions{Tendermint: "123.123.123"}, + Network: "testing", + Version: "123.123.123", }) s2.SetNodePrivKey(s2PrivKey) @@ -98,7 +96,7 @@ func makeSwitchPair(t testing.TB, initSwitch func(*Switch) *Switch) (*Switch, *S s2.Start() // Create a listener for s1 - l := NewDefaultListener("tcp", ":8001") + l := NewDefaultListener("tcp", ":8001", true) // Dial the listener & add the connection to s2. lAddr := l.ExternalAddress() diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go new file mode 100644 index 00000000..5a0e8b35 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go @@ -0,0 +1,77 @@ +package p2p + +import ( + "fmt" + "net" + "strconv" + "strings" + + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" +) + +const maxNodeInfoSize = 10240 // 10Kb + +type NodeInfo struct { + PubKey crypto.PubKeyEd25519 `json:"pub_key"` + Moniker string `json:"moniker"` + Network string `json:"network"` + RemoteAddr string `json:"remote_addr"` + ListenAddr string `json:"listen_addr"` + Version string `json:"version"` // major.minor.revision + Other []string `json:"other"` // other application specific data +} + +// CONTRACT: two nodes are compactible if the major/minor versions match and network match +func (info *NodeInfo) CompatibleWith(other *NodeInfo) error { + iMajor, iMinor, _, iErr := splitVersion(info.Version) + oMajor, oMinor, _, oErr := splitVersion(other.Version) + + // if our own version number is not formatted right, we messed up + if iErr != nil { + return iErr + } + + // version number must be formatted correctly ("x.x.x") + if oErr != nil { + return oErr + } + + // major version must match + if iMajor != oMajor { + return fmt.Errorf("Peer is on a different major version. Got %v, expected %v", oMajor, iMajor) + } + + // minor version must match + if iMinor != oMinor { + return fmt.Errorf("Peer is on a different minor version. Got %v, expected %v", oMinor, iMinor) + } + + // nodes must be on the same network + if info.Network != other.Network { + return fmt.Errorf("Peer is on a different network. Got %v, expected %v", other.Network, info.Network) + } + + return nil +} + +func (info *NodeInfo) ListenHost() string { + host, _, _ := net.SplitHostPort(info.ListenAddr) + return host +} + +func (info *NodeInfo) ListenPort() int { + _, port, _ := net.SplitHostPort(info.ListenAddr) + port_i, err := strconv.Atoi(port) + if err != nil { + return -1 + } + return port_i +} + +func splitVersion(version string) (string, string, string, error) { + spl := strings.Split(version, ".") + if len(spl) != 3 { + return "", "", "", fmt.Errorf("Invalid version format %v", version) + } + return spl[0], spl[1], spl[2], nil +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/README.md b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/README.md similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/README.md rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/README.md 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 new file mode 100644 index 00000000..1b02cb12 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go @@ -0,0 +1,7 @@ +package upnp + +import ( + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" +) + +var log = logger.New("module", "upnp") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/probe.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go similarity index 96% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/probe.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go index 3f9f8ad9..9532729d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/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/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) type UPNPCapabilities struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/upnp.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/upnp.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/upnp.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/upnp.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/util.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/util.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/util.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/util.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/version.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/version.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/version.go rename to Godeps/_workspace/src/github.com/tendermint/go-p2p/version.go diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/LICENSE.md b/Godeps/_workspace/src/github.com/tendermint/go-wire/LICENSE.md new file mode 100644 index 00000000..a2c8ecdf --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/LICENSE.md @@ -0,0 +1,206 @@ +Tendermint Go-Wire +Copyright (C) 2015 Tendermint + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +//-------------------------------------------------------------------------------- + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/> + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/README.md b/Godeps/_workspace/src/github.com/tendermint/go-wire/README.md similarity index 94% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/README.md rename to Godeps/_workspace/src/github.com/tendermint/go-wire/README.md index 3108505e..e9b20bf1 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/README.md +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/README.md @@ -1,12 +1,4 @@ -### NOTICE - -This documentation is out of date. -* 0x00 is reserved as a nil byte for RegisterInterface -* moved TypeByte() into RegisterInterface/ConcreteType -* Pointers that don't have a declared TypeByte() are - encoded with a leading 0x00 (nil) or 0x01. - -# `tendermint/wire` +# `tendermint/go-wire` The `binary` submodule encodes primary types and structs into bytes. @@ -136,3 +128,14 @@ WriteBinary(Dog{}, buf, n, err) // Writes GreeterTypeDog byte dog_ := ReadBinary(Dog{}, buf, n, err) // Expects to read GreeterTypeDog byte dog := dog_.(Dog) // ok if *err != nil, otherwise dog_ == nil. ``` + +### Revisions + +This documentation is out of date. Here are some changes that still need documentation: + +* 0x00 is reserved as a nil byte for RegisterInterface +* moved TypeByte() into RegisterInterface/ConcreteType +* Pointers that don't have a declared TypeByte() are + encoded with a leading 0x00 (nil) or 0x01. +* ReadBinary\*, ReadString, ReadByteSlice, ReadByteSlices take a `lmt` parameter + diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/byteslice.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go similarity index 63% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/byteslice.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go index ee4bb941..71348817 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/byteslice.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go @@ -3,15 +3,15 @@ package wire import ( "io" - . "github.com/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) -func WriteByteSlice(bz []byte, w io.Writer, n *int64, err *error) { +func WriteByteSlice(bz []byte, w io.Writer, n *int, err *error) { WriteVarint(len(bz), w, n, err) WriteTo(bz, w, n, err) } -func ReadByteSlice(r io.Reader, n *int64, err *error) []byte { +func ReadByteSlice(r io.Reader, lmt int, n *int, err *error) []byte { length := ReadVarint(r, n, err) if *err != nil { return nil @@ -20,7 +20,7 @@ func ReadByteSlice(r io.Reader, n *int64, err *error) []byte { *err = ErrBinaryReadSizeUnderflow return nil } - if MaxBinaryReadSize < MaxInt64(int64(length), *n+int64(length)) { + if lmt != 0 && lmt < MaxInt(length, *n+length) { *err = ErrBinaryReadSizeOverflow return nil } @@ -32,7 +32,7 @@ func ReadByteSlice(r io.Reader, n *int64, err *error) []byte { //----------------------------------------------------------------------------- -func WriteByteSlices(bzz [][]byte, w io.Writer, n *int64, err *error) { +func WriteByteSlices(bzz [][]byte, w io.Writer, n *int, err *error) { WriteVarint(len(bzz), w, n, err) for _, bz := range bzz { WriteByteSlice(bz, w, n, err) @@ -42,7 +42,7 @@ func WriteByteSlices(bzz [][]byte, w io.Writer, n *int64, err *error) { } } -func ReadByteSlices(r io.Reader, n *int64, err *error) [][]byte { +func ReadByteSlices(r io.Reader, lmt int, n *int, err *error) [][]byte { length := ReadVarint(r, n, err) if *err != nil { return nil @@ -51,14 +51,14 @@ func ReadByteSlices(r io.Reader, n *int64, err *error) [][]byte { *err = ErrBinaryReadSizeUnderflow return nil } - if MaxBinaryReadSize < MaxInt64(int64(length), *n+int64(length)) { + if lmt != 0 && lmt < MaxInt(length, *n+length) { *err = ErrBinaryReadSizeOverflow return nil } bzz := make([][]byte, length) for i := 0; i < length; i++ { - bz := ReadByteSlice(r, n, err) + bz := ReadByteSlice(r, lmt, n, err) if *err != nil { return nil } diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice_test.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice_test.go new file mode 100644 index 00000000..1768e445 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice_test.go @@ -0,0 +1,86 @@ +package wire + +import ( + "bytes" + "testing" +) + +func TestReadByteSliceEquality(t *testing.T) { + + var buf = bytes.NewBuffer(nil) + var bufBytes []byte + + // Write a byteslice + var testBytes = []byte("ThisIsSomeTestArray") + var n int + var err error + WriteByteSlice(testBytes, buf, &n, &err) + if err != nil { + t.Error(err.Error()) + } + bufBytes = buf.Bytes() + + // Read the byteslice, should return the same byteslice + buf = bytes.NewBuffer(bufBytes) + var n2 int + res := ReadByteSlice(buf, 0, &n2, &err) + if err != nil { + t.Error(err.Error()) + } + if n != n2 { + t.Error("Read bytes did not match write bytes length") + } + + if !bytes.Equal(testBytes, res) { + t.Error("Returned the wrong bytes") + } + +} + +func TestReadByteSliceLimit(t *testing.T) { + + var buf = bytes.NewBuffer(nil) + var bufBytes []byte + + // Write a byteslice + var testBytes = []byte("ThisIsSomeTestArray") + var n int + var err error + WriteByteSlice(testBytes, buf, &n, &err) + if err != nil { + t.Error(err.Error()) + } + bufBytes = buf.Bytes() + + // Read the byteslice, should work fine with no limit. + buf = bytes.NewBuffer(bufBytes) + var n2 int + ReadByteSlice(buf, 0, &n2, &err) + if err != nil { + t.Error(err.Error()) + } + if n != n2 { + t.Error("Read bytes did not match write bytes length") + } + + // Limit to the byteslice length, should succeed. + buf = bytes.NewBuffer(bufBytes) + t.Logf("%X", bufBytes) + var n3 int + ReadByteSlice(buf, len(bufBytes), &n3, &err) + if err != nil { + t.Error(err.Error()) + } + if n != n3 { + t.Error("Read bytes did not match write bytes length") + } + + // Limit to the byteslice length, should succeed. + buf = bytes.NewBuffer(bufBytes) + var n4 int + ReadByteSlice(buf, len(bufBytes)-1, &n4, &err) + if err != ErrBinaryReadSizeOverflow { + t.Error("Expected ErrBinaryReadsizeOverflow") + } + +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/codec.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go similarity index 89% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/codec.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go index 63edb94a..bfd19652 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/codec.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go @@ -4,14 +4,14 @@ import ( "bytes" "errors" "fmt" - . "github.com/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" "io" "reflect" "time" ) -type Encoder func(o interface{}, w io.Writer, n *int64, err *error) -type Decoder func(r io.Reader, n *int64, err *error) interface{} +type Encoder func(o interface{}, w io.Writer, n *int, err *error) +type Decoder func(r io.Reader, n *int, err *error) interface{} type Comparator func(o1 interface{}, o2 interface{}) int type Codec struct { @@ -37,7 +37,7 @@ const ( typeTime = byte(0x20) ) -func BasicCodecEncoder(o interface{}, w io.Writer, n *int64, err *error) { +func BasicCodecEncoder(o interface{}, w io.Writer, n *int, err *error) { switch o := o.(type) { case nil: PanicSanity("nil type unsupported") @@ -88,7 +88,7 @@ func BasicCodecEncoder(o interface{}, w io.Writer, n *int64, err *error) { } } -func BasicCodecDecoder(r io.Reader, n *int64, err *error) (o interface{}) { +func BasicCodecDecoder(r io.Reader, n *int, err *error) (o interface{}) { type_ := ReadByte(r, n, err) if *err != nil { return @@ -117,9 +117,9 @@ func BasicCodecDecoder(r io.Reader, n *int64, err *error) (o interface{}) { case typeUvarint: o = ReadUvarint(r, n, err) case typeString: - o = ReadString(r, n, err) + o = ReadString(r, 0, n, err) case typeByteSlice: - o = ReadByteSlice(r, n, err) + o = ReadByteSlice(r, 0, n, err) case typeTime: o = ReadTime(r, n, err) default: diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/int.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/int.go similarity index 70% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/int.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/int.go index c63666fa..dee066cb 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/int.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/int.go @@ -8,11 +8,11 @@ import ( // Byte -func WriteByte(b byte, w io.Writer, n *int64, err *error) { +func WriteByte(b byte, w io.Writer, n *int, err *error) { WriteTo([]byte{b}, w, n, err) } -func ReadByte(r io.Reader, n *int64, err *error) byte { +func ReadByte(r io.Reader, n *int, err *error) byte { buf := make([]byte, 1) ReadFull(buf, r, n, err) return buf[0] @@ -20,34 +20,34 @@ func ReadByte(r io.Reader, n *int64, err *error) byte { // Int8 -func WriteInt8(i int8, w io.Writer, n *int64, err *error) { +func WriteInt8(i int8, w io.Writer, n *int, err *error) { WriteByte(byte(i), w, n, err) } -func ReadInt8(r io.Reader, n *int64, err *error) int8 { +func ReadInt8(r io.Reader, n *int, err *error) int8 { return int8(ReadByte(r, n, err)) } // Uint8 -func WriteUint8(i uint8, w io.Writer, n *int64, err *error) { +func WriteUint8(i uint8, w io.Writer, n *int, err *error) { WriteByte(byte(i), w, n, err) } -func ReadUint8(r io.Reader, n *int64, err *error) uint8 { +func ReadUint8(r io.Reader, n *int, err *error) uint8 { return uint8(ReadByte(r, n, err)) } // Int16 -func WriteInt16(i int16, w io.Writer, n *int64, err *error) { +func WriteInt16(i int16, w io.Writer, n *int, err *error) { buf := make([]byte, 2) binary.BigEndian.PutUint16(buf, uint16(i)) *n += 2 WriteTo(buf, w, n, err) } -func ReadInt16(r io.Reader, n *int64, err *error) int16 { +func ReadInt16(r io.Reader, n *int, err *error) int16 { buf := make([]byte, 2) ReadFull(buf, r, n, err) return int16(binary.BigEndian.Uint16(buf)) @@ -55,14 +55,14 @@ func ReadInt16(r io.Reader, n *int64, err *error) int16 { // Uint16 -func WriteUint16(i uint16, w io.Writer, n *int64, err *error) { +func WriteUint16(i uint16, w io.Writer, n *int, err *error) { buf := make([]byte, 2) binary.BigEndian.PutUint16(buf, uint16(i)) *n += 2 WriteTo(buf, w, n, err) } -func ReadUint16(r io.Reader, n *int64, err *error) uint16 { +func ReadUint16(r io.Reader, n *int, err *error) uint16 { buf := make([]byte, 2) ReadFull(buf, r, n, err) return uint16(binary.BigEndian.Uint16(buf)) @@ -70,7 +70,7 @@ func ReadUint16(r io.Reader, n *int64, err *error) uint16 { // []Uint16 -func WriteUint16s(iz []uint16, w io.Writer, n *int64, err *error) { +func WriteUint16s(iz []uint16, w io.Writer, n *int, err *error) { WriteUint32(uint32(len(iz)), w, n, err) for _, i := range iz { WriteUint16(i, w, n, err) @@ -80,7 +80,7 @@ func WriteUint16s(iz []uint16, w io.Writer, n *int64, err *error) { } } -func ReadUint16s(r io.Reader, n *int64, err *error) []uint16 { +func ReadUint16s(r io.Reader, n *int, err *error) []uint16 { length := ReadUint32(r, n, err) if *err != nil { return nil @@ -98,14 +98,14 @@ func ReadUint16s(r io.Reader, n *int64, err *error) []uint16 { // Int32 -func WriteInt32(i int32, w io.Writer, n *int64, err *error) { +func WriteInt32(i int32, w io.Writer, n *int, err *error) { buf := make([]byte, 4) binary.BigEndian.PutUint32(buf, uint32(i)) *n += 4 WriteTo(buf, w, n, err) } -func ReadInt32(r io.Reader, n *int64, err *error) int32 { +func ReadInt32(r io.Reader, n *int, err *error) int32 { buf := make([]byte, 4) ReadFull(buf, r, n, err) return int32(binary.BigEndian.Uint32(buf)) @@ -113,14 +113,14 @@ func ReadInt32(r io.Reader, n *int64, err *error) int32 { // Uint32 -func WriteUint32(i uint32, w io.Writer, n *int64, err *error) { +func WriteUint32(i uint32, w io.Writer, n *int, err *error) { buf := make([]byte, 4) binary.BigEndian.PutUint32(buf, uint32(i)) *n += 4 WriteTo(buf, w, n, err) } -func ReadUint32(r io.Reader, n *int64, err *error) uint32 { +func ReadUint32(r io.Reader, n *int, err *error) uint32 { buf := make([]byte, 4) ReadFull(buf, r, n, err) return uint32(binary.BigEndian.Uint32(buf)) @@ -128,14 +128,14 @@ func ReadUint32(r io.Reader, n *int64, err *error) uint32 { // Int64 -func WriteInt64(i int64, w io.Writer, n *int64, err *error) { +func WriteInt64(i int64, w io.Writer, n *int, err *error) { buf := make([]byte, 8) binary.BigEndian.PutUint64(buf, uint64(i)) *n += 8 WriteTo(buf, w, n, err) } -func ReadInt64(r io.Reader, n *int64, err *error) int64 { +func ReadInt64(r io.Reader, n *int, err *error) int64 { buf := make([]byte, 8) ReadFull(buf, r, n, err) return int64(binary.BigEndian.Uint64(buf)) @@ -143,14 +143,14 @@ func ReadInt64(r io.Reader, n *int64, err *error) int64 { // Uint64 -func WriteUint64(i uint64, w io.Writer, n *int64, err *error) { +func WriteUint64(i uint64, w io.Writer, n *int, err *error) { buf := make([]byte, 8) binary.BigEndian.PutUint64(buf, uint64(i)) *n += 8 WriteTo(buf, w, n, err) } -func ReadUint64(r io.Reader, n *int64, err *error) uint64 { +func ReadUint64(r io.Reader, n *int, err *error) uint64 { buf := make([]byte, 8) ReadFull(buf, r, n, err) return uint64(binary.BigEndian.Uint64(buf)) @@ -186,7 +186,7 @@ func uvarintSize(i uint64) int { return 8 } -func WriteVarint(i int, w io.Writer, n *int64, err *error) { +func WriteVarint(i int, w io.Writer, n *int, err *error) { var negate = false if i < 0 { negate = true @@ -204,10 +204,9 @@ func WriteVarint(i int, w io.Writer, n *int64, err *error) { binary.BigEndian.PutUint64(buf, uint64(i)) WriteTo(buf[(8-size):], w, n, err) } - *n += int64(1 + size) } -func ReadVarint(r io.Reader, n *int64, err *error) int { +func ReadVarint(r io.Reader, n *int, err *error) int { var size = ReadUint8(r, n, err) var negate = false if (size >> 4) == 0xF { @@ -226,7 +225,6 @@ func ReadVarint(r io.Reader, n *int64, err *error) int { } buf := make([]byte, 8) ReadFull(buf[(8-size):], r, n, err) - *n += int64(1 + size) var i = int(binary.BigEndian.Uint64(buf)) if negate { return -i @@ -237,7 +235,7 @@ func ReadVarint(r io.Reader, n *int64, err *error) int { // Uvarint -func WriteUvarint(i uint, w io.Writer, n *int64, err *error) { +func WriteUvarint(i uint, w io.Writer, n *int, err *error) { var size = uvarintSize(uint64(i)) WriteUint8(uint8(size), w, n, err) if size > 0 { @@ -245,10 +243,9 @@ func WriteUvarint(i uint, w io.Writer, n *int64, err *error) { binary.BigEndian.PutUint64(buf, uint64(i)) WriteTo(buf[(8-size):], w, n, err) } - *n += int64(1 + size) } -func ReadUvarint(r io.Reader, n *int64, err *error) uint { +func ReadUvarint(r io.Reader, n *int, err *error) uint { var size = ReadUint8(r, n, err) if size > 8 { setFirstErr(err, errors.New("Uvarint overflow")) @@ -259,7 +256,6 @@ func ReadUvarint(r io.Reader, n *int64, err *error) uint { } buf := make([]byte, 8) ReadFull(buf[(8-size):], r, n, err) - *n += int64(1 + size) return uint(binary.BigEndian.Uint64(buf)) } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/int_test.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/int_test.go similarity index 95% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/int_test.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/int_test.go index 3baceaa4..a48d6ead 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/int_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/int_test.go @@ -10,7 +10,7 @@ func TestVarint(t *testing.T) { check := func(i int, s string) { buf := new(bytes.Buffer) - n, err := new(int64), new(error) + n, err := new(int), new(error) WriteVarint(i, buf, n, err) bufBytes := buf.Bytes() // Read before consuming below. i_ := ReadVarint(buf, n, err) @@ -50,7 +50,7 @@ func TestUvarint(t *testing.T) { check := func(i uint, s string) { buf := new(bytes.Buffer) - n, err := new(int64), new(error) + n, err := new(int), new(error) WriteUvarint(i, buf, n, err) bufBytes := buf.Bytes() i_ := ReadUvarint(buf, n, err) diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go new file mode 100644 index 00000000..66e9e733 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go @@ -0,0 +1,17 @@ +package wire + +import ( + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" +) + +var log = logger.New("module", "binary") + +func init() { + log.SetHandler( + logger.LvlFilterHandler( + logger.LvlWarn, + //logger.LvlDebug, + logger.RootHandler(), + ), + ) +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/reflect.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go similarity index 91% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/reflect.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go index d964d585..cc4185e8 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/reflect.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go @@ -9,11 +9,7 @@ import ( "sync" "time" - . "github.com/tendermint/tendermint/common" -) - -const ( - ReflectSliceChunk = 1024 + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) type TypeInfo struct { @@ -33,7 +29,7 @@ type TypeInfo struct { type Options struct { JSONName string // (JSON) Corresponding JSON field name. (override with `json=""`) - Varint bool // (Binary) Use length-prefixed encoding for (u)int* + Varint bool // (Binary) Use length-prefixed encoding for (u)int64 } func getOptionsFromField(field reflect.StructField) (skip bool, opts Options) { @@ -179,7 +175,7 @@ func MakeTypeInfo(rt reflect.Type) *TypeInfo { // Contract: Caller must ensure that rt is supported // (e.g. is recursively composed of supported native types, and structs and slices.) -func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Reader, n *int64, err *error) { +func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Reader, lmt int, n *int, err *error) { // Get typeInfo typeInfo := GetTypeInfo(rt) @@ -204,7 +200,8 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea } crv := reflect.New(crt).Elem() r = NewPrefixedReader([]byte{typeByte}, r) - readReflectBinary(crv, crt, opts, r, n, err) + *n -= 1 // Must also rewind *n + readReflectBinary(crv, crt, opts, r, lmt, n, err) rv.Set(crv) // NOTE: orig rv is ignored. return } @@ -228,6 +225,7 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea typeInfo = GetTypeInfo(rt) if typeInfo.Byte != 0x00 { r = NewPrefixedReader([]byte{typeByte}, r) + *n -= 1 // Must also rewind *n } else if typeByte != 0x01 { *err = errors.New(Fmt("Unexpected type byte %X for ptr of untyped thing", typeByte)) return @@ -255,47 +253,47 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea if *err != nil { return } - log.Info("Read bytearray", "bytes", buf) + log.Info("Read bytearray", "bytes", buf, "n", *n) reflect.Copy(rv, reflect.ValueOf(buf)) } else { for i := 0; i < length; i++ { elemRv := rv.Index(i) - readReflectBinary(elemRv, elemRt, opts, r, n, err) + readReflectBinary(elemRv, elemRt, opts, r, lmt, n, err) if *err != nil { return } - if MaxBinaryReadSize < *n { + if lmt != 0 && lmt < *n { *err = ErrBinaryReadSizeOverflow return } } - log.Info(Fmt("Read %v-array", elemRt), "length", length) + log.Info("Read x-array", "x", elemRt, "length", length, "n", *n) } case reflect.Slice: elemRt := rt.Elem() if elemRt.Kind() == reflect.Uint8 { // Special case: Byteslices - byteslice := ReadByteSlice(r, n, err) - log.Info("Read byteslice", "bytes", byteslice) + byteslice := ReadByteSlice(r, lmt, n, err) + log.Info("Read byteslice", "bytes", byteslice, "n", *n) rv.Set(reflect.ValueOf(byteslice)) } else { var sliceRv reflect.Value // Read length length := ReadVarint(r, n, err) - log.Info(Fmt("Read length: %v", length)) + log.Info("Read slice", "length", length, "n", *n) sliceRv = reflect.MakeSlice(rt, 0, 0) - // read one ReflectSliceChunk at a time and append - for i := 0; i*ReflectSliceChunk < length; i++ { - l := MinInt(ReflectSliceChunk, length-i*ReflectSliceChunk) + // read one ReadSliceChunkSize at a time and append + for i := 0; i*ReadSliceChunkSize < length; i++ { + l := MinInt(ReadSliceChunkSize, length-i*ReadSliceChunkSize) tmpSliceRv := reflect.MakeSlice(rt, l, l) for j := 0; j < l; j++ { elemRv := tmpSliceRv.Index(j) - readReflectBinary(elemRv, elemRt, opts, r, n, err) + readReflectBinary(elemRv, elemRt, opts, r, lmt, n, err) if *err != nil { return } - if MaxBinaryReadSize < *n { + if lmt != 0 && lmt < *n { *err = ErrBinaryReadSizeOverflow return } @@ -310,86 +308,86 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea if rt == timeType { // Special case: time.Time t := ReadTime(r, n, err) - log.Info(Fmt("Read time: %v", t)) + log.Info("Read time", "t", t, "n", *n) rv.Set(reflect.ValueOf(t)) } else { for _, fieldInfo := range typeInfo.Fields { i, fieldType, opts := fieldInfo.unpack() fieldRv := rv.Field(i) - readReflectBinary(fieldRv, fieldType, opts, r, n, err) + readReflectBinary(fieldRv, fieldType, opts, r, lmt, n, err) } } case reflect.String: - str := ReadString(r, n, err) - log.Info(Fmt("Read string: %v", str)) + str := ReadString(r, lmt, n, err) + log.Info("Read string", "str", str, "n", *n) rv.SetString(str) case reflect.Int64: if opts.Varint { num := ReadVarint(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetInt(int64(num)) } else { num := ReadInt64(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetInt(int64(num)) } case reflect.Int32: num := ReadUint32(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetInt(int64(num)) case reflect.Int16: num := ReadUint16(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetInt(int64(num)) case reflect.Int8: num := ReadUint8(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetInt(int64(num)) case reflect.Int: num := ReadVarint(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetInt(int64(num)) case reflect.Uint64: if opts.Varint { num := ReadVarint(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetUint(uint64(num)) } else { num := ReadUint64(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetUint(uint64(num)) } case reflect.Uint32: num := ReadUint32(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetUint(uint64(num)) case reflect.Uint16: num := ReadUint16(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetUint(uint64(num)) case reflect.Uint8: num := ReadUint8(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetUint(uint64(num)) case reflect.Uint: num := ReadVarint(r, n, err) - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num, "n", *n) rv.SetUint(uint64(num)) case reflect.Bool: num := ReadUint8(r, n, err) - log.Info(Fmt("Read bool: %v", num)) + log.Info("Read bool", "bool", num, "n", *n) rv.SetBool(num > 0) default: @@ -399,7 +397,7 @@ func readReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, r io.Rea // rv: the reflection value of the thing to write // rt: the type of rv as declared in the container, not necessarily rv.Type(). -func writeReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, w io.Writer, n *int64, err *error) { +func writeReflectBinary(rv reflect.Value, rt reflect.Type, opts Options, w io.Writer, n *int, err *error) { // Get typeInfo typeInfo := GetTypeInfo(rt) @@ -685,7 +683,7 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro elemRv := rv.Index(i) readReflectJSON(elemRv, elemRt, oSlice[i], err) } - log.Info(Fmt("Read %v-array", elemRt), "length", length) + log.Info("Read x-array", "x", elemRt, "length", length) } case reflect.Slice: @@ -712,7 +710,7 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro return } length := len(oSlice) - log.Info(Fmt("Read length: %v", length)) + log.Info("Read slice", "length", length) sliceRv := reflect.MakeSlice(rt, length, length) // Read elems for i := 0; i < length; i++ { @@ -730,7 +728,7 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro *err = errors.New(Fmt("Expected string but got type %v", reflect.TypeOf(o))) return } - log.Info(Fmt("Read time: %v", str)) + log.Info("Read time", "t", str) t, err_ := time.Parse(iso8601, str) if err_ != nil { *err = err_ @@ -762,7 +760,7 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro *err = errors.New(Fmt("Expected string but got type %v", reflect.TypeOf(o))) return } - log.Info(Fmt("Read string: %v", str)) + log.Info("Read string", "str", str) rv.SetString(str) case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int: @@ -771,7 +769,7 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro *err = errors.New(Fmt("Expected numeric but got type %v", reflect.TypeOf(o))) return } - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num) rv.SetInt(int64(num)) case reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uint: @@ -784,7 +782,7 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro *err = errors.New(Fmt("Expected unsigned numeric but got %v", num)) return } - log.Info(Fmt("Read num: %v", num)) + log.Info("Read num", "num", num) rv.SetUint(uint64(num)) case reflect.Bool: @@ -793,7 +791,7 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro *err = errors.New(Fmt("Expected boolean but got type %v", reflect.TypeOf(o))) return } - log.Info(Fmt("Read boolean: %v", bl)) + log.Info("Read boolean", "boolean", bl) rv.SetBool(bl) default: @@ -801,7 +799,7 @@ func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *erro } } -func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int64, err *error) { +func writeReflectJSON(rv reflect.Value, rt reflect.Type, w io.Writer, n *int, err *error) { log.Info(Fmt("writeReflectJSON(%v, %v, %v, %v, %v)", rv, rt, w, n, err)) // Get typeInfo diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/reflect_test.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go similarity index 91% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/reflect_test.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go index b21b8bf2..8050ba5e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/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/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) type SimpleStruct struct { @@ -77,8 +77,8 @@ func TestAnimalInterface(t *testing.T) { snakeReader := bytes.NewReader(snakeBytes) // Now you can read it. - n, err := new(int64), new(error) - it := ReadBinary(foo, snakeReader, n, err).(Animal) + n, err := new(int), new(error) + it := ReadBinary(foo, snakeReader, 0, n, err).(Animal) fmt.Println(it, reflect.TypeOf(it)) } @@ -369,8 +369,8 @@ func TestBinary(t *testing.T) { instance, instancePtr := testCase.Instantiator() // Read onto a struct - n, err := new(int64), new(error) - res := ReadBinary(instance, bytes.NewReader(data), n, err) + n, err := new(int), new(error) + res := ReadBinary(instance, bytes.NewReader(data), 0, n, err) if *err != nil { t.Fatalf("Failed to read into instance: %v", *err) } @@ -379,18 +379,33 @@ func TestBinary(t *testing.T) { testCase.Validator(res, t) // Read onto a pointer - n, err = new(int64), new(error) - res = ReadBinaryPtr(instancePtr, bytes.NewReader(data), n, err) + n, err = new(int), new(error) + res = ReadBinaryPtr(instancePtr, bytes.NewReader(data), 0, n, err) if *err != nil { t.Fatalf("Failed to read into instance: %v", *err) } - if res != instancePtr { t.Errorf("Expected pointer to pass through") } // Validate object testCase.Validator(reflect.ValueOf(res).Elem().Interface(), t) + + // Read with len(data)-1 limit should fail. + instance, _ = testCase.Instantiator() + n, err = new(int), new(error) + ReadBinary(instance, bytes.NewReader(data), len(data)-1, n, err) + if *err != ErrBinaryReadSizeOverflow { + t.Fatalf("Expected ErrBinaryReadSizeOverflow") + } + + // Read with len(data) limit should succeed. + instance, _ = testCase.Instantiator() + n, err = new(int), new(error) + ReadBinary(instance, bytes.NewReader(data), len(data), n, err) + if *err != nil { + t.Fatalf("Failed to read instance with sufficient limit: %v", (*err).Error(), *n, len(data), reflect.TypeOf(instance)) + } } } @@ -459,14 +474,14 @@ func TestJSONFieldNames(t *testing.T) { //------------------------------------------------------------------------------ func TestBadAlloc(t *testing.T) { - n, err := new(int64), new(error) + n, err := new(int), new(error) instance := new([]byte) data := RandBytes(100 * 1024) b := new(bytes.Buffer) // this slice of data claims to be much bigger than it really is WriteUvarint(uint(10000000000000000), b, n, err) b.Write(data) - res := ReadBinary(instance, b, n, err) + res := ReadBinary(instance, b, 0, n, err) fmt.Println(res, *err) } @@ -499,8 +514,8 @@ func TestSimpleArray(t *testing.T) { fooReader := bytes.NewReader(fooBytes) // Now you can read it. - n, err := new(int64), new(error) - it := ReadBinary(foo, fooReader, n, err).(SimpleArray) + n, err := new(int), new(error) + it := ReadBinary(foo, fooReader, 0, n, err).(SimpleArray) if !bytes.Equal(it[:], fooArray[:]) { t.Errorf("Expected %v but got %v", fooArray, it) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/string.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go similarity index 58% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/string.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/string.go index 00ee3e99..e762221a 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/string.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go @@ -3,17 +3,17 @@ package wire import ( "io" - . "github.com/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) // String -func WriteString(s string, w io.Writer, n *int64, err *error) { +func WriteString(s string, w io.Writer, n *int, err *error) { WriteVarint(len(s), w, n, err) WriteTo([]byte(s), w, n, err) } -func ReadString(r io.Reader, n *int64, err *error) string { +func ReadString(r io.Reader, lmt int, n *int, err *error) string { length := ReadVarint(r, n, err) if *err != nil { return "" @@ -22,7 +22,7 @@ func ReadString(r io.Reader, n *int64, err *error) string { *err = ErrBinaryReadSizeUnderflow return "" } - if MaxBinaryReadSize < MaxInt64(int64(length), *n+int64(length)) { + if lmt != 0 && lmt < MaxInt(length, *n+length) { *err = ErrBinaryReadSizeOverflow return "" } diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/string_test.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/string_test.go new file mode 100644 index 00000000..2a4e3b1a --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/string_test.go @@ -0,0 +1,86 @@ +package wire + +import ( + "bytes" + "testing" +) + +func TestReadStringEquality(t *testing.T) { + + var buf = bytes.NewBuffer(nil) + var bufBytes []byte + + // Write a string + var testString = "ThisIsSomeTestString" + var n int + var err error + WriteString(testString, buf, &n, &err) + if err != nil { + t.Error(err.Error()) + } + bufBytes = buf.Bytes() + + // Read the string, should return the same string + buf = bytes.NewBuffer(bufBytes) + var n2 int + res := ReadString(buf, 0, &n2, &err) + if err != nil { + t.Error(err.Error()) + } + if n != n2 { + t.Error("Read string did not match write string length") + } + + if testString != res { + t.Error("Returned the wrong string") + } + +} + +func TestReadStringLimit(t *testing.T) { + + var buf = bytes.NewBuffer(nil) + var bufBytes []byte + + // Write a byteslice + var testString = string("ThisIsSomeTestString") + var n int + var err error + WriteString(testString, buf, &n, &err) + if err != nil { + t.Error(err.Error()) + } + bufBytes = buf.Bytes() + + // Read the string, should work fine with no limit. + buf = bytes.NewBuffer(bufBytes) + var n2 int + ReadString(buf, 0, &n2, &err) + if err != nil { + t.Error(err.Error()) + } + if n != n2 { + t.Error("Read string did not match write string length") + } + + // Limit to the string length, should succeed. + buf = bytes.NewBuffer(bufBytes) + t.Logf("%X", bufBytes) + var n3 int + ReadString(buf, len(bufBytes), &n3, &err) + if err != nil { + t.Error(err.Error()) + } + if n != n3 { + t.Error("Read string did not match write string length") + } + + // Limit to the string length, should succeed. + buf = bytes.NewBuffer(bufBytes) + var n4 int + ReadString(buf, len(bufBytes)-1, &n4, &err) + if err != ErrBinaryReadSizeOverflow { + t.Error("Expected ErrBinaryReadsizeOverflow") + } + +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/time.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go similarity index 65% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/time.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/time.go index fde8b8ae..1d6f7e46 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/time.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go @@ -4,7 +4,7 @@ import ( "io" "time" - . "github.com/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) /* @@ -12,13 +12,13 @@ Writes nanoseconds since epoch but with millisecond precision. This is to ease compatibility with Javascript etc. */ -func WriteTime(t time.Time, w io.Writer, n *int64, err *error) { +func WriteTime(t time.Time, w io.Writer, n *int, err *error) { nanosecs := t.UnixNano() millisecs := nanosecs / 1000000 WriteInt64(millisecs*1000000, w, n, err) } -func ReadTime(r io.Reader, n *int64, err *error) time.Time { +func ReadTime(r io.Reader, n *int, err *error) time.Time { t := ReadInt64(r, n, err) if t%1000000 != 0 { PanicSanity("Time cannot have sub-millisecond precision") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/util.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go similarity index 60% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/util.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/util.go index 70e2b3ff..bde328d9 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/util.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go @@ -3,13 +3,15 @@ package wire import ( "bytes" "crypto/sha256" - "code.google.com/p/go.crypto/ripemd160" + "encoding/json" - . "github.com/tendermint/tendermint/common" + "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" ) func BinaryBytes(o interface{}) []byte { - w, n, err := new(bytes.Buffer), new(int64), new(error) + w, n, err := new(bytes.Buffer), new(int), new(error) WriteBinary(o, w, n, err) if *err != nil { PanicSanity(*err) @@ -18,7 +20,7 @@ func BinaryBytes(o interface{}) []byte { } func JSONBytes(o interface{}) []byte { - w, n, err := new(bytes.Buffer), new(int64), new(error) + w, n, err := new(bytes.Buffer), new(int), new(error) WriteJSON(o, w, n, err) if *err != nil { PanicSanity(*err) @@ -26,6 +28,21 @@ func JSONBytes(o interface{}) []byte { return w.Bytes() } +// NOTE: inefficient +func JSONBytesPretty(o interface{}) []byte { + jsonBytes := JSONBytes(o) + var object interface{} + err := json.Unmarshal(jsonBytes, &object) + if err != nil { + PanicSanity(err) + } + jsonBytes, err = json.MarshalIndent(object, "", "\t") + if err != nil { + PanicSanity(err) + } + return jsonBytes +} + // NOTE: does not care about the type, only the binary representation. func BinaryEqual(a, b interface{}) bool { aBytes := BinaryBytes(a) @@ -42,7 +59,7 @@ func BinaryCompare(a, b interface{}) int { // NOTE: only use this if you need 32 bytes. func BinarySha256(o interface{}) []byte { - hasher, n, err := sha256.New(), new(int64), new(error) + hasher, n, err := sha256.New(), new(int), new(error) WriteBinary(o, hasher, n, err) if *err != nil { PanicSanity(*err) @@ -52,7 +69,7 @@ func BinarySha256(o interface{}) []byte { // NOTE: The default hash function is Ripemd160. func BinaryRipemd160(o interface{}) []byte { - hasher, n, err := ripemd160.New(), new(int64), new(error) + hasher, n, err := ripemd160.New(), new(int), new(error) WriteBinary(o, hasher, n, err) if *err != nil { PanicSanity(*err) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/version.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/version.go similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/version.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/version.go diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/wire.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go similarity index 70% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/wire/wire.go rename to Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go index aece054f..b983ff0e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/wire.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go @@ -6,46 +6,55 @@ import ( "io" "reflect" - . "github.com/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) -// TODO document and maybe make it configurable. -const MaxBinaryReadSize = 21 * 1024 * 1024 - var ErrBinaryReadSizeOverflow = errors.New("Error: binary read size overflow") var ErrBinaryReadSizeUnderflow = errors.New("Error: binary read size underflow") -func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{} { +const ( + ReadSliceChunkSize = 1024 +) + +func ReadBinary(o interface{}, r io.Reader, lmt int, n *int, err *error) (res interface{}) { rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) if rv.Kind() == reflect.Ptr { if rv.IsNil() { // This allows ReadBinaryObject() to return a nil pointer, // if the value read is nil. rvPtr := reflect.New(rt) - ReadBinaryPtr(rvPtr.Interface(), r, n, err) - return rvPtr.Elem().Interface() + ReadBinaryPtr(rvPtr.Interface(), r, lmt, n, err) + res = rvPtr.Elem().Interface() } else { - readReflectBinary(rv, rt, Options{}, r, n, err) - return o + readReflectBinary(rv, rt, Options{}, r, lmt, n, err) + res = o } } else { ptrRv := reflect.New(rt) - readReflectBinary(ptrRv.Elem(), rt, Options{}, r, n, err) - return ptrRv.Elem().Interface() + readReflectBinary(ptrRv.Elem(), rt, Options{}, r, lmt, n, err) + res = ptrRv.Elem().Interface() + } + if lmt != 0 && lmt < *n && *err == nil { + *err = ErrBinaryReadSizeOverflow } + return res } -func ReadBinaryPtr(o interface{}, r io.Reader, n *int64, err *error) interface{} { +func ReadBinaryPtr(o interface{}, r io.Reader, lmt int, n *int, err *error) (res interface{}) { rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) if rv.Kind() == reflect.Ptr { - readReflectBinary(rv.Elem(), rt.Elem(), Options{}, r, n, err) + readReflectBinary(rv.Elem(), rt.Elem(), Options{}, r, lmt, n, err) } else { PanicSanity("ReadBinaryPtr expects o to be a pointer") } - return o + res = o + if lmt != 0 && lmt < *n && *err == nil { + *err = ErrBinaryReadSizeOverflow + } + return res } -func WriteBinary(o interface{}, w io.Writer, n *int64, err *error) { +func WriteBinary(o interface{}, w io.Writer, n *int, err *error) { rv := reflect.ValueOf(o) rt := reflect.TypeOf(o) writeReflectBinary(rv, rt, Options{}, w, n, err) @@ -102,7 +111,7 @@ func ReadJSONObjectPtr(o interface{}, object interface{}, err *error) interface{ return o } -func WriteJSON(o interface{}, w io.Writer, n *int64, err *error) { +func WriteJSON(o interface{}, w io.Writer, n *int, err *error) { rv := reflect.ValueOf(o) rt := reflect.TypeOf(o) if rv.Kind() == reflect.Ptr { @@ -113,22 +122,22 @@ func WriteJSON(o interface{}, w io.Writer, n *int64, err *error) { // Write all of bz to w // Increment n and set err accordingly. -func WriteTo(bz []byte, w io.Writer, n *int64, err *error) { +func WriteTo(bz []byte, w io.Writer, n *int, err *error) { if *err != nil { return } n_, err_ := w.Write(bz) - *n += int64(n_) + *n += n_ *err = err_ } // Read len(buf) from r // Increment n and set err accordingly. -func ReadFull(buf []byte, r io.Reader, n *int64, err *error) { +func ReadFull(buf []byte, r io.Reader, n *int, err *error) { if *err != nil { return } n_, err_ := io.ReadFull(r, buf) - *n += int64(n_) + *n += n_ *err = err_ } diff --git a/Godeps/_workspace/src/github.com/tendermint/log15/handler.go b/Godeps/_workspace/src/github.com/tendermint/log15/handler.go index 4c771b4b..5dc72998 100644 --- a/Godeps/_workspace/src/github.com/tendermint/log15/handler.go +++ b/Godeps/_workspace/src/github.com/tendermint/log15/handler.go @@ -11,7 +11,7 @@ import ( "sync/atomic" "unsafe" - "github.com/inconshreveable/log15/stack" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/inconshreveable/log15/stack" ) // A Logger prints its log records by writing to a Handler. diff --git a/Godeps/_workspace/src/github.com/tendermint/log15/root.go b/Godeps/_workspace/src/github.com/tendermint/log15/root.go index 98103173..7034447a 100644 --- a/Godeps/_workspace/src/github.com/tendermint/log15/root.go +++ b/Godeps/_workspace/src/github.com/tendermint/log15/root.go @@ -3,8 +3,8 @@ package log15 import ( "os" - "github.com/inconshreveable/log15/term" - "github.com/mattn/go-colorable" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/inconshreveable/log15/term" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/mattn/go-colorable" ) var ( diff --git a/Godeps/_workspace/src/github.com/tendermint/log15/stack/stack_test.go b/Godeps/_workspace/src/github.com/tendermint/log15/stack/stack_test.go index 52371b1e..64cd7d08 100644 --- a/Godeps/_workspace/src/github.com/tendermint/log15/stack/stack_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/log15/stack/stack_test.go @@ -9,7 +9,7 @@ import ( "runtime" "testing" - "github.com/inconshreveable/log15/stack" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/inconshreveable/log15/stack" ) type testType struct{} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/account.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/account/account.go deleted file mode 100644 index 9be275db..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/account.go +++ /dev/null @@ -1,74 +0,0 @@ -package account - -import ( - "bytes" - "fmt" - "io" - - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/merkle" - ptypes "github.com/tendermint/tendermint/permission/types" - "github.com/tendermint/tendermint/wire" -) - -// Signable is an interface for all signable things. -// It typically removes signatures before serializing. -type Signable interface { - WriteSignBytes(chainID string, w io.Writer, n *int64, 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(int64), 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)) -} - -//----------------------------------------------------------------------------- - -// Account resides in the application state, and is mutated by transactions -// 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. - - Permissions ptypes.AccountPermissions `json:"permissions"` -} - -func (acc *Account) Copy() *Account { - accCopy := *acc - return &accCopy -} - -func (acc *Account) String() string { - if acc == nil { - return "nil-Account" - } - return fmt.Sprintf("Account{%X:%v B:%v C:%v S:%X P:%s}", acc.Address, acc.PubKey, acc.Balance, len(acc.Code), acc.StorageRoot, acc.Permissions) -} - -func AccountEncoder(o interface{}, w io.Writer, n *int64, err *error) { - wire.WriteBinary(o.(*Account), w, n, err) -} - -func AccountDecoder(r io.Reader, n *int64, err *error) interface{} { - return wire.ReadBinary(&Account{}, r, n, err) -} - -var AccountCodec = wire.Codec{ - Encode: AccountEncoder, - Decode: AccountDecoder, -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/priv_account.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/account/priv_account.go deleted file mode 100644 index e119fc56..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/account/priv_account.go +++ /dev/null @@ -1,84 +0,0 @@ -package account - -import ( - "github.com/tendermint/ed25519" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" -) - -type PrivAccount struct { - Address []byte `json:"address"` - PubKey PubKey `json:"pub_key"` - PrivKey PrivKey `json:"priv_key"` -} - -func (pA *PrivAccount) Generate(index int) *PrivAccount { - newPrivKey := pA.PrivKey.(PrivKeyEd25519).Generate(index) - newPubKey := newPrivKey.PubKey() - newAddress := newPubKey.Address() - return &PrivAccount{ - Address: newAddress, - PubKey: newPubKey, - PrivKey: newPrivKey, - } -} - -func (pA *PrivAccount) Sign(chainID string, o Signable) Signature { - return pA.PrivKey.Sign(SignBytes(chainID, o)) -} - -func (pA *PrivAccount) String() string { - return Fmt("PrivAccount{%X}", pA.Address) -} - -//---------------------------------------- - -// Generates a new account with private key. -func GenPrivAccount() *PrivAccount { - privKeyBytes := new([64]byte) - copy(privKeyBytes[:32], CRandBytes(32)) - pubKeyBytes := ed25519.MakePublicKey(privKeyBytes) - pubKey := PubKeyEd25519(*pubKeyBytes) - privKey := PrivKeyEd25519(*privKeyBytes) - return &PrivAccount{ - Address: pubKey.Address(), - PubKey: pubKey, - PrivKey: privKey, - } -} - -// Generates 32 priv key bytes from secret -func GenPrivKeyBytesFromSecret(secret string) []byte { - return wire.BinarySha256(secret) // Not Ripemd160 because we want 32 bytes. -} - -// Generates a new account with private key from SHA256 hash of a secret -func GenPrivAccountFromSecret(secret string) *PrivAccount { - privKey32 := GenPrivKeyBytesFromSecret(secret) - privKeyBytes := new([64]byte) - copy(privKeyBytes[:32], privKey32) - pubKeyBytes := ed25519.MakePublicKey(privKeyBytes) - pubKey := PubKeyEd25519(*pubKeyBytes) - privKey := PrivKeyEd25519(*privKeyBytes) - return &PrivAccount{ - Address: pubKey.Address(), - PubKey: pubKey, - PrivKey: privKey, - } -} - -func GenPrivAccountFromPrivKeyBytes(privKeyBytes []byte) *PrivAccount { - if len(privKeyBytes) != 64 { - PanicSanity(Fmt("Expected 64 bytes but got %v", len(privKeyBytes))) - } - var privKeyArray [64]byte - copy(privKeyArray[:], privKeyBytes) - pubKeyBytes := ed25519.MakePublicKey(&privKeyArray) - pubKey := PubKeyEd25519(*pubKeyBytes) - privKey := PrivKeyEd25519(privKeyArray) - return &PrivAccount{ - Address: pubKey.Address(), - PubKey: pubKey, - PrivKey: privKey, - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go index c4763309..497be012 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/sfreiberg/gotwilio" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/sfreiberg/gotwilio" ) var lastAlertUnix int64 = 0 diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go index 834803fa..b42f6167 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go @@ -1,7 +1,7 @@ package alert import ( - cfg "github.com/tendermint/tendermint/config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go index 0f0740e0..73e8c457 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go @@ -1,7 +1,7 @@ package alert import ( - "github.com/tendermint/tendermint/logger" + "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 index f04e9994..41b90776 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/log.go @@ -1,7 +1,7 @@ package blockchain import ( - "github.com/tendermint/tendermint/logger" + "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 index b2f3c5bd..db750c1d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool.go @@ -5,15 +5,15 @@ import ( "sync" "time" - flow "code.google.com/p/mxk/go1/flowcontrol" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" + 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 - maxTotalRequests = 300 - maxPendingRequests = maxTotalRequests + maxTotalRequesters = 300 + maxPendingRequests = maxTotalRequesters maxPendingRequestsPerPeer = 75 peerTimeoutSeconds = 15 minRecvRate = 10240 // 10Kb/s @@ -36,8 +36,8 @@ type BlockPool struct { // block requests mtx sync.Mutex - requests map[int]*bpRequester - height int // the lowest key in requests. + requesters map[int]*bpRequester + height int // the lowest key in requesters. numPending int32 // number of requests pending assignment or block response // peers @@ -52,7 +52,7 @@ func NewBlockPool(start int, requestsCh chan<- BlockRequest, timeoutsCh chan<- s bp := &BlockPool{ peers: make(map[string]*bpPeer), - requests: make(map[int]*bpRequester), + requesters: make(map[int]*bpRequester), height: start, numPending: 0, @@ -65,7 +65,7 @@ func NewBlockPool(start int, requestsCh chan<- BlockRequest, timeoutsCh chan<- s func (pool *BlockPool) OnStart() error { pool.QuitService.OnStart() - go pool.makeRequestsRoutine() + go pool.makeRequestersRoutine() pool.startTime = time.Now() return nil } @@ -74,8 +74,8 @@ func (pool *BlockPool) OnStop() { pool.QuitService.OnStop() } -// Run spawns requests as needed. -func (pool *BlockPool) makeRequestsRoutine() { +// Run spawns requesters as needed. +func (pool *BlockPool) makeRequestersRoutine() { for { if !pool.IsRunning() { break @@ -86,14 +86,14 @@ func (pool *BlockPool) makeRequestsRoutine() { time.Sleep(requestIntervalMS * time.Millisecond) // check for timed out peers pool.removeTimedoutPeers() - } else if len(pool.requests) >= maxTotalRequests { + } 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.makeNextRequest() + pool.makeNextRequester() } } } @@ -147,10 +147,10 @@ func (pool *BlockPool) PeekTwoBlocks() (first *types.Block, second *types.Block) pool.mtx.Lock() // Lock defer pool.mtx.Unlock() - if r := pool.requests[pool.height]; r != nil { + if r := pool.requesters[pool.height]; r != nil { first = r.getBlock() } - if r := pool.requests[pool.height+1]; r != nil { + if r := pool.requesters[pool.height+1]; r != nil { second = r.getBlock() } return @@ -162,14 +162,18 @@ func (pool *BlockPool) PopRequest() { pool.mtx.Lock() // Lock defer pool.mtx.Unlock() - /* The block can disappear at any time, due to removePeer(). - if r := pool.requests[pool.height]; r == nil || r.block == nil { - PanicSanity("PopRequest() requires a valid block") + 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)) } - */ - - delete(pool.requests, pool.height) - pool.height++ } // Invalidates the block at pool.height, @@ -178,11 +182,11 @@ func (pool *BlockPool) RedoRequest(height int) { pool.mtx.Lock() // Lock defer pool.mtx.Unlock() - request := pool.requests[height] + request := pool.requesters[height] if request.block == nil { PanicSanity("Expected block to be non-nil") } - // RemovePeer will redo all requests associated with this peer. + // RemovePeer will redo all requesters associated with this peer. // TODO: record this malfeasance pool.RemovePeer(request.peerID) // Lock on peersMtx. } @@ -192,12 +196,12 @@ func (pool *BlockPool) AddBlock(peerID string, block *types.Block, blockSize int pool.mtx.Lock() // Lock defer pool.mtx.Unlock() - request := pool.requests[block.Height] - if request == nil { + requester := pool.requesters[block.Height] + if requester == nil { return } - if request.setBlock(block, peerID) { + if requester.setBlock(block, peerID) { pool.numPending-- peer := pool.getPeer(peerID) peer.decrPending(blockSize) @@ -228,10 +232,10 @@ func (pool *BlockPool) RemovePeer(peerID string) { } func (pool *BlockPool) removePeer(peerID string) { - for _, request := range pool.requests { - if request.getPeerID() == peerID { + for _, requester := range pool.requesters { + if requester.getPeerID() == peerID { pool.numPending++ - go request.redo() // pick another peer and ... + go requester.redo() // pick another peer and ... } } delete(pool.peers, peerID) @@ -269,14 +273,14 @@ func (pool *BlockPool) pickIncrAvailablePeer(minHeight int) *bpPeer { return nil } -func (pool *BlockPool) makeNextRequest() { +func (pool *BlockPool) makeNextRequester() { pool.mtx.Lock() // Lock defer pool.mtx.Unlock() - nextHeight := pool.height + len(pool.requests) + nextHeight := pool.height + len(pool.requesters) request := newBPRequester(pool, nextHeight) - pool.requests[nextHeight] = request + pool.requesters[nextHeight] = request pool.numPending++ request.Start() @@ -301,12 +305,12 @@ func (pool *BlockPool) debug() string { defer pool.mtx.Unlock() str := "" - for h := pool.height; h < pool.height+len(pool.requests); h++ { - if pool.requests[h] == nil { + 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.requests[h].block != nil) + str += Fmt("B?(%v) ", pool.requesters[h].block != nil) } } return str 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 index a70c96d5..4d6a3451 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" + . "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 { diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go index b80438a7..0ca0e2f7 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go @@ -7,12 +7,13 @@ import ( "reflect" "time" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/p2p" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + . "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 ( @@ -28,6 +29,7 @@ const ( statusUpdateIntervalSeconds = 10 // check if we should switch to consensus reactor switchToConsensusIntervalSeconds = 1 + maxBlockchainResponseSize = types.MaxBlockSize + 2 ) type consensusReactor interface { @@ -40,19 +42,20 @@ type consensusReactor interface { type BlockchainReactor struct { p2p.BaseReactor - sw *p2p.Switch - state *sm.State - store *BlockStore - pool *BlockPool - sync bool - requestsCh chan BlockRequest - timeoutsCh chan string - lastBlock *types.Block + 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, store *BlockStore, sync bool) *BlockchainReactor { +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())) @@ -65,12 +68,13 @@ func NewBlockchainReactor(state *sm.State, store *BlockStore, sync bool) *Blockc timeoutsCh, ) bcR := &BlockchainReactor{ - state: state, - store: store, - pool: pool, - sync: sync, - requestsCh: requestsCh, - timeoutsCh: timeoutsCh, + state: state, + proxyAppCtx: proxyAppCtx, + store: store, + pool: pool, + sync: sync, + requestsCh: requestsCh, + timeoutsCh: timeoutsCh, } bcR.BaseReactor = *p2p.NewBaseReactor(log, "BlockchainReactor", bcR) return bcR @@ -192,7 +196,7 @@ FOR_LOOP: case _ = <-switchToConsensusTicker.C: height, numPending := bcR.pool.GetStatus() outbound, inbound, _ := bcR.Switch.NumPeers() - log.Info("Consensus ticker", "numPending", numPending, "total", len(bcR.pool.requests), + 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) @@ -217,7 +221,7 @@ FOR_LOOP: firstParts := first.MakePartSet() firstPartsHeader := firstParts.Header() // Finally, verify the first block using the second's validation. - err := bcR.state.BondedValidators.VerifyValidation( + 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) @@ -225,11 +229,16 @@ FOR_LOOP: break SYNC_LOOP } else { bcR.pool.PopRequest() - err := sm.ExecBlock(bcR.state, first, firstPartsHeader) + 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() } @@ -279,10 +288,10 @@ var _ = wire.RegisterInterface( // TODO: ensure that bz is completely read. func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) { msgType = bz[0] - n := int64(0) + n := int(0) r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage - if err != nil && n != int64(len(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 @@ -300,6 +309,7 @@ func (m *bcBlockRequestMessage) String() string { //------------------------------------- +// NOTE: keep up-to-date with maxBlockchainResponseSize type bcBlockResponseMessage struct { Block *types.Block } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go index 69a49929..de9a6571 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go @@ -6,10 +6,10 @@ import ( "fmt" "io" - . "github.com/tendermint/tendermint/common" - dbm "github.com/tendermint/tendermint/db" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + . "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" ) /* @@ -53,13 +53,13 @@ func (bs *BlockStore) GetReader(key []byte) io.Reader { } func (bs *BlockStore) LoadBlock(height int) *types.Block { - var n int64 + var n int var err error r := bs.GetReader(calcBlockMetaKey(height)) if r == nil { return nil } - meta := wire.ReadBinary(&types.BlockMeta{}, r, &n, &err).(*types.BlockMeta) + meta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta) if err != nil { PanicCrisis(Fmt("Error reading block meta: %v", err)) } @@ -68,7 +68,7 @@ func (bs *BlockStore) LoadBlock(height int) *types.Block { part := bs.LoadBlockPart(height, i) bytez = append(bytez, part.Bytes...) } - block := wire.ReadBinary(&types.Block{}, bytes.NewReader(bytez), &n, &err).(*types.Block) + block := wire.ReadBinary(&types.Block{}, bytes.NewReader(bytez), 0, &n, &err).(*types.Block) if err != nil { PanicCrisis(Fmt("Error reading block: %v", err)) } @@ -76,13 +76,13 @@ func (bs *BlockStore) LoadBlock(height int) *types.Block { } func (bs *BlockStore) LoadBlockPart(height int, index int) *types.Part { - var n int64 + var n int var err error r := bs.GetReader(calcBlockPartKey(height, index)) if r == nil { return nil } - part := wire.ReadBinary(&types.Part{}, r, &n, &err).(*types.Part) + part := wire.ReadBinary(&types.Part{}, r, 0, &n, &err).(*types.Part) if err != nil { PanicCrisis(Fmt("Error reading block part: %v", err)) } @@ -90,13 +90,13 @@ func (bs *BlockStore) LoadBlockPart(height int, index int) *types.Part { } func (bs *BlockStore) LoadBlockMeta(height int) *types.BlockMeta { - var n int64 + var n int var err error r := bs.GetReader(calcBlockMetaKey(height)) if r == nil { return nil } - meta := wire.ReadBinary(&types.BlockMeta{}, r, &n, &err).(*types.BlockMeta) + meta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta) if err != nil { PanicCrisis(Fmt("Error reading block meta: %v", err)) } @@ -106,13 +106,13 @@ func (bs *BlockStore) LoadBlockMeta(height int) *types.BlockMeta { // 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 int64 + var n int var err error r := bs.GetReader(calcBlockValidationKey(height)) if r == nil { return nil } - validation := wire.ReadBinary(&types.Validation{}, r, &n, &err).(*types.Validation) + validation := wire.ReadBinary(&types.Validation{}, r, 0, &n, &err).(*types.Validation) if err != nil { PanicCrisis(Fmt("Error reading validation: %v", err)) } @@ -121,13 +121,13 @@ func (bs *BlockStore) LoadBlockValidation(height int) *types.Validation { // NOTE: the Precommit-vote heights are for the block at `height` func (bs *BlockStore) LoadSeenValidation(height int) *types.Validation { - var n int64 + var n int var err error r := bs.GetReader(calcSeenValidationKey(height)) if r == nil { return nil } - validation := wire.ReadBinary(&types.Validation{}, r, &n, &err).(*types.Validation) + validation := wire.ReadBinary(&types.Validation{}, r, 0, &n, &err).(*types.Validation) if err != nil { PanicCrisis(Fmt("Error reading validation: %v", err)) } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/io.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/common/io.go deleted file mode 100644 index 0c33b075..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/common/io.go +++ /dev/null @@ -1,24 +0,0 @@ -package common - -import ( - "io" -) - -type PrefixedReader struct { - Prefix []byte - reader io.Reader -} - -func NewPrefixedReader(prefix []byte, reader io.Reader) *PrefixedReader { - return &PrefixedReader{prefix, reader} -} - -func (pr *PrefixedReader) Read(p []byte) (n int, err error) { - if len(pr.Prefix) > 0 { - read := copy(p, pr.Prefix) - pr.Prefix = pr.Prefix[read:] - return read, nil - } else { - return pr.reader.Read(p) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/log.go deleted file mode 100644 index 3cd8f430..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/log.go +++ /dev/null @@ -1,9 +0,0 @@ -package config - -import ( - // We can't use github.com/tendermint/tendermint/logger - // because that would create a dependency cycle. - "github.com/tendermint/log15" -) - -var log = log15.New("module", "config") 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 index 1c44cf31..288cf250 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/config.go @@ -1,13 +1,12 @@ package tendermint import ( - "github.com/naoina/toml" "os" "path" "strings" - . "github.com/tendermint/tendermint/common" - cfg "github.com/tendermint/tendermint/config" + . "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 { @@ -22,19 +21,15 @@ func getTMRoot(rootDir string) string { func initTMRoot(rootDir string) { rootDir = getTMRoot(rootDir) - EnsureDir(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"))) - } - if !FileExists(genesisFilePath) { - MustWriteFile(genesisFilePath, []byte(defaultGenesis)) + MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644) } } @@ -42,10 +37,8 @@ func GetConfig(rootDir string) cfg.Config { rootDir = getTMRoot(rootDir) initTMRoot(rootDir) - var mapConfig = cfg.MapConfig(make(map[string]interface{})) configFilePath := path.Join(rootDir, "config.toml") - configFileBytes := MustReadFile(configFilePath) - err := toml.Unmarshal(configFileBytes, mapConfig) + mapConfig, err := cfg.ReadMapConfigFromFile(configFilePath) if err != nil { Exit(Fmt("Could not read config: %v", err)) } @@ -54,8 +47,12 @@ func GetConfig(rootDir string) cfg.Config { if mapConfig.IsSet("chain_id") { Exit("Cannot set 'chain_id' via config.toml") } - mapConfig.SetDefault("chain_id", "tendermint_testnet_10") + 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") @@ -65,24 +62,21 @@ func GetConfig(rootDir string) cfg.Config { 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("revisions_file", rootDir+"/revisions") + mapConfig.SetDefault("prof_laddr", "") + mapConfig.SetDefault("revision_file", rootDir+"/revision") return mapConfig } -func ensureDefault(mapConfig cfg.MapConfig, key string, value interface{}) { - if !mapConfig.IsSet(key) { - mapConfig[key] = value - } -} - 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 = "goldenalchemist.chaintest.net:46656" +seeds = "" fast_sync = true db_backend = "leveldb" log_level = "notice" @@ -93,63 +87,3 @@ func defaultConfig(moniker string) (defaultConfig string) { defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1) return } - -var defaultGenesis = `{ - "chain_id": "tendermint_testnet_11", - "accounts": [ - { - "address": "9FCBA7F840A0BFEBBE755E853C9947270A912D04", - "amount": 1995999998000000 - }, - { - "address": "964B1493BBE3312278B7DEB94C39149F7899A345", - "amount": 100000000000000 - }, - { - "address": "B9FA4AB462B9C6BF6A62DB4AE77C9E7087209A04", - "amount": 1000000000000 - }, - { - "address": "F171824590D69386F709E7B6704B369C5A370D60", - "amount": 1000000000000 - }, - { - "address": "56EFE746A13D9A6054AC89C3E2A361C2DB8B9EAE", - "amount": 1000000000000 - }, - { - "address": "7C2E032D8407EDF66A04D88CF0E1D9B15D98AE2D", - "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/genesis.json b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json new file mode 100644 index 00000000..eca00696 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json @@ -0,0 +1,75 @@ +{ + "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_test/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test/config.go index 28cf6a29..01a54da1 100644 --- 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 @@ -3,13 +3,12 @@ package tendermint_test import ( - "github.com/naoina/toml" "os" "path" "strings" - . "github.com/tendermint/tendermint/common" - cfg "github.com/tendermint/tendermint/config" + . "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() { @@ -27,7 +26,7 @@ func getTMRoot(rootDir string) string { func initTMRoot(rootDir string) { rootDir = getTMRoot(rootDir) - EnsureDir(rootDir) + EnsureDir(rootDir, 0700) configFilePath := path.Join(rootDir, "config.toml") genesisFilePath := path.Join(rootDir, "genesis.json") @@ -36,10 +35,10 @@ func initTMRoot(rootDir string) { if !FileExists(configFilePath) { // Ask user for moniker // moniker := cfg.Prompt("Type hostname: ", "anonymous") - MustWriteFile(configFilePath, []byte(defaultConfig("anonymous"))) + MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644) } if !FileExists(genesisFilePath) { - MustWriteFile(genesisFilePath, []byte(defaultGenesis)) + MustWriteFile(genesisFilePath, []byte(defaultGenesis), 0644) } } @@ -47,10 +46,8 @@ func GetConfig(rootDir string) cfg.Config { rootDir = getTMRoot(rootDir) initTMRoot(rootDir) - var mapConfig = cfg.MapConfig(make(map[string]interface{})) configFilePath := path.Join(rootDir, "config.toml") - configFileBytes := MustReadFile(configFilePath) - err := toml.Unmarshal(configFileBytes, mapConfig) + mapConfig, err := cfg.ReadMapConfigFromFile(configFilePath) if err != nil { Exit(Fmt("Could not read config: %v", err)) } @@ -61,6 +58,7 @@ func GetConfig(rootDir string) cfg.Config { } 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) @@ -70,20 +68,17 @@ func GetConfig(rootDir string) cfg.Config { 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("revisions_file", rootDir+"/revisions") + mapConfig.SetDefault("prof_laddr", "") + mapConfig.SetDefault("revision_file", rootDir+"/revision") return mapConfig } -func ensureDefault(mapConfig cfg.MapConfig, key string, value interface{}) { - if !mapConfig.IsSet(key) { - mapConfig[key] = value - } -} - 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 = "" 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 new file mode 100644 index 00000000..f5860375 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/common_test.go @@ -0,0 +1,335 @@ +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 index 8366b36c..63706a7f 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/config.go @@ -1,7 +1,7 @@ package consensus import ( - cfg "github.com/tendermint/tendermint/config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config = nil 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 index eb680cd6..1fa956cd 100644 --- 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 @@ -4,8 +4,8 @@ import ( "strings" "sync" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" + . "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 { diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go index 0b3a33db..ba38a689 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go @@ -1,7 +1,7 @@ package consensus import ( - "github.com/tendermint/tendermint/logger" + "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 index dcf28e56..bbefb21d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/reactor.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/reactor.go @@ -8,13 +8,13 @@ import ( "sync" "time" - bc "github.com/tendermint/tendermint/blockchain" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/p2p" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + . "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 ( @@ -22,9 +22,8 @@ const ( DataChannel = byte(0x21) VoteChannel = byte(0x22) - PeerStateKey = "ConsensusReactor.peerState" - peerGossipSleepDuration = 100 * time.Millisecond // Time to sleep if there's nothing to send. + maxConsensusMessageSize = 1048576 // 1MB; NOTE: keep in sync with types.PartSet sizes. ) //----------------------------------------------------------------------------- @@ -107,7 +106,7 @@ func (conR *ConsensusReactor) AddPeer(peer *p2p.Peer) { // Create peerState for peer peerState := NewPeerState(peer) - peer.Data.Set(PeerStateKey, peerState) + peer.Data.Set(types.PeerStateKey, peerState) // Begin gossip routines for this peer. go conR.gossipDataRoutine(peer, peerState) @@ -138,7 +137,7 @@ func (conR *ConsensusReactor) Receive(chID byte, peer *p2p.Peer, msgBytes []byte } // Get peer states - ps := peer.Data.Get(PeerStateKey).(*PeerState) + 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) @@ -455,35 +454,21 @@ OUTER_LOOP: } } // If there are prevotes to send... - if rs.Round == prs.Round && prs.Step <= RoundStepPrevote { - if ps.PickSendVote(rs.Votes.Prevotes(rs.Round)) { - log.Info("Picked rs.Prevotes(rs.Round) to send") - continue OUTER_LOOP - } - } - // If there are precommits to send... - if rs.Round == prs.Round && prs.Step <= RoundStepPrecommit { - if ps.PickSendVote(rs.Votes.Precommits(rs.Round)) { - log.Info("Picked rs.Precommits(rs.Round) to send") - continue OUTER_LOOP - } - } - // If there are prevotes to send for the last round... - if rs.Round == prs.Round+1 && prs.Step <= RoundStepPrevote { + 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 for the last round... - if rs.Round == prs.Round+1 && prs.Step <= RoundStepPrecommit { + // 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 0 <= prs.ProposalPOLRound { + 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") @@ -548,8 +533,8 @@ type PeerRoundState struct { 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 believe commit round is. -1 if none. - CatchupCommit *BitArray // All commit precommits peer has for this 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 } //----------------------------------------------------------------------------- @@ -588,6 +573,14 @@ func (ps *PeerState) GetRoundState() *PeerRoundState { 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() @@ -696,14 +689,18 @@ func (ps *PeerState) getVoteBitArray(height, round int, type_ byte) *BitArray { return nil } -// NOTE: 'round' is what we know to be the commit round for height. +// '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 } - if ps.CatchupCommitRound != -1 && ps.CatchupCommitRound != round { - PanicSanity(Fmt("Conflicting CatchupCommitRound. Height: %v, Orig: %v, New: %v", height, ps.CatchupCommitRound, round)) - } + /* + 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! } @@ -917,9 +914,9 @@ var _ = wire.RegisterInterface( // TODO: check for unnecessary extra bytes at the end. func DecodeMessage(bz []byte) (msgType byte, msg ConsensusMessage, err error) { msgType = bz[0] - n := new(int64) + n := new(int) r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ ConsensusMessage }{}, r, n, &err).(struct{ ConsensusMessage }).ConsensusMessage + msg = wire.ReadBinary(struct{ ConsensusMessage }{}, r, maxConsensusMessageSize, n, &err).(struct{ ConsensusMessage }).ConsensusMessage return } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go index 9c46a765..7e4b6879 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go @@ -1,153 +1,3 @@ -/* - -* Terms: - - NewHeight, NewRound, Propose, Prevote, Precommit represent state machine steps. (aka RoundStep). - - To "prevote/precommit" something means to broadcast a prevote/precommit vote for something. - - (H,R) means a particular height H and round R. A vote "at (H,R)" is a vote signed with (H,R). - -* Proposals: - - A proposal is signed and published by the designated proposer at each round. - A proposal at (H,R) is composed of a proposed block of height H, and optionally a POL round number. - The POL round number R' (where R' < R) is set to the latest POL round known to the proposer. - If the proposer is locked on a block, it must include a POL round for the proposal. - -* POL and Justification of votes: - - A set of +2/3 of prevotes for a particular block or <nil> at (H,R) is called a POL (proof-of-lock). - A POL for <nil> might instead be called a proof-of-unlock, but it's better to have a single terminology for both. - - Each precommit which changes the lock at round R must be justified by a POL - where +2/3 prevoted for some block or <nil> at some round, equal to or less than R, - but greater than the last round at which the lock was changed. - - POL = Proof-of-Lock = +2/3 prevotes for block B (or +2/3 prevotes for <nil>) at (H,R) - - lastLockChangeRound < POLRound <= newLockChangeRound - - Without the POLRound <= newLockChangeRound condition, an unlock would be possible from a - future condition that hasn't happened yet, so it destroys deterministic accountability. - - The point of the above inequality is to ensure that changes in the lock (locking/unlocking/lock-changing) - are always justified by something that happened "in the past" by round numbers, so if there is a problem, - we can deterministically figure out "when it was caused" and by who. - - If there is a blockchain halt or fork, the blame will fall on +1/3 of Byzantine voting power = - who cannot push the blame into earlier rounds. (See lemma 4). - -* Block commits: - - The set of +2/3 of precommits at the same round for the same block is called a commit. - - A block contains the last block's commit which is comprised of +2/3 precommit votes at (H-1,R). - While all the precommits in the commit are from the same height & round (ordered by validator index), - some precommits may be absent (e.g. if the validator's precommit vote didn't reach the proposer in time), - or some precommits may be for different blockhashes for the last block hash (which is fine). - -* Consensus State Machine Overview: - - During NewHeight/NewRound/Propose/Prevote/Precommit: - * Nodes gossip the proposal block proposed by the designated proposer at round. - * Nodes gossip prevotes/precommits at rounds [0...currentRound+1] (currentRound+1 to allow round-skipping) - * Nodes gossip prevotes for the proposal's POL (proof-of-lock) round if proposed. - * Nodes gossip to late nodes (lagging in height) with precommits of the commit round (aka catchup) - - Upon each state transition, the height/round/step is broadcast to neighboring peers. - -* NewRound(height:H,round:R): - * Set up new round. --> goto Propose(H,R) - * NOTE: Not much happens in this step. It exists for clarity. - -* Propose(height:H,round:R): - * Upon entering Propose: - * The designated proposer proposes a block at (H,R). - * The Propose step ends: - * After `timeoutPropose` after entering Propose. --> goto Prevote(H,R) - * After receiving proposal block and all POL prevotes. --> goto Prevote(H,R) - * After any +2/3 prevotes received at (H,R+1). --> goto Prevote(H,R+1) - * After any +2/3 precommits received at (H,R+1). --> goto Precommit(H,R+1) - * After +2/3 precommits received for a particular block. --> goto Commit(H) - -* Prevote(height:H,round:R): - * Upon entering Prevote, each validator broadcasts its prevote vote. - * If the validator is locked on a block, it prevotes that. - * Else, if the proposed block from Propose(H,R) is good, it prevotes that. - * Else, if the proposal is invalid or wasn't received on time, it prevotes <nil>. - * The Prevote step ends: - * After +2/3 prevotes for a particular block or <nil>. --> goto Precommit(H,R) - * After `timeoutPrevote` after receiving any +2/3 prevotes. --> goto Precommit(H,R) - * After any +2/3 prevotes received at (H,R+1). --> goto Prevote(H,R+1) - * After any +2/3 precommits received at (H,R+1). --> goto Precommit(H,R+1) - * After +2/3 precommits received for a particular block. --> goto Commit(H) - -* Precommit(height:H,round:R): - * Upon entering Precommit, each validator broadcasts its precommit vote. - * If the validator had seen +2/3 of prevotes for a particular block from Prevote(H,R), - it locks (changes lock to) that block and precommits that block. - * Else, if the validator had seen +2/3 of prevotes for <nil>, it unlocks and precommits <nil>. - * Else, if +2/3 of prevotes for a particular block or <nil> is not received on time, - it precommits <nil>. - * The Precommit step ends: - * After +2/3 precommits for a particular block. --> goto Commit(H) - * After +2/3 precommits for <nil>. --> goto NewRound(H,R+1) - * After `timeoutPrecommit` after receiving any +2/3 precommits. --> goto NewRound(H,R+1) - * After any +2/3 prevotes received at (H,R+1). --> goto Prevote(H,R+1) - * After any +2/3 precommits received at (H,R+1). --> goto Precommit(H,R+1) - -* Commit(height:H): - * Set CommitTime = now - * Wait until block is received. --> goto NewHeight(H+1) - -* NewHeight(height:H): - * Move Precommits to LastCommit and increment height. - * Set StartTime = CommitTime+timeoutCommit - * Wait until `StartTime` to receive straggler commits. --> goto NewRound(H,0) - -* Proof of Safety: - If a good validator commits at round R, it's because it saw +2/3 of precommits at round R. - This implies that (assuming tolerance bounds) +1/3 of honest nodes are still locked at round R+1. - These locked validators will remain locked until they see +2/3 prevote for something - else, but this won't happen because +1/3 are locked and honest. - -* Proof of Liveness: - Lemma 1: If +1/3 good nodes are locked on two different blocks, the proposers' POLRound will - eventually cause nodes locked from the earlier round to unlock. - -> `timeoutProposalR` increments with round R, while the block.size && POL prevote size - are fixed, so eventually we'll be able to "fully gossip" the block & POL. - TODO: cap the block.size at something reasonable. - Lemma 2: If a good node is at round R, neighboring good nodes will soon catch up to round R. - Lemma 3: If a node at (H,R) receives +2/3 prevotes for a block (or +2/3 for <nil>) at (H,R+1), - it will enter NewRound(H,R+1). - Lemma 4: Terminal conditions imply the existence of deterministic accountability, for - a synchronous (fixed-duration) protocol extension (judgement). - TODO: define terminal conditions (fork and non-decision). - TODO: define new assumptions for the synchronous judgement period. - - - +-------------------------------------+ - v |(Wait til `CommmitTime+timeoutCommit`) - +-----------+ +-----+-----+ - +----------> | Propose +--------------+ | NewHeight | - | +-----------+ | +-----------+ - | | ^ - |(Else, after timeoutPrecommit) v | - +-----+-----+ +-----------+ | - | Precommit | <------------------------+ Prevote | | - +-----+-----+ +-----------+ | - |(When +2/3 Precommits for block found) | - v | - +--------------------------------------------------------------------+ - | Commit | - | | - | * Set CommitTime = now; | - | * Wait for block, then stage/save/commit block; | - +--------------------------------------------------------------------+ - -*/ - package consensus import ( @@ -157,14 +7,14 @@ import ( "sync" "time" - acm "github.com/tendermint/tendermint/account" - bc "github.com/tendermint/tendermint/blockchain" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - mempl "github.com/tendermint/tendermint/mempool" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + . "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 ( @@ -304,10 +154,11 @@ func (rs *RoundState) StringShort() string { type ConsensusState struct { BaseService - blockStore *bc.BlockStore - mempoolReactor *mempl.MempoolReactor - privValidator *types.PrivValidator - newStepCh chan *RoundState + proxyAppCtx proxy.AppContext + blockStore *bc.BlockStore + mempool *mempl.Mempool + privValidator *types.PrivValidator + newStepCh chan *RoundState mtx sync.Mutex RoundState @@ -319,16 +170,16 @@ type ConsensusState struct { evc *events.EventCache // set in stageBlock and passed into state } -func NewConsensusState(state *sm.State, blockStore *bc.BlockStore, mempoolReactor *mempl.MempoolReactor) *ConsensusState { +func NewConsensusState(state *sm.State, proxyAppCtx proxy.AppContext, blockStore *bc.BlockStore, mempool *mempl.Mempool) *ConsensusState { cs := &ConsensusState{ - blockStore: blockStore, - mempoolReactor: mempoolReactor, - newStepCh: make(chan *RoundState, 10), + 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.maybeRebond() cs.reconstructLastCommit(state) cs.BaseService = *NewBaseService(log, "ConsensusState", cs) return cs @@ -340,7 +191,7 @@ func (cs *ConsensusState) reconstructLastCommit(state *sm.State) { if state.LastBlockHeight == 0 { return } - lastPrecommits := types.NewVoteSet(state.LastBlockHeight, 0, types.VoteTypePrecommit, state.LastBondedValidators) + 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 { @@ -425,7 +276,7 @@ func (cs *ConsensusState) updateToState(state *sm.State) { } // Reset fields based on state. - validators := state.BondedValidators + validators := state.Validators height := state.LastBlockHeight + 1 // next desired block height lastPrecommits := (*types.VoteSet)(nil) if cs.CommitRound > -1 && cs.Votes != nil { @@ -460,7 +311,7 @@ func (cs *ConsensusState) updateToState(state *sm.State) { cs.Votes = NewHeightVoteSet(height, validators) cs.CommitRound = -1 cs.LastCommit = lastPrecommits - cs.LastValidators = state.LastBondedValidators + cs.LastValidators = state.LastValidators cs.state = state cs.stagedBlock = nil @@ -470,30 +321,6 @@ func (cs *ConsensusState) updateToState(state *sm.State) { cs.newStepCh <- cs.getRoundState() } -// If we're unbonded, broadcast RebondTx. -func (cs *ConsensusState) maybeRebond() { - if cs.privValidator == nil || !cs.state.UnbondingValidators.HasAddress(cs.privValidator.Address) { - return - } - rebondTx := &types.RebondTx{ - Address: cs.privValidator.Address, - Height: cs.Height, - } - err := cs.privValidator.SignRebondTx(cs.state.ChainID, rebondTx) - if err == nil { - err := cs.mempoolReactor.BroadcastTx(rebondTx) - if err != nil { - log.Error("Failed to broadcast RebondTx", - "height", cs.Height, "round", cs.Round, "tx", rebondTx, "error", err) - } else { - log.Notice("Signed and broadcast RebondTx", - "height", cs.Height, "round", cs.Round, "tx", rebondTx) - } - } else { - log.Warn("Error signing RebondTx", "height", cs.Height, "round", cs.Round, "tx", rebondTx, "error", err) - } -} - func (cs *ConsensusState) SetPrivValidator(priv *types.PrivValidator) { cs.mtx.Lock() defer cs.mtx.Unlock() @@ -594,8 +421,7 @@ func (cs *ConsensusState) EnterPropose(height int, round int) { } } -// Decides on the next proposal and sets them onto cs.Proposal* -func (cs *ConsensusState) decideProposal(height int, round int) { +func (cs *ConsensusState) decideProposal(height, round int) { var block *types.Block var blockParts *types.PartSet @@ -606,6 +432,9 @@ func (cs *ConsensusState) decideProposal(height int, round int) { } else { // Create a new proposal block from state/txs from the mempool. block, blockParts = cs.createProposalBlock() + if block == nil { // on error + return + } } // Make proposal @@ -641,6 +470,7 @@ func (cs *ConsensusState) isProposalComplete() bool { } // 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 @@ -656,7 +486,14 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts log.Error("EnterPropose: Cannot propose anything: No validation for the previous block.") return } - txs := cs.mempoolReactor.Mempool.GetProposalTxs() + + // 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, @@ -666,7 +503,8 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts NumTxs: len(txs), LastBlockHash: cs.state.LastBlockHash, LastBlockParts: cs.state.LastBlockParts, - StateHash: nil, // Will set afterwards. + ValidatorsHash: cs.state.Validators.Hash(), + AppHash: hash, }, LastValidation: validation, Data: &types.Data{ @@ -674,15 +512,8 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts }, } block.FillHeader() - - // Set the block.Header.StateHash. - err := cs.state.ComputeBlockStateHash(block) - if err != nil { - log.Error("EnterPropose: Error setting state hash", "error", err) - return - } - blockParts = block.MakePartSet() + return block, blockParts } @@ -1011,8 +842,6 @@ func (cs *ConsensusState) FinalizeCommit(height int) { // cs.StartTime is already set. // Schedule Round0 to start soon. go cs.scheduleRound0(height + 1) - // If we're unbonded, broadcast RebondTx. - cs.maybeRebond() // By here, // * cs.Height has been increment to height+1 @@ -1049,7 +878,7 @@ func (cs *ConsensusState) SetProposal(proposal *types.Proposal) error { } // Verify signature - if !cs.Validators.Proposer().PubKey.VerifyBytes(acm.SignBytes(cs.state.ChainID, proposal), proposal.Signature) { + if !cs.Validators.Proposer().PubKey.VerifyBytes(types.SignBytes(cs.state.ChainID, proposal), proposal.Signature) { return ErrInvalidProposalSignature } @@ -1080,9 +909,9 @@ func (cs *ConsensusState) AddProposalBlockPart(height int, part *types.Part) (ad } if added && cs.ProposalBlockParts.IsComplete() { // Added and completed! - var n int64 + var n int var err error - cs.ProposalBlock = wire.ReadBinary(&types.Block{}, cs.ProposalBlockParts.GetReader(), &n, &err).(*types.Block) + 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 @@ -1098,21 +927,23 @@ func (cs *ConsensusState) AddProposalBlockPart(height int, part *types.Part) (ad // 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, address, err := cs.AddVote(valIndex, vote, peerKey) + 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 errDupe, ok := err.(*types.ErrVoteConflictingSignature); ok { + } 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.mempoolReactor.BroadcastTx(evidenceTx) // shouldn't need to check returned err + cs.mempool.BroadcastTx(evidenceTx) // shouldn't need to check returned err + */ return added, err } else { // Probably an invalid signature. Bad peer. @@ -1163,7 +994,7 @@ func (cs *ConsensusState) addVote(valIndex int, vote *types.Vote, peerKey string switch vote.Type { case types.VoteTypePrevote: prevotes := cs.Votes.Prevotes(vote.Round) - log.Info(Fmt("Added to prevotes: %v", prevotes.StringShort())) + 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), @@ -1198,7 +1029,7 @@ func (cs *ConsensusState) addVote(valIndex int, vote *types.Vote, peerKey string } case types.VoteTypePrecommit: precommits := cs.Votes.Precommits(vote.Round) - log.Info(Fmt("Added to precommit: %v", precommits.StringShort())) + log.Info("Added to precommit", "vote", vote, "precommits", precommits.StringShort()) hash, _, ok := precommits.TwoThirdsMajority() if ok { go func() { @@ -1243,22 +1074,26 @@ func (cs *ConsensusState) stageBlock(block *types.Block, blockParts *types.PartS 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() - // reset the event cache and pass it into the state - cs.evc = events.NewEventCache(cs.evsw) stateCopy.SetFireable(cs.evc) - // Commit block onto the copied state. - // NOTE: Basic validation is done in state.AppendBlock(). - err := sm.ExecBlock(stateCopy, block, blockParts.Header()) + // 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 - } else { - cs.stagedBlock = block - cs.stagedState = stateCopy - return nil } + + // 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) { @@ -1304,18 +1139,23 @@ func (cs *ConsensusState) saveBlock(block *types.Block, blockParts *types.PartSe 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.mempoolReactor.Mempool.ResetForBlockAndState(block, cs.stagedState) + cs.mempool.Update(block) // Fire off event if cs.evsw != nil && cs.evc != nil { - go func(block *types.Block) { - cs.evsw.FireEvent(types.EventStringNewBlock(), types.EventDataNewBlock{block}) - cs.evc.Flush() - }(block) + cs.evsw.FireEvent(types.EventStringNewBlock(), types.EventDataNewBlock{block}) + go cs.evc.Flush() } } @@ -1328,3 +1168,22 @@ func (cs *ConsensusState) SetFireable(evsw events.Fireable) { 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 new file mode 100644 index 00000000..7ec75bb1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state_test.go @@ -0,0 +1,1186 @@ +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/consensus/test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/test.go deleted file mode 100644 index be0066e5..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/test.go +++ /dev/null @@ -1,225 +0,0 @@ -package consensus - -import ( - "bytes" - "fmt" - "testing" - "time" - - bc "github.com/tendermint/tendermint/blockchain" - dbm "github.com/tendermint/tendermint/db" - mempl "github.com/tendermint/tendermint/mempool" - "github.com/tendermint/tendermint/p2p" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" -) - -//------------------------------------------------------------------------------- -// utils - -func changeProposer(t *testing.T, perspectiveOf, newProposer *ConsensusState) *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.privValidator.Address) - v2.Accum, v2.VotingPower = 100, 100 - if updated := perspectiveOf.Validators.Update(v2); !updated { - t.Fatal("failed to update validator") - } - - // make the proposal - propBlock, _ := newProposer.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 ...*ConsensusState) { - 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, from *ConsensusState, 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 { - panic("Failed to add vote") - } else if err != nil { - panic(fmt.Sprintln("Failed to add vote:", err)) - } -} - -func signVote(from *ConsensusState, voteType byte, hash []byte, header types.PartSetHeader) *types.Vote { - vote, err := from.signVote(voteType, hash, header) - if err != nil { - panic(fmt.Sprintln("Failed to sign vote", err)) - } - return vote -} - -func signVoteMany(voteType byte, hash []byte, header types.PartSetHeader, css ...*ConsensusState) []*types.Vote { - votes := make([]*types.Vote, len(css)) - for i, cs := range css { - votes[i] = signVote(cs, voteType, hash, header) - } - return votes -} - -// add vote to one cs from another -func signAddVoteToFromMany(voteType byte, to *ConsensusState, hash []byte, header types.PartSetHeader, froms ...*ConsensusState) { - for _, from := range froms { - vote := signVote(from, voteType, hash, header) - addVoteToFrom(to, from, vote) - } -} - -func signAddVoteToFrom(voteType byte, to, from *ConsensusState, 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) { - timeout := time.NewTicker(2 * time.Second) - select { - case <-timeout.C: - panic("We should have gone to the next step, not be stuck waiting") - case <-cs.NewStepCh(): - break - } -} - -func validatePrevote(t *testing.T, cs *ConsensusState, round int, privVal *types.PrivValidator, 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 incrementRound(css ...*ConsensusState) { - for _, cs := range css { - cs.Round += 1 - } -} - -func validatePrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound int, privVal *types.PrivValidator, 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 *types.PrivValidator, votedBlockHash, lockedBlockHash []byte, f func()) { - // verify the prevote - validatePrevote(t, cs, thisRound, privVal, votedBlockHash) - if f != nil { - f() - } - // wait to finish precommit - <-cs.NewStepCh() - // verify precommit - cs.mtx.Lock() - validatePrecommit(t, cs, thisRound, lockRound, privVal, votedBlockHash, lockedBlockHash) - cs.mtx.Unlock() -} - -func simpleConsensusState(nValidators int) ([]*ConsensusState, []*types.PrivValidator) { - // Get State - state, privAccs, privVals := sm.RandGenesisState(10, true, 1000, nValidators, false, 10) - _, _ = privAccs, privVals - - fmt.Println(state.BondedValidators) - - css := make([]*ConsensusState, nValidators) - for i := 0; i < nValidators; i++ { - // Get BlockStore - blockDB := dbm.NewMemDB() - blockStore := bc.NewBlockStore(blockDB) - - // Make MempoolReactor - mempool := mempl.NewMempool(state.Copy()) - mempoolReactor := mempl.NewMempoolReactor(mempool) - - mempoolReactor.SetSwitch(p2p.NewSwitch()) - - // Make ConsensusReactor - cs := NewConsensusState(state, blockStore, mempoolReactor) - cs.SetPrivValidator(privVals[i]) - - // read off the NewHeightStep - <-cs.NewStepCh() - - css[i] = cs - } - - return css, privVals -} - -func randConsensusState() (*ConsensusState, []*types.PrivValidator) { - state, _, privValidators := sm.RandGenesisState(20, false, 1000, 10, false, 1000) - blockStore := bc.NewBlockStore(dbm.NewMemDB()) - mempool := mempl.NewMempool(state) - mempoolReactor := mempl.NewMempoolReactor(mempool) - cs := NewConsensusState(state, blockStore, mempoolReactor) - return cs, privValidators -} 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 index d0109ae1..c37793f9 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/event_cache.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/event_cache.go @@ -1,7 +1,7 @@ package events import ( - "github.com/tendermint/tendermint/types" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" ) const ( diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go index a4173d24..0ee25b18 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go @@ -3,8 +3,8 @@ package events import ( "sync" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" + . "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 diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go index 5b301bdf..8226fc66 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go @@ -1,7 +1,7 @@ package events import ( - "github.com/tendermint/tendermint/logger" + "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/p2p/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go similarity index 54% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/config.go rename to Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go index c9cbf126..e6248998 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go @@ -1,7 +1,7 @@ -package p2p +package mempool import ( - cfg "github.com/tendermint/tendermint/config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go index 0bc62b10..8fdf5aa2 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go @@ -1,7 +1,7 @@ package mempool import ( - "github.com/tendermint/tendermint/logger" + "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 index e0e09f04..5a6d5cf7 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool.go @@ -1,107 +1,226 @@ -/* -Mempool receives new transactions and applies them to the latest committed state. -If the transaction is acceptable, then it broadcasts the tx to peers. - -When this node happens to be the next proposer, it simply uses the recently -modified state (and the associated transactions) to construct a proposal. -*/ - package mempool import ( + "bytes" "sync" + "sync/atomic" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" + "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 { - mtx sync.Mutex - state *sm.State - cache *sm.BlockCache - txs []types.Tx + 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(state *sm.State) *Mempool { - return &Mempool{ - state: state, - cache: sm.NewBlockCache(state), +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() } -func (mem *Mempool) GetState() *sm.State { - return mem.state +// 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 } -func (mem *Mempool) GetCache() *sm.BlockCache { - return mem.cache +// 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 + } } -// Apply tx to the state and remember it. -func (mem *Mempool) AddTx(tx types.Tx) (err error) { - mem.mtx.Lock() - defer mem.mtx.Unlock() - err = sm.ExecTx(mem.cache, tx, false, nil) +// 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 { - log.Info("AddTx() error", "tx", tx, "error", err) - return err - } else { - log.Info("AddTx() success", "tx", tx) - mem.txs = append(mem.txs, tx) - return nil + return nil, nil, err } + + // And collect all the transactions. + txs := mem.collectTxs() + + return txs, hash, nil } -func (mem *Mempool) GetProposalTxs() []types.Tx { - mem.mtx.Lock() - defer mem.mtx.Unlock() - log.Info("GetProposalTxs:", "txs", mem.txs) - return mem.txs +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 being committed. -// "state" is the result of state.AppendBlock("block"). +// "block" is the new block that was committed. // Txs that are present in "block" are discarded from mempool. -// Txs that have become invalid in the new "state" are also discarded. -func (mem *Mempool) ResetForBlockAndState(block *types.Block, state *sm.State) { - mem.mtx.Lock() - defer mem.mtx.Unlock() - mem.state = state.Copy() - mem.cache = sm.NewBlockCache(mem.state) +// 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(types.TxID(state.ChainID, tx))] = struct{}{} + blockTxsMap[string(tx)] = struct{}{} } - // Next, filter all txs from mem.txs that are in blockTxsMap - txs := []types.Tx{} - for _, tx := range mem.txs { - txID := types.TxID(state.ChainID, tx) - if _, ok := blockTxsMap[string(txID)]; ok { - log.Info("Filter out, already committed", "tx", tx, "txID", txID) - continue - } else { - log.Info("Filter in, still new", "tx", tx, "txID", txID) - txs = append(txs, tx) + // 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 } } - // Next, filter all txs that aren't valid given new state. - validTxs := []types.Tx{} - for _, tx := range txs { - err := sm.ExecTx(mem.cache, tx, false, nil) - if err == nil { - log.Info("Filter in, valid", "tx", tx) - validTxs = append(validTxs, tx) - } else { - // tx is no longer valid. - log.Info("Filter out, no longer valid", "tx", tx, "error", 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 // +} - // We're done! - log.Info("New txs", "txs", validTxs, "oldTxs", mem.txs) - mem.txs = validTxs +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 new file mode 100644 index 00000000..b01fd685 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool_test.go @@ -0,0 +1,118 @@ +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 index 2e6e36ec..5b41c117 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/reactor.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/reactor.go @@ -4,25 +4,28 @@ import ( "bytes" "fmt" "reflect" - - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + "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" ) -var ( +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 - - evsw events.Fireable + Mempool *Mempool // TODO: un-expose + evsw events.Fireable } func NewMempoolReactor(mempool *Mempool) *MempoolReactor { @@ -44,11 +47,13 @@ func (memR *MempoolReactor) GetChannels() []*p2p.ChannelDescriptor { } // Implements Reactor -func (pexR *MempoolReactor) AddPeer(peer *p2p.Peer) { +func (memR *MempoolReactor) AddPeer(peer *p2p.Peer) { + go memR.broadcastTxRoutine(peer) } // Implements Reactor -func (pexR *MempoolReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { +func (memR *MempoolReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { + // broadcast routine checks if peer is gone and returns } // Implements Reactor @@ -62,7 +67,7 @@ func (memR *MempoolReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { switch msg := msg.(type) { case *TxMessage: - err := memR.Mempool.AddTx(msg.Tx) + err := memR.Mempool.AppendTx(msg.Tx) if err != nil { // Bad, seen, or conflicting tx. log.Info("Could not add tx", "tx", msg.Tx) @@ -70,29 +75,63 @@ func (memR *MempoolReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { } else { log.Info("Added valid tx", "tx", msg.Tx) } - // Share tx. - // We use a simple shotgun approach for now. - // TODO: improve efficiency - for _, peer := range memR.Switch.Peers().List() { - if peer.Key == src.Key { - continue - } - peer.TrySend(MempoolChannel, msg) - } - + // 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 { - err := memR.Mempool.AddTx(tx) - if err != nil { - return err + 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 } - msg := &TxMessage{Tx: tx} - memR.Switch.Broadcast(MempoolChannel, msg) - return nil } // implements events.Eventable @@ -116,9 +155,9 @@ var _ = wire.RegisterInterface( func DecodeMessage(bz []byte) (msgType byte, msg MempoolMessage, err error) { msgType = bz[0] - n := new(int64) + n := new(int) r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ MempoolMessage }{}, r, n, &err).(struct{ MempoolMessage }).MempoolMessage + msg = wire.ReadBinary(struct{ MempoolMessage }{}, r, maxMempoolMessageSize, n, &err).(struct{ MempoolMessage }).MempoolMessage return } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go index f78e7577..b0d9fc60 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go @@ -1,7 +1,7 @@ package node import ( - cfg "github.com/tendermint/tendermint/config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go index 2d52213f..825117b4 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go @@ -1,18 +1,18 @@ package node import ( - acm "github.com/tendermint/tendermint/account" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" "time" ) type NodeID struct { Name string - PubKey acm.PubKey + PubKey crypto.PubKey } type PrivNodeID struct { NodeID - PrivKey acm.PrivKey + PrivKey crypto.PrivKey } type NodeGreeting struct { @@ -25,7 +25,7 @@ type NodeGreeting struct { type SignedNodeGreeting struct { NodeGreeting - Signature acm.Signature + Signature crypto.Signature } func (pnid *PrivNodeID) SignGreeting() *SignedNodeGreeting { diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go index 65e5e78f..768cd315 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go @@ -1,7 +1,7 @@ package node import ( - "github.com/tendermint/tendermint/logger" + "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 index 99594a33..4b04f16f 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node.go @@ -2,29 +2,28 @@ package node import ( "bytes" + "io/ioutil" "math/rand" "net" "net/http" - "os" - "strconv" "strings" "time" - acm "github.com/tendermint/tendermint/account" - bc "github.com/tendermint/tendermint/blockchain" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/consensus" - dbm "github.com/tendermint/tendermint/db" - "github.com/tendermint/tendermint/events" - mempl "github.com/tendermint/tendermint/mempool" - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/rpc" - "github.com/tendermint/tendermint/rpc/core" - "github.com/tendermint/tendermint/rpc/server" - sm "github.com/tendermint/tendermint/state" - stypes "github.com/tendermint/tendermint/state/types" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + . "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" @@ -32,16 +31,14 @@ import _ "net/http/pprof" type Node struct { sw *p2p.Switch evsw *events.EventSwitch - book *p2p.AddrBook blockStore *bc.BlockStore - pexReactor *p2p.PEXReactor bcReactor *bc.BlockchainReactor mempoolReactor *mempl.MempoolReactor consensusState *consensus.ConsensusState consensusReactor *consensus.ConsensusReactor privValidator *types.PrivValidator - genDoc *stypes.GenesisDoc - privKey acm.PrivKeyEd25519 + genesisDoc *types.GenesisDoc + privKey crypto.PrivKeyEd25519 } func NewNode() *Node { @@ -50,46 +47,23 @@ func NewNode() *Node { blockStore := bc.NewBlockStore(blockStoreDB) // Get State - stateDB := dbm.GetDB("state") - state := sm.LoadState(stateDB) - var genDoc *stypes.GenesisDoc - if state == nil { - genDoc, state = sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file")) - state.Save() - // write the gendoc to db - buf, n, err := new(bytes.Buffer), new(int64), new(error) - wire.WriteJSON(genDoc, buf, n, err) - stateDB.Set(stypes.GenDocKey, buf.Bytes()) - if *err != nil { - Exit(Fmt("Unable to write gendoc to db: %v", err)) - } - } else { - genDocBytes := stateDB.Get(stypes.GenDocKey) - err := new(error) - wire.ReadJSONPtr(&genDoc, genDocBytes, err) - if *err != nil { - Exit(Fmt("Unable to read gendoc from db: %v", err)) - } - } + 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 - var privValidator *types.PrivValidator privValidatorFile := config.GetString("priv_validator_file") - if _, err := os.Stat(privValidatorFile); err == nil { - privValidator = types.LoadPrivValidator(privValidatorFile) - log.Notice("Loaded PrivValidator", - "file", privValidatorFile, "privValidator", privValidator) - } else { - privValidator = types.GenPrivValidator() - privValidator.SetFile(privValidatorFile) - privValidator.Save() - log.Notice("Generated PrivValidator", "file", privValidatorFile) - } + privValidator := types.LoadOrGenPrivValidator(privValidatorFile) // Generate node PrivKey - privKey := acm.GenPrivKeyEd25519() + privKey := crypto.GenPrivKeyEd25519() // Make event switch eventSwitch := events.NewEventSwitch() @@ -98,19 +72,15 @@ func NewNode() *Node { Exit(Fmt("Failed to start switch: %v", err)) } - // Make PEXReactor - book := p2p.NewAddrBook(config.GetString("addrbook_file")) - pexReactor := p2p.NewPEXReactor(book) - // Make BlockchainReactor - bcReactor := bc.NewBlockchainReactor(state.Copy(), blockStore, config.GetBool("fast_sync")) + bcReactor := bc.NewBlockchainReactor(state.Copy(), proxyAppCtxConsensus, blockStore, config.GetBool("fast_sync")) // Make MempoolReactor - mempool := mempl.NewMempool(state.Copy()) + mempool := mempl.NewMempool(proxyAppCtxMempool) mempoolReactor := mempl.NewMempoolReactor(mempool) // Make ConsensusReactor - consensusState := consensus.NewConsensusState(state.Copy(), blockStore, mempoolReactor) + consensusState := consensus.NewConsensusState(state.Copy(), proxyAppCtxConsensus, blockStore, mempool) consensusReactor := consensus.NewConsensusReactor(consensusState, blockStore, config.GetBool("fast_sync")) if privValidator != nil { consensusReactor.SetPrivValidator(privValidator) @@ -118,34 +88,38 @@ func NewNode() *Node { // Make p2p network switch sw := p2p.NewSwitch() - sw.AddReactor("PEX", pexReactor) 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, pexReactor, bcReactor, mempoolReactor, consensusReactor) + 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, - book: book, blockStore: blockStore, - pexReactor: pexReactor, bcReactor: bcReactor, mempoolReactor: mempoolReactor, consensusState: consensusState, consensusReactor: consensusReactor, privValidator: privValidator, - genDoc: genDoc, + genesisDoc: state.GenesisDoc, privKey: privKey, } } // Call Start() after adding the listeners. func (n *Node) Start() error { - n.book.Start() n.sw.SetNodeInfo(makeNodeInfo(n.sw, n.privKey)) n.sw.SetNodePrivKey(n.privKey) _, err := n.sw.Start() @@ -156,7 +130,6 @@ func (n *Node) Stop() { log.Notice("Stopping Node") // TODO: gracefully disconnect from peers. n.sw.Stop() - n.book.Stop() } // Add the event switch to reactors, mempool, etc. @@ -172,7 +145,6 @@ func SetFireable(evsw *events.EventSwitch, eventables ...events.Eventable) { func (n *Node) AddListener(l p2p.Listener) { log.Notice(Fmt("Added %v", l)) n.sw.AddListener(l) - n.book.AddOurAddress(l.ExternalAddress()) } // Dial a list of seeds in random order @@ -195,11 +167,9 @@ func (n *Node) dialSeed(addr *p2p.NetAddress) { peer, err := n.sw.DialPeerWithAddress(addr) if err != nil { log.Error("Error dialing seed", "error", err) - //n.book.MarkAttempt(addr) return } else { log.Notice("Connected to seed", "peer", peer) - n.book.AddAddress(addr, addr) } } @@ -210,7 +180,7 @@ func (n *Node) StartRPC() (net.Listener, error) { core.SetMempoolReactor(n.mempoolReactor) core.SetSwitch(n.sw) core.SetPrivValidator(n.privValidator) - core.SetGenDoc(n.genDoc) + core.SetGenesisDoc(n.genesisDoc) listenAddr := config.GetString("rpc_laddr") @@ -241,23 +211,23 @@ func (n *Node) EventSwitch() *events.EventSwitch { return n.evsw } -func makeNodeInfo(sw *p2p.Switch, privKey acm.PrivKeyEd25519) *types.NodeInfo { +func makeNodeInfo(sw *p2p.Switch, privKey crypto.PrivKeyEd25519) *p2p.NodeInfo { - nodeInfo := &types.NodeInfo{ - PubKey: privKey.PubKey().(acm.PubKeyEd25519), + nodeInfo := &p2p.NodeInfo{ + PubKey: privKey.PubKey().(crypto.PubKeyEd25519), Moniker: config.GetString("moniker"), - ChainID: config.GetString("chain_id"), - Version: types.Versions{ - Tendermint: Version, - P2P: p2p.Version, - RPC: rpc.Version, - Wire: wire.Version, + 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("revisions_file")); err == nil { - nodeInfo.Version.Revision = string(rev) + if rev, err := ReadFile(config.GetString("revision_file")); err == nil { + nodeInfo.Other = append(nodeInfo.Other, Fmt("revision=%v", string(rev))) } if !sw.IsListening() { @@ -268,27 +238,44 @@ func makeNodeInfo(sw *p2p.Switch, privKey acm.PrivKeyEd25519) *types.NodeInfo { p2pHost := p2pListener.ExternalAddress().IP.String() p2pPort := p2pListener.ExternalAddress().Port rpcListenAddr := config.GetString("rpc_laddr") - _, rpcPortStr, _ := net.SplitHostPort(rpcListenAddr) - rpcPort, err := strconv.Atoi(rpcPortStr) - if err != nil { - PanicSanity(Fmt("Expected numeric RPC.ListenAddr port but got %v", rpcPortStr)) - } // 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.Host = p2pHost - nodeInfo.P2PPort = p2pPort - nodeInfo.RPCPort = uint16(rpcPort) + 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")) + l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), config.GetBool("skip_upnp")) n.AddListener(l) err := n.Start() if err != nil { @@ -315,3 +302,38 @@ func RunNode() { 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 index a958c96c..d5234215 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node_test.go @@ -4,14 +4,28 @@ import ( "testing" "time" - _ "github.com/tendermint/tendermint/config/tendermint_test" - "github.com/tendermint/tendermint/p2p" + . "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")) + 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()) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/log.go deleted file mode 100644 index 7802aa76..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package p2p - -import ( - "github.com/tendermint/tendermint/logger" -) - -var log = logger.New("module", "p2p") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer_set.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer_set.go deleted file mode 100644 index 8a5f8e6d..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer_set.go +++ /dev/null @@ -1,227 +0,0 @@ -package p2p - -import ( - "net" - "strings" - "sync" -) - -// IPeerSet has a (immutable) subset of the methods of PeerSet. -type IPeerSet interface { - Has(key string) bool - Get(key string) *Peer - List() []*Peer - Size() int -} - -//----------------------------------------------------------------------------- - -var ( - maxPeersPerIPRange = [4]int{11, 7, 5, 3} // ... -) - -// PeerSet is a special structure for keeping a table of peers. -// Iteration over the peers is super fast and thread-safe. -// We also track how many peers per IP range and avoid too many -type PeerSet struct { - mtx sync.Mutex - lookup map[string]*peerSetItem - list []*Peer - connectedIPs *nestedCounter -} - -type peerSetItem struct { - peer *Peer - index int -} - -func NewPeerSet() *PeerSet { - return &PeerSet{ - lookup: make(map[string]*peerSetItem), - list: make([]*Peer, 0, 256), - connectedIPs: NewNestedCounter(), - } -} - -// Returns false if peer with key (PubKeyEd25519) is already in set -// or if we have too many peers from the peer's IP range -func (ps *PeerSet) Add(peer *Peer) error { - ps.mtx.Lock() - defer ps.mtx.Unlock() - if ps.lookup[peer.Key] != nil { - return ErrSwitchDuplicatePeer - } - - // ensure we havent maxed out connections for the peer's IP range yet - // and update the IP range counters - if !ps.incrIPRangeCounts(peer.Host) { - return ErrSwitchMaxPeersPerIPRange - } - - index := len(ps.list) - // Appending is safe even with other goroutines - // iterating over the ps.list slice. - ps.list = append(ps.list, peer) - ps.lookup[peer.Key] = &peerSetItem{peer, index} - return nil -} - -func (ps *PeerSet) Has(peerKey string) bool { - ps.mtx.Lock() - defer ps.mtx.Unlock() - _, ok := ps.lookup[peerKey] - return ok -} - -func (ps *PeerSet) Get(peerKey string) *Peer { - ps.mtx.Lock() - defer ps.mtx.Unlock() - item, ok := ps.lookup[peerKey] - if ok { - return item.peer - } else { - return nil - } -} - -func (ps *PeerSet) Remove(peer *Peer) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - item := ps.lookup[peer.Key] - if item == nil { - return - } - - // update the IP range counters - ps.decrIPRangeCounts(peer.Host) - - index := item.index - // Copy the list but without the last element. - // (we must copy because we're mutating the list) - newList := make([]*Peer, len(ps.list)-1) - copy(newList, ps.list) - // If it's the last peer, that's an easy special case. - if index == len(ps.list)-1 { - ps.list = newList - delete(ps.lookup, peer.Key) - return - } - - // Move the last item from ps.list to "index" in list. - lastPeer := ps.list[len(ps.list)-1] - lastPeerKey := lastPeer.Key - lastPeerItem := ps.lookup[lastPeerKey] - newList[index] = lastPeer - lastPeerItem.index = index - ps.list = newList - delete(ps.lookup, peer.Key) - -} - -func (ps *PeerSet) Size() int { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return len(ps.list) -} - -// threadsafe list of peers. -func (ps *PeerSet) List() []*Peer { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return ps.list -} - -//----------------------------------------------------------------------------- -// track the number of IPs we're connected to for each IP address range - -// forms an IP address hierarchy tree with counts -// the struct itself is not thread safe and should always only be accessed with the ps.mtx locked -type nestedCounter struct { - count int - children map[string]*nestedCounter -} - -func NewNestedCounter() *nestedCounter { - nc := new(nestedCounter) - nc.children = make(map[string]*nestedCounter) - return nc -} - -// Check if we have too many IPs in the IP range of the incoming connection -// Thread safe -func (ps *PeerSet) HasMaxForIPRange(conn net.Conn) (ok bool) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - ip, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) - ipBytes := strings.Split(ip, ".") - - c := ps.connectedIPs - for i, ipByte := range ipBytes { - if c, ok = c.children[ipByte]; !ok { - return false - } - if maxPeersPerIPRange[i] <= c.count { - return true - } - } - return false -} - -// Increments counts for this address' IP range -// Returns false if we already have enough connections -// Not thread safe (only called by ps.Add()) -func (ps *PeerSet) incrIPRangeCounts(address string) bool { - addrParts := strings.Split(address, ".") - - c := ps.connectedIPs - return incrNestedCounters(c, addrParts, 0) -} - -// Recursively descend the IP hierarchy, checking if we have -// max peers for each range and incrementing if not. -// Returns false if incr failed because max peers reached for some range counter. -func incrNestedCounters(c *nestedCounter, ipBytes []string, index int) bool { - ipByte := ipBytes[index] - child := c.children[ipByte] - if child == nil { - child = NewNestedCounter() - c.children[ipByte] = child - } - if index+1 < len(ipBytes) { - if !incrNestedCounters(child, ipBytes, index+1) { - return false - } - } - if maxPeersPerIPRange[index] <= child.count { - return false - } else { - child.count += 1 - return true - } -} - -// Decrement counts for this address' IP range -func (ps *PeerSet) decrIPRangeCounts(address string) { - addrParts := strings.Split(address, ".") - - c := ps.connectedIPs - decrNestedCounters(c, addrParts, 0) -} - -// Recursively descend the IP hierarchy, decrementing by one. -// If the counter is zero, deletes the child. -func decrNestedCounters(c *nestedCounter, ipBytes []string, index int) { - ipByte := ipBytes[index] - child := c.children[ipByte] - if child == nil { - log.Error("p2p/peer_set decrNestedCounters encountered a missing child counter") - return - } - if index+1 < len(ipBytes) { - decrNestedCounters(child, ipBytes, index+1) - } - child.count -= 1 - if child.count <= 0 { - delete(c.children, ipByte) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer_set_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer_set_test.go deleted file mode 100644 index 90bd8670..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/peer_set_test.go +++ /dev/null @@ -1,169 +0,0 @@ -package p2p - -import ( - "math/rand" - "strings" - "testing" - - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" -) - -// Returns an empty dummy peer -func randPeer() *Peer { - return &Peer{ - Key: RandStr(12), - NodeInfo: &types.NodeInfo{ - Host: Fmt("%v.%v.%v.%v", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256), - }, - } -} - -func TestAddRemoveOne(t *testing.T) { - peerSet := NewPeerSet() - - peer := randPeer() - err := peerSet.Add(peer) - if err != nil { - t.Errorf("Failed to add new peer") - } - if peerSet.Size() != 1 { - t.Errorf("Failed to add new peer and increment size") - } - - peerSet.Remove(peer) - if peerSet.Has(peer.Key) { - t.Errorf("Failed to remove peer") - } - if peerSet.Size() != 0 { - t.Errorf("Failed to remove peer and decrement size") - } -} - -func TestAddRemoveMany(t *testing.T) { - peerSet := NewPeerSet() - - peers := []*Peer{} - N := 100 - maxPeersPerIPRange = [4]int{N, N, N, N} - for i := 0; i < N; i++ { - peer := randPeer() - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - if peerSet.Size() != i+1 { - t.Errorf("Failed to add new peer and increment size") - } - peers = append(peers, peer) - } - - for i, peer := range peers { - peerSet.Remove(peer) - if peerSet.Has(peer.Key) { - t.Errorf("Failed to remove peer") - } - if peerSet.Size() != len(peers)-i-1 { - t.Errorf("Failed to remove peer and decrement size") - } - } -} - -func newPeerInIPRange(ipBytes ...string) *Peer { - ips := make([]string, 4) - for i, ipByte := range ipBytes { - ips[i] = ipByte - } - for i := len(ipBytes); i < 4; i++ { - ips[i] = Fmt("%v", rand.Int()%256) - } - ipS := strings.Join(ips, ".") - return &Peer{ - Key: RandStr(12), - NodeInfo: &types.NodeInfo{ - Host: ipS, - }, - } -} - -func TestIPRanges(t *testing.T) { - peerSet := NewPeerSet() - - // test /8 - maxPeersPerIPRange = [4]int{2, 2, 2, 2} - peer := newPeerInIPRange("54", "1") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - peer = newPeerInIPRange("54", "2") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - peer = newPeerInIPRange("54", "3") - if err := peerSet.Add(peer); err == nil { - t.Errorf("Added peer when we shouldn't have") - } - peer = newPeerInIPRange("55", "1") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - - // test /16 - peerSet = NewPeerSet() - maxPeersPerIPRange = [4]int{3, 2, 1, 1} - peer = newPeerInIPRange("54", "112", "1") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - peer = newPeerInIPRange("54", "112", "2") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - peer = newPeerInIPRange("54", "112", "3") - if err := peerSet.Add(peer); err == nil { - t.Errorf("Added peer when we shouldn't have") - } - peer = newPeerInIPRange("54", "113", "1") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - - // test /24 - peerSet = NewPeerSet() - maxPeersPerIPRange = [4]int{5, 3, 2, 1} - peer = newPeerInIPRange("54", "112", "11", "1") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - peer = newPeerInIPRange("54", "112", "11", "2") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - peer = newPeerInIPRange("54", "112", "11", "3") - if err := peerSet.Add(peer); err == nil { - t.Errorf("Added peer when we shouldn't have") - } - peer = newPeerInIPRange("54", "112", "12", "1") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - - // test /32 - peerSet = NewPeerSet() - maxPeersPerIPRange = [4]int{11, 7, 5, 2} - peer = newPeerInIPRange("54", "112", "11", "10") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - peer = newPeerInIPRange("54", "112", "11", "10") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } - peer = newPeerInIPRange("54", "112", "11", "10") - if err := peerSet.Add(peer); err == nil { - t.Errorf("Added peer when we shouldn't have") - } - peer = newPeerInIPRange("54", "112", "11", "11") - if err := peerSet.Add(peer); err != nil { - t.Errorf("Failed to add new peer") - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/log.go deleted file mode 100644 index 49f53c86..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/p2p/upnp/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package upnp - -import ( - "github.com/tendermint/tendermint/logger" -) - -var log = logger.New("module", "upnp") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/errors.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/errors.go deleted file mode 100644 index 4b1d7cb9..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/errors.go +++ /dev/null @@ -1,23 +0,0 @@ -package types - -import ( - "fmt" -) - -//------------------------------------------------------------------------------------------------ -// Some errors - -// permission number out of bounds -type ErrInvalidPermission PermFlag - -func (e ErrInvalidPermission) Error() string { - return fmt.Sprintf("invalid permission %d", e) -} - -// set=false. This error should be caught and the global -// value fetched for the permission by the caller -type ErrValueNotSet PermFlag - -func (e ErrValueNotSet) Error() string { - return fmt.Sprintf("the value for permission %d is not set", e) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/permissions.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/permissions.go deleted file mode 100644 index 74242ae4..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/permissions.go +++ /dev/null @@ -1,238 +0,0 @@ -package types - -import ( - "fmt" - . "github.com/tendermint/tendermint/common" -) - -//------------------------------------------------------------------------------------------------ - -var ( - GlobalPermissionsAddress = Zero256[:20] - GlobalPermissionsAddress256 = Zero256 -) - -// A particular permission -type PermFlag uint64 - -// Base permission references are like unix (the index is already bit shifted) -const ( - // chain permissions - Root PermFlag = 1 << iota // 1 - Send // 2 - Call // 4 - CreateContract // 8 - CreateAccount // 16 - Bond // 32 - Name // 64 - - // moderator permissions - HasBase - SetBase - UnsetBase - SetGlobal - HasRole - AddRole - RmRole - - NumPermissions uint = 14 // NOTE Adjust this too. We can support upto 64 - - TopPermFlag PermFlag = 1 << (NumPermissions - 1) - AllPermFlags PermFlag = TopPermFlag | (TopPermFlag - 1) - DefaultPermFlags PermFlag = Send | Call | CreateContract | CreateAccount | Bond | Name | HasBase | HasRole -) - -var ( - ZeroBasePermissions = BasePermissions{0, 0} - ZeroAccountPermissions = AccountPermissions{ - Base: ZeroBasePermissions, - } - DefaultAccountPermissions = AccountPermissions{ - Base: BasePermissions{ - Perms: DefaultPermFlags, - SetBit: AllPermFlags, - }, - Roles: []string{}, - } -) - -//--------------------------------------------------------------------------------------------- - -// Base chain permissions struct -type BasePermissions struct { - // bit array with "has"/"doesn't have" for each permission - Perms PermFlag `json:"perms"` - - // bit array with "set"/"not set" for each permission (not-set should fall back to global) - SetBit PermFlag `json:"set"` -} - -// Get a permission value. ty should be a power of 2. -// ErrValueNotSet is returned if the permission's set bit is off, -// and should be caught by caller so the global permission can be fetched -func (p *BasePermissions) Get(ty PermFlag) (bool, error) { - if ty == 0 { - return false, ErrInvalidPermission(ty) - } - if p.SetBit&ty == 0 { - return false, ErrValueNotSet(ty) - } - return p.Perms&ty > 0, nil -} - -// Set a permission bit. Will set the permission's set bit to true. -func (p *BasePermissions) Set(ty PermFlag, value bool) error { - if ty == 0 { - return ErrInvalidPermission(ty) - } - p.SetBit |= ty - if value { - p.Perms |= ty - } else { - p.Perms &= ^ty - } - return nil -} - -// Set the permission's set bit to false -func (p *BasePermissions) Unset(ty PermFlag) error { - if ty == 0 { - return ErrInvalidPermission(ty) - } - p.SetBit &= ^ty - return nil -} - -// Check if the permission is set -func (p *BasePermissions) IsSet(ty PermFlag) bool { - if ty == 0 { - return false - } - return p.SetBit&ty > 0 -} - -func (p BasePermissions) String() string { - return fmt.Sprintf("Base: %b; Set: %b", p.Perms, p.SetBit) -} - -//--------------------------------------------------------------------------------------------- - -type AccountPermissions struct { - Base BasePermissions `json:"base"` - Roles []string `json:"roles"` -} - -// Returns true if the role is found -func (aP *AccountPermissions) HasRole(role string) bool { - role = string(LeftPadBytes([]byte(role), 32)) - for _, r := range aP.Roles { - if r == role { - return true - } - } - return false -} - -// Returns true if the role is added, and false if it already exists -func (aP *AccountPermissions) AddRole(role string) bool { - role = string(LeftPadBytes([]byte(role), 32)) - for _, r := range aP.Roles { - if r == role { - return false - } - } - aP.Roles = append(aP.Roles, role) - return true -} - -// Returns true if the role is removed, and false if it is not found -func (aP *AccountPermissions) RmRole(role string) bool { - role = string(LeftPadBytes([]byte(role), 32)) - for i, r := range aP.Roles { - if r == role { - post := []string{} - if len(aP.Roles) > i+1 { - post = aP.Roles[i+1:] - } - aP.Roles = append(aP.Roles[:i], post...) - return true - } - } - return false -} - -//-------------------------------------------------------------------------------- -// string utilities - -// PermFlagToString assumes the permFlag is valid, else returns "#-UNKNOWN-#" -func PermFlagToString(pf PermFlag) (perm string) { - switch pf { - case Root: - perm = "root" - case Send: - perm = "send" - case Call: - perm = "call" - case CreateContract: - perm = "create_contract" - case CreateAccount: - perm = "create_account" - case Bond: - perm = "bond" - case Name: - perm = "name" - case HasBase: - perm = "has_base" - case SetBase: - perm = "set_base" - case UnsetBase: - perm = "unset_base" - case SetGlobal: - perm = "set_global" - case HasRole: - perm = "has_role" - case AddRole: - perm = "add_role" - case RmRole: - perm = "rm_role" - default: - perm = "#-UNKNOWN-#" - } - return -} - -func PermStringToFlag(perm string) (pf PermFlag, err error) { - switch perm { - case "root": - pf = Root - case "send": - pf = Send - case "call": - pf = Call - case "create_contract": - pf = CreateContract - case "create_account": - pf = CreateAccount - case "bond": - pf = Bond - case "name": - pf = Name - case "has_base": - pf = HasBase - case "set_base": - pf = SetBase - case "unset_base": - pf = UnsetBase - case "set_global": - pf = SetGlobal - case "has_role": - pf = HasRole - case "add_role": - pf = AddRole - case "rm_role": - pf = RmRole - default: - err = fmt.Errorf("Unknown permission %s", perm) - } - return -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/snatives.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/snatives.go deleted file mode 100644 index 3fad9bd8..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types/snatives.go +++ /dev/null @@ -1,102 +0,0 @@ -package types - -import ( - "github.com/tendermint/tendermint/wire" -) - -//--------------------------------------------------------------------------------------------------- -// PermissionsTx.PermArgs interface and argument encoding - -// Arguments are a registered interface in the PermissionsTx, -// so binary handles the arguments and each permission function gets a type-byte -// PermFlag() maps the type-byte to the permission -// The account sending the PermissionsTx must have this PermFlag set -type PermArgs interface { - PermFlag() PermFlag -} - -const ( - PermArgsTypeHasBase = byte(0x01) - PermArgsTypeSetBase = byte(0x02) - PermArgsTypeUnsetBase = byte(0x03) - PermArgsTypeSetGlobal = byte(0x04) - PermArgsTypeHasRole = byte(0x05) - PermArgsTypeAddRole = byte(0x06) - PermArgsTypeRmRole = byte(0x07) -) - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ PermArgs }{}, - wire.ConcreteType{&HasBaseArgs{}, PermArgsTypeHasBase}, - wire.ConcreteType{&SetBaseArgs{}, PermArgsTypeSetBase}, - wire.ConcreteType{&UnsetBaseArgs{}, PermArgsTypeUnsetBase}, - wire.ConcreteType{&SetGlobalArgs{}, PermArgsTypeSetGlobal}, - wire.ConcreteType{&HasRoleArgs{}, PermArgsTypeHasRole}, - wire.ConcreteType{&AddRoleArgs{}, PermArgsTypeAddRole}, - wire.ConcreteType{&RmRoleArgs{}, PermArgsTypeRmRole}, -) - -type HasBaseArgs struct { - Address []byte `json:"address"` - Permission PermFlag `json:"permission"` -} - -func (*HasBaseArgs) PermFlag() PermFlag { - return HasBase -} - -type SetBaseArgs struct { - Address []byte `json:"address"` - Permission PermFlag `json:"permission"` - Value bool `json:"value"` -} - -func (*SetBaseArgs) PermFlag() PermFlag { - return SetBase -} - -type UnsetBaseArgs struct { - Address []byte `json:"address"` - Permission PermFlag `json:"permission"` -} - -func (*UnsetBaseArgs) PermFlag() PermFlag { - return UnsetBase -} - -type SetGlobalArgs struct { - Permission PermFlag `json:"permission"` - Value bool `json:"value"` -} - -func (*SetGlobalArgs) PermFlag() PermFlag { - return SetGlobal -} - -type HasRoleArgs struct { - Address []byte `json:"address"` - Role string `json:"role"` -} - -func (*HasRoleArgs) PermFlag() PermFlag { - return HasRole -} - -type AddRoleArgs struct { - Address []byte `json:"address"` - Role string `json:"role"` -} - -func (*AddRoleArgs) PermFlag() PermFlag { - return AddRole -} - -type RmRoleArgs struct { - Address []byte `json:"address"` - Role string `json:"role"` -} - -func (*RmRoleArgs) PermFlag() PermFlag { - return RmRole -} 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 new file mode 100644 index 00000000..824599a0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/app_context.go @@ -0,0 +1,28 @@ +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 new file mode 100644 index 00000000..049bec04 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/local_app_context.go @@ -0,0 +1,123 @@ +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 new file mode 100644 index 00000000..5459d49b --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/log.go @@ -0,0 +1,7 @@ +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 new file mode 100644 index 00000000..e3a021bd --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context.go @@ -0,0 +1,310 @@ +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 new file mode 100644 index 00000000..86d388e4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context_test.go @@ -0,0 +1,98 @@ +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 index 3b138c5b..3e295549 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/client.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/client.go @@ -7,9 +7,9 @@ import ( "io/ioutil" "net/http" - . "github.com/tendermint/tendermint/common" - . "github.com/tendermint/tendermint/rpc/types" - "github.com/tendermint/tendermint/wire" + . "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) { 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 index 8b33e2f1..bfebc78d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/log.go @@ -1,7 +1,7 @@ package rpcclient import ( - "github.com/tendermint/log15" + "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/accounts.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/accounts.go deleted file mode 100644 index 47dc8889..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/accounts.go +++ /dev/null @@ -1,67 +0,0 @@ -package core - -import ( - "fmt" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - ctypes "github.com/tendermint/tendermint/rpc/core/types" -) - -func GenPrivAccount() (*ctypes.ResultGenPrivAccount, error) { - return &ctypes.ResultGenPrivAccount{acm.GenPrivAccount()}, nil -} - -// If the account is not known, returns nil, nil. -func GetAccount(address []byte) (*ctypes.ResultGetAccount, error) { - cache := mempoolReactor.Mempool.GetCache() - account := cache.GetAccount(address) - if account == nil { - return nil, nil - } - return &ctypes.ResultGetAccount{account}, nil -} - -func GetStorage(address, key []byte) (*ctypes.ResultGetStorage, error) { - state := consensusState.GetState() - account := state.GetAccount(address) - if account == nil { - return nil, fmt.Errorf("UnknownAddress: %X", address) - } - storageRoot := account.StorageRoot - storageTree := state.LoadStorage(storageRoot) - - _, value := storageTree.Get(LeftPadWord256(key).Bytes()) - if value == nil { - return &ctypes.ResultGetStorage{key, nil}, nil - } - return &ctypes.ResultGetStorage{key, value.([]byte)}, nil -} - -func ListAccounts() (*ctypes.ResultListAccounts, error) { - var blockHeight int - var accounts []*acm.Account - state := consensusState.GetState() - blockHeight = state.LastBlockHeight - state.GetAccounts().Iterate(func(key interface{}, value interface{}) bool { - accounts = append(accounts, value.(*acm.Account)) - return false - }) - return &ctypes.ResultListAccounts{blockHeight, accounts}, nil -} - -func DumpStorage(address []byte) (*ctypes.ResultDumpStorage, error) { - state := consensusState.GetState() - account := state.GetAccount(address) - if account == nil { - return nil, fmt.Errorf("UnknownAddress: %X", address) - } - storageRoot := account.StorageRoot - storageTree := state.LoadStorage(storageRoot) - storageItems := []ctypes.StorageItem{} - storageTree.Iterate(func(key interface{}, value interface{}) bool { - storageItems = append(storageItems, ctypes.StorageItem{ - key.([]byte), value.([]byte)}) - return false - }) - return &ctypes.ResultDumpStorage{storageRoot, storageItems}, nil -} 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 index 427390a2..ad61bac5 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/blocks.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/blocks.go @@ -2,9 +2,9 @@ package core import ( "fmt" - . "github.com/tendermint/tendermint/common" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/types" + . "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" ) //----------------------------------------------------------------------------- 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 index c2593d5b..bf269a70 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/config.go @@ -1,7 +1,7 @@ package core import ( - cfg "github.com/tendermint/tendermint/config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config = nil 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 index d6abcf72..ea621b13 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/consensus.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/consensus.go @@ -1,29 +1,24 @@ package core import ( - cm "github.com/tendermint/tendermint/consensus" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + "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 bondedValidators []*types.Validator - var unbondingValidators []*types.Validator + var validators []*types.Validator state := consensusState.GetState() blockHeight = state.LastBlockHeight - state.BondedValidators.Iterate(func(index int, val *types.Validator) bool { - bondedValidators = append(bondedValidators, val) - return false - }) - state.UnbondingValidators.Iterate(func(index int, val *types.Validator) bool { - unbondingValidators = append(unbondingValidators, val) + state.Validators.Iterate(func(index int, val *types.Validator) bool { + validators = append(validators, val) return false }) - return &ctypes.ResultListValidators{blockHeight, bondedValidators, unbondingValidators}, nil + return &ctypes.ResultListValidators{blockHeight, validators}, nil } func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { @@ -31,7 +26,7 @@ func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { peerRoundStates := []string{} for _, peer := range p2pSwitch.Peers().List() { // TODO: clean this up? - peerState := peer.Data.Get(cm.PeerStateKey).(*cm.PeerState) + peerState := peer.Data.Get(types.PeerStateKey).(*cm.PeerState) peerRoundState := peerState.GetRoundState() peerRoundStateStr := peer.Key + ":" + string(wire.JSONBytes(peerRoundState)) peerRoundStates = append(peerRoundStates, peerRoundStateStr) 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 index d359bee2..a0dfe3d8 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/log.go @@ -1,7 +1,7 @@ package core import ( - "github.com/tendermint/log15" + "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 index eaf1d5c6..00cbacf5 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/mempool.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/mempool.go @@ -2,9 +2,8 @@ package core import ( "fmt" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" + 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" ) //----------------------------------------------------------------------------- @@ -15,20 +14,10 @@ func BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { if err != nil { return nil, fmt.Errorf("Error broadcasting transaction: %v", err) } - - txHash := types.TxID(mempoolReactor.Mempool.GetState().ChainID, tx) - var createsContract uint8 - var contractAddr []byte - // check if creates new contract - if callTx, ok := tx.(*types.CallTx); ok { - if len(callTx.Address) == 0 { - createsContract = 1 - contractAddr = state.NewContractAddress(callTx.Input.Address, callTx.Input.Sequence) - } - } - return &ctypes.ResultBroadcastTx{ctypes.Receipt{txHash, createsContract, contractAddr}}, nil + return &ctypes.ResultBroadcastTx{}, nil } func ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) { - return &ctypes.ResultListUnconfirmedTxs{mempoolReactor.Mempool.GetProposalTxs()}, nil + txs, _, err := mempoolReactor.Mempool.Reap() + return &ctypes.ResultListUnconfirmedTxs{len(txs), txs}, err } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/names.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/names.go deleted file mode 100644 index 318beaaf..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/names.go +++ /dev/null @@ -1,29 +0,0 @@ -package core - -import ( - "fmt" - - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/types" -) - -func GetName(name string) (*ctypes.ResultGetName, error) { - st := consensusState.GetState() // performs a copy - entry := st.GetNameRegEntry(name) - if entry == nil { - return nil, fmt.Errorf("Name %s not found", name) - } - return &ctypes.ResultGetName{entry}, nil -} - -func ListNames() (*ctypes.ResultListNames, error) { - var blockHeight int - var names []*types.NameRegEntry - state := consensusState.GetState() - blockHeight = state.LastBlockHeight - state.GetNames().Iterate(func(key interface{}, value interface{}) bool { - names = append(names, value.(*types.NameRegEntry)) - return false - }) - return &ctypes.ResultListNames{blockHeight, names}, nil -} 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 index 7ce50312..09f8555f 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/net.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/net.go @@ -1,23 +1,14 @@ package core import ( - dbm "github.com/tendermint/tendermint/db" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" + 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" ) //----------------------------------------------------------------------------- -// cache the genesis state -var genesisState *sm.State - +// TODO Move to status.go or node.go func Status() (*ctypes.ResultStatus, error) { - db := dbm.NewMemDB() - if genesisState == nil { - genesisState = sm.MakeGenesisState(db, genDoc) - } - genesisHash := genesisState.Hash() latestHeight := blockStore.Height() var ( latestBlockMeta *types.BlockMeta @@ -32,7 +23,6 @@ func Status() (*ctypes.ResultStatus, error) { return &ctypes.ResultStatus{ NodeInfo: p2pSwitch.NodeInfo(), - GenesisHash: genesisHash, PubKey: privValidator.PubKey, LatestBlockHash: latestBlockHash, LatestBlockHeight: latestHeight, 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 index 1cad8013..98ec21ec 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/pipe.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/pipe.go @@ -1,12 +1,11 @@ package core import ( - bc "github.com/tendermint/tendermint/blockchain" - "github.com/tendermint/tendermint/consensus" - mempl "github.com/tendermint/tendermint/mempool" - "github.com/tendermint/tendermint/p2p" - stypes "github.com/tendermint/tendermint/state/types" - "github.com/tendermint/tendermint/types" + "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 @@ -15,7 +14,7 @@ var consensusReactor *consensus.ConsensusReactor var mempoolReactor *mempl.MempoolReactor var p2pSwitch *p2p.Switch var privValidator *types.PrivValidator -var genDoc *stypes.GenesisDoc // cache the genesis structure +var genDoc *types.GenesisDoc // cache the genesis structure func SetBlockStore(bs *bc.BlockStore) { blockStore = bs @@ -41,6 +40,6 @@ func SetPrivValidator(pv *types.PrivValidator) { privValidator = pv } -func SetGenDoc(doc *stypes.GenesisDoc) { +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 index afc9586a..dcbde192 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/routes.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/routes.go @@ -1,29 +1,19 @@ package core import ( - rpc "github.com/tendermint/tendermint/rpc/server" + 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"}), - "get_account": rpc.NewRPCFunc(GetAccount, []string{"address"}), - "get_storage": rpc.NewRPCFunc(GetStorage, []string{"address", "key"}), - "call": rpc.NewRPCFunc(Call, []string{"fromAddress", "toAddress", "data"}), - "call_code": rpc.NewRPCFunc(CallCode, []string{"fromAddress", "code", "data"}), - "list_validators": rpc.NewRPCFunc(ListValidators, []string{}), - "dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, []string{}), - "dump_storage": rpc.NewRPCFunc(DumpStorage, []string{"address"}), - "broadcast_tx": rpc.NewRPCFunc(BroadcastTx, []string{"tx"}), - "list_unconfirmed_txs": rpc.NewRPCFunc(ListUnconfirmedTxs, []string{}), - "list_accounts": rpc.NewRPCFunc(ListAccounts, []string{}), - "get_name": rpc.NewRPCFunc(GetName, []string{"name"}), - "list_names": rpc.NewRPCFunc(ListNames, []string{}), - "unsafe/gen_priv_account": rpc.NewRPCFunc(GenPrivAccount, []string{}), - "unsafe/sign_tx": rpc.NewRPCFunc(SignTx, []string{"tx", "privAccounts"}), + "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/txs.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/txs.go deleted file mode 100644 index 073b6665..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/txs.go +++ /dev/null @@ -1,116 +0,0 @@ -package core - -import ( - "fmt" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/vm" -) - -func toVMAccount(acc *acm.Account) *vm.Account { - return &vm.Account{ - Address: LeftPadWord256(acc.Address), - Balance: acc.Balance, - Code: acc.Code, // This is crazy. - Nonce: int64(acc.Sequence), - Other: acc.PubKey, - } -} - -//----------------------------------------------------------------------------- - -// Run a contract's code on an isolated and unpersisted state -// Cannot be used to create new contracts -func Call(fromAddress, toAddress, data []byte) (*ctypes.ResultCall, error) { - st := consensusState.GetState() // performs a copy - cache := state.NewBlockCache(st) - outAcc := cache.GetAccount(toAddress) - if outAcc == nil { - return nil, fmt.Errorf("Account %x does not exist", toAddress) - } - callee := toVMAccount(outAcc) - caller := &vm.Account{Address: LeftPadWord256(fromAddress)} - txCache := state.NewTxCache(cache) - params := vm.Params{ - BlockHeight: int64(st.LastBlockHeight), - BlockHash: LeftPadWord256(st.LastBlockHash), - BlockTime: st.LastBlockTime.Unix(), - GasLimit: st.GetGasLimit(), - } - - vmach := vm.NewVM(txCache, params, caller.Address, nil) - gas := st.GetGasLimit() - ret, err := vmach.Call(caller, callee, callee.Code, data, 0, &gas) - if err != nil { - return nil, err - } - return &ctypes.ResultCall{Return: ret}, nil -} - -// Run the given code on an isolated and unpersisted state -// Cannot be used to create new contracts -func CallCode(fromAddress, code, data []byte) (*ctypes.ResultCall, error) { - - st := consensusState.GetState() // performs a copy - cache := mempoolReactor.Mempool.GetCache() - callee := &vm.Account{Address: LeftPadWord256(fromAddress)} - caller := &vm.Account{Address: LeftPadWord256(fromAddress)} - txCache := state.NewTxCache(cache) - params := vm.Params{ - BlockHeight: int64(st.LastBlockHeight), - BlockHash: LeftPadWord256(st.LastBlockHash), - BlockTime: st.LastBlockTime.Unix(), - GasLimit: st.GetGasLimit(), - } - - vmach := vm.NewVM(txCache, params, caller.Address, nil) - gas := st.GetGasLimit() - ret, err := vmach.Call(caller, callee, code, data, 0, &gas) - if err != nil { - return nil, err - } - return &ctypes.ResultCall{Return: ret}, nil -} - -//----------------------------------------------------------------------------- - -func SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (*ctypes.ResultSignTx, error) { - // more checks? - - for i, privAccount := range privAccounts { - if privAccount == nil || privAccount.PrivKey == nil { - return nil, fmt.Errorf("Invalid (empty) privAccount @%v", i) - } - } - switch tx.(type) { - case *types.SendTx: - sendTx := tx.(*types.SendTx) - for i, input := range sendTx.Inputs { - input.PubKey = privAccounts[i].PubKey - input.Signature = privAccounts[i].Sign(config.GetString("chain_id"), sendTx) - } - case *types.CallTx: - callTx := tx.(*types.CallTx) - callTx.Input.PubKey = privAccounts[0].PubKey - callTx.Input.Signature = privAccounts[0].Sign(config.GetString("chain_id"), callTx) - case *types.BondTx: - bondTx := tx.(*types.BondTx) - // the first privaccount corresponds to the BondTx pub key. - // the rest to the inputs - bondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), bondTx).(acm.SignatureEd25519) - for i, input := range bondTx.Inputs { - input.PubKey = privAccounts[i+1].PubKey - input.Signature = privAccounts[i+1].Sign(config.GetString("chain_id"), bondTx) - } - case *types.UnbondTx: - unbondTx := tx.(*types.UnbondTx) - unbondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), unbondTx).(acm.SignatureEd25519) - case *types.RebondTx: - rebondTx := tx.(*types.RebondTx) - rebondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), rebondTx).(acm.SignatureEd25519) - } - return &ctypes.ResultSignTx{tx}, nil -} 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 index e756544c..702b9eca 100644 --- 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 @@ -1,38 +1,12 @@ package core_types import ( - acm "github.com/tendermint/tendermint/account" - stypes "github.com/tendermint/tendermint/state/types" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + "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 ResultGetStorage struct { - Key []byte `json:"key"` - Value []byte `json:"value"` -} - -type ResultCall struct { - Return []byte `json:"return"` - GasUsed int64 `json:"gas_used"` - // TODO ... -} - -type ResultListAccounts struct { - BlockHeight int `json:"block_height"` - Accounts []*acm.Account `json:"accounts"` -} - -type ResultDumpStorage struct { - StorageRoot []byte `json:"storage_root"` - StorageItems []StorageItem `json:"storage_items"` -} - -type StorageItem struct { - Key []byte `json:"key"` - Value []byte `json:"value"` -} - type ResultBlockchainInfo struct { LastHeight int `json:"last_height"` BlockMetas []*types.BlockMeta `json:"block_metas"` @@ -44,12 +18,11 @@ type ResultGetBlock struct { } type ResultStatus struct { - NodeInfo *types.NodeInfo `json:"node_info"` - GenesisHash []byte `json:"genesis_hash"` - PubKey acm.PubKey `json:"pub_key"` - LatestBlockHash []byte `json:"latest_block_hash"` - LatestBlockHeight int `json:"latest_block_height"` - LatestBlockTime int64 `json:"latest_block_time"` // nano + 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 { @@ -59,14 +32,13 @@ type ResultNetInfo struct { } type Peer struct { - types.NodeInfo `json:"node_info"` - IsOutbound bool `json:"is_outbound"` + p2p.NodeInfo `json:"node_info"` + IsOutbound bool `json:"is_outbound"` } type ResultListValidators struct { - BlockHeight int `json:"block_height"` - BondedValidators []*types.Validator `json:"bonded_validators"` - UnbondingValidators []*types.Validator `json:"unbonding_validators"` + BlockHeight int `json:"block_height"` + Validators []*types.Validator `json:"validators"` } type ResultDumpConsensusState struct { @@ -74,43 +46,16 @@ type ResultDumpConsensusState struct { PeerRoundStates []string `json:"peer_round_states"` } -type ResultListNames struct { - BlockHeight int `json:"block_height"` - Names []*types.NameRegEntry `json:"names"` -} - -type ResultGenPrivAccount struct { - PrivAccount *acm.PrivAccount `json:"priv_account"` -} - -type ResultGetAccount struct { - Account *acm.Account `json:"account"` -} - type ResultBroadcastTx struct { - Receipt Receipt `json:"receipt"` -} - -type Receipt struct { - TxHash []byte `json:"tx_hash"` - CreatesContract uint8 `json:"creates_contract"` - ContractAddr []byte `json:"contract_addr"` } type ResultListUnconfirmedTxs struct { + N int `json:"n_txs"` Txs []types.Tx `json:"txs"` } -type ResultGetName struct { - Entry *types.NameRegEntry `json:"entry"` -} - type ResultGenesis struct { - Genesis *stypes.GenesisDoc `json:"genesis"` -} - -type ResultSignTx struct { - Tx types.Tx `json:"tx"` + Genesis *types.GenesisDoc `json:"genesis"` } type ResultEvent struct { @@ -129,24 +74,15 @@ type Response struct { } const ( - ResultTypeGetStorage = byte(0x01) - ResultTypeCall = byte(0x02) - ResultTypeListAccounts = byte(0x03) - ResultTypeDumpStorage = byte(0x04) ResultTypeBlockchainInfo = byte(0x05) ResultTypeGetBlock = byte(0x06) ResultTypeStatus = byte(0x07) ResultTypeNetInfo = byte(0x08) ResultTypeListValidators = byte(0x09) ResultTypeDumpConsensusState = byte(0x0A) - ResultTypeListNames = byte(0x0B) - ResultTypeGenPrivAccount = byte(0x0C) - ResultTypeGetAccount = byte(0x0D) ResultTypeBroadcastTx = byte(0x0E) ResultTypeListUnconfirmedTxs = byte(0x0F) - ResultTypeGetName = byte(0x10) ResultTypeGenesis = byte(0x11) - ResultTypeSignTx = byte(0x12) ResultTypeEvent = byte(0x13) // so websockets can respond to rpc functions ) @@ -155,23 +91,14 @@ type Result interface{} // for wire.readReflect var _ = wire.RegisterInterface( struct{ Result }{}, - wire.ConcreteType{&ResultGetStorage{}, ResultTypeGetStorage}, - wire.ConcreteType{&ResultCall{}, ResultTypeCall}, - wire.ConcreteType{&ResultListAccounts{}, ResultTypeListAccounts}, - wire.ConcreteType{&ResultDumpStorage{}, ResultTypeDumpStorage}, 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{&ResultListNames{}, ResultTypeListNames}, - wire.ConcreteType{&ResultGenPrivAccount{}, ResultTypeGenPrivAccount}, - wire.ConcreteType{&ResultGetAccount{}, ResultTypeGetAccount}, wire.ConcreteType{&ResultBroadcastTx{}, ResultTypeBroadcastTx}, wire.ConcreteType{&ResultListUnconfirmedTxs{}, ResultTypeListUnconfirmedTxs}, - wire.ConcreteType{&ResultGetName{}, ResultTypeGetName}, wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis}, - wire.ConcreteType{&ResultSignTx{}, ResultTypeSignTx}, wire.ConcreteType{&ResultEvent{}, ResultTypeEvent}, ) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/client.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/client.go deleted file mode 100644 index c2417248..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/client.go +++ /dev/null @@ -1,236 +0,0 @@ -package core_client - -import ( - "bytes" - "fmt" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - rpctypes "github.com/tendermint/tendermint/rpc/types" - "github.com/tendermint/tendermint/wire" - "io/ioutil" - "net/http" - "net/url" - - //"reflect" - // Uncomment to use go:generate - // _ "github.com/tendermint/go-rpc-gen" -) - -// maps camel-case function names to lower case rpc version -var reverseFuncMap = map[string]string{ - "Status": "status", - "NetInfo": "net_info", - "BlockchainInfo": "blockchain", - "Genesis": "genesis", - "GetBlock": "get_block", - "GetAccount": "get_account", - "GetStorage": "get_storage", - "Call": "call", - "CallCode": "call_code", - "ListValidators": "list_validators", - "DumpConsensusState": "dump_consensus_state", - "DumpStorage": "dump_storage", - "BroadcastTx": "broadcast_tx", - "ListUnconfirmedTxs": "list_unconfirmed_txs", - "ListAccounts": "list_accounts", - "GetName": "get_name", - "ListNames": "list_names", - "GenPrivAccount": "unsafe/gen_priv_account", - "SignTx": "unsafe/sign_tx", -} - -/* -// fill the map from camelcase to lowercase -func fillReverseFuncMap() map[string]string { - fMap := make(map[string]string) - for name, f := range core.Routes { - camelName := runtime.FuncForPC(f.f.Pointer()).Name() - spl := strings.Split(camelName, ".") - if len(spl) > 1 { - camelName = spl[len(spl)-1] - } - fMap[camelName] = name - } - return fMap -} -*/ - -type Response struct { - Status string - Data interface{} - Error string -} - -//go:generate go-rpc-gen -interface Client -dir ../core -pkg core -type *ClientHTTP,*ClientJSON -exclude pipe.go -out-pkg core_client - -type ClientJSON struct { - addr string -} - -type ClientHTTP struct { - addr string -} - -func NewClient(addr, typ string) Client { - switch typ { - case "HTTP": - return &ClientHTTP{addr} - case "JSONRPC": - return &ClientJSON{addr} - default: - panic("Unknown client type " + typ + ". Select HTTP or JSONRPC") - } - return nil -} - -func argsToJson(args ...interface{}) ([]string, error) { - l := len(args) - jsons := make([]string, l) - n, err := new(int64), new(error) - for i, a := range args { - buf := new(bytes.Buffer) - wire.WriteJSON(a, buf, n, err) - if *err != nil { - return nil, *err - } - jsons[i] = string(buf.Bytes()) - } - return jsons, nil -} - -func (c *ClientJSON) RequestResponse(s rpctypes.RPCRequest) (b []byte, err error) { - b = wire.JSONBytes(s) - buf := bytes.NewBuffer(b) - resp, err := http.Post(c.addr, "text/json", buf) - if err != nil { - return nil, err - } - defer resp.Body.Close() - return ioutil.ReadAll(resp.Body) -} - -/* - What follows is used by `rpc-gen` when `go generate` is called - to populate the rpc client methods -*/ - -// first we define the base interface, which rpc-gen will further populate with generated methods - -/*rpc-gen:define-interface Client -type Client interface { - Address() string // returns the remote address -} -*/ - -// encoding functions - -func binaryWriter(args ...interface{}) ([]interface{}, error) { - list := []interface{}{} - for _, a := range args { - buf, n, err := new(bytes.Buffer), new(int64), new(error) - wire.WriteJSON(a, buf, n, err) - if *err != nil { - return nil, *err - } - list = append(list, buf.Bytes()) - - } - return list, nil -} - -func argsToURLValues(argNames []string, args ...interface{}) (url.Values, error) { - values := make(url.Values) - if len(argNames) == 0 { - return values, nil - } - if len(argNames) != len(args) { - return nil, fmt.Errorf("argNames and args have different lengths: %d, %d", len(argNames), len(args)) - } - slice, err := argsToJson(args...) - if err != nil { - return nil, err - } - for i, name := range argNames { - s := slice[i] - values.Set(name, s) // s[0] - /*for j := 1; j < len(s); j++ { - values.Add(name, s[j]) - }*/ - } - return values, nil -} - -func unmarshalCheckResponse(body []byte) (response *ctypes.Response, err error) { - response = new(ctypes.Response) - wire.ReadJSON(response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response, nil -} - -// import statements we will need for the templates - -/*rpc-gen:imports: -rpctypes github.com/tendermint/tendermint/rpc/types -net/http -io/ioutil -fmt -*/ - -// Template functions to be filled in - -/*rpc-gen:template:*ClientJSON func (c *ClientJSON) {{name}}({{args.def}}) ({{response}}) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["{{name}}"], - Params: []interface{}{ {{args.ident}} }, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil{ - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil{ - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.({{response.0}}) - if !ok{ - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -}*/ - -/*rpc-gen:template:*ClientHTTP func (c *ClientHTTP) {{name}}({{args.def}}) ({{response}}){ - values, err := argsToURLValues({{args.name}}, {{args.ident}}) - if err != nil{ - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["{{name}}"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil{ - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.({{response.0}}) - if !ok{ - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -}*/ diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/client_methods.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/client_methods.go deleted file mode 100644 index 29c2ac53..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/client_methods.go +++ /dev/null @@ -1,1042 +0,0 @@ -// File generated by github.com/ebuchman/rpc-gen - -package core_client - -import ( - "fmt" - acm "github.com/tendermint/tendermint/account" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - rpctypes "github.com/tendermint/tendermint/rpc/types" - "github.com/tendermint/tendermint/types" - "io/ioutil" - "net/http" -) - -type Client interface { - BlockchainInfo(minHeight int, maxHeight int) (*ctypes.ResultBlockchainInfo, error) - BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) - Call(fromAddress []byte, toAddress []byte, data []byte) (*ctypes.ResultCall, error) - CallCode(fromAddress []byte, code []byte, data []byte) (*ctypes.ResultCall, error) - DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) - DumpStorage(address []byte) (*ctypes.ResultDumpStorage, error) - GenPrivAccount() (*ctypes.ResultGenPrivAccount, error) - Genesis() (*ctypes.ResultGenesis, error) - GetAccount(address []byte) (*ctypes.ResultGetAccount, error) - GetBlock(height int) (*ctypes.ResultGetBlock, error) - GetName(name string) (*ctypes.ResultGetName, error) - GetStorage(address []byte, key []byte) (*ctypes.ResultGetStorage, error) - ListAccounts() (*ctypes.ResultListAccounts, error) - ListNames() (*ctypes.ResultListNames, error) - ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) - ListValidators() (*ctypes.ResultListValidators, error) - NetInfo() (*ctypes.ResultNetInfo, error) - SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (*ctypes.ResultSignTx, error) - Status() (*ctypes.ResultStatus, error) -} - -func (c *ClientHTTP) BlockchainInfo(minHeight int, maxHeight int) (*ctypes.ResultBlockchainInfo, error) { - values, err := argsToURLValues([]string{"minHeight", "maxHeight"}, minHeight, maxHeight) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["BlockchainInfo"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultBlockchainInfo) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - values, err := argsToURLValues([]string{"tx"}, tx) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["BroadcastTx"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultBroadcastTx) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) Call(fromAddress []byte, toAddress []byte, data []byte) (*ctypes.ResultCall, error) { - values, err := argsToURLValues([]string{"fromAddress", "toAddress", "data"}, fromAddress, toAddress, data) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["Call"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultCall) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) CallCode(fromAddress []byte, code []byte, data []byte) (*ctypes.ResultCall, error) { - values, err := argsToURLValues([]string{"fromAddress", "code", "data"}, fromAddress, code, data) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["CallCode"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultCall) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["DumpConsensusState"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultDumpConsensusState) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) DumpStorage(address []byte) (*ctypes.ResultDumpStorage, error) { - values, err := argsToURLValues([]string{"address"}, address) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["DumpStorage"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultDumpStorage) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) GenPrivAccount() (*ctypes.ResultGenPrivAccount, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["GenPrivAccount"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGenPrivAccount) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) Genesis() (*ctypes.ResultGenesis, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["Genesis"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGenesis) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) GetAccount(address []byte) (*ctypes.ResultGetAccount, error) { - values, err := argsToURLValues([]string{"address"}, address) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["GetAccount"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGetAccount) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) GetBlock(height int) (*ctypes.ResultGetBlock, error) { - values, err := argsToURLValues([]string{"height"}, height) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["GetBlock"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGetBlock) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) GetName(name string) (*ctypes.ResultGetName, error) { - values, err := argsToURLValues([]string{"name"}, name) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["GetName"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGetName) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) GetStorage(address []byte, key []byte) (*ctypes.ResultGetStorage, error) { - values, err := argsToURLValues([]string{"address", "key"}, address, key) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["GetStorage"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGetStorage) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) ListAccounts() (*ctypes.ResultListAccounts, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["ListAccounts"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultListAccounts) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) ListNames() (*ctypes.ResultListNames, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["ListNames"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultListNames) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["ListUnconfirmedTxs"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultListUnconfirmedTxs) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) ListValidators() (*ctypes.ResultListValidators, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["ListValidators"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultListValidators) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) NetInfo() (*ctypes.ResultNetInfo, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["NetInfo"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultNetInfo) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (*ctypes.ResultSignTx, error) { - values, err := argsToURLValues([]string{"tx", "privAccounts"}, tx, privAccounts) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["SignTx"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultSignTx) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientHTTP) Status() (*ctypes.ResultStatus, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["Status"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultStatus) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) BlockchainInfo(minHeight int, maxHeight int) (*ctypes.ResultBlockchainInfo, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["BlockchainInfo"], - Params: []interface{}{minHeight, maxHeight}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultBlockchainInfo) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["BroadcastTx"], - Params: []interface{}{tx}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultBroadcastTx) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) Call(fromAddress []byte, toAddress []byte, data []byte) (*ctypes.ResultCall, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["Call"], - Params: []interface{}{fromAddress, toAddress, data}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultCall) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) CallCode(fromAddress []byte, code []byte, data []byte) (*ctypes.ResultCall, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["CallCode"], - Params: []interface{}{fromAddress, code, data}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultCall) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["DumpConsensusState"], - Params: []interface{}{}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultDumpConsensusState) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) DumpStorage(address []byte) (*ctypes.ResultDumpStorage, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["DumpStorage"], - Params: []interface{}{address}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultDumpStorage) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) GenPrivAccount() (*ctypes.ResultGenPrivAccount, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GenPrivAccount"], - Params: []interface{}{}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGenPrivAccount) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) Genesis() (*ctypes.ResultGenesis, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["Genesis"], - Params: []interface{}{}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGenesis) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) GetAccount(address []byte) (*ctypes.ResultGetAccount, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GetAccount"], - Params: []interface{}{address}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGetAccount) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) GetBlock(height int) (*ctypes.ResultGetBlock, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GetBlock"], - Params: []interface{}{height}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGetBlock) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) GetName(name string) (*ctypes.ResultGetName, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GetName"], - Params: []interface{}{name}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGetName) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) GetStorage(address []byte, key []byte) (*ctypes.ResultGetStorage, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GetStorage"], - Params: []interface{}{address, key}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultGetStorage) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) ListAccounts() (*ctypes.ResultListAccounts, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["ListAccounts"], - Params: []interface{}{}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultListAccounts) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) ListNames() (*ctypes.ResultListNames, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["ListNames"], - Params: []interface{}{}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultListNames) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["ListUnconfirmedTxs"], - Params: []interface{}{}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultListUnconfirmedTxs) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) ListValidators() (*ctypes.ResultListValidators, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["ListValidators"], - Params: []interface{}{}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultListValidators) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) NetInfo() (*ctypes.ResultNetInfo, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["NetInfo"], - Params: []interface{}{}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultNetInfo) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (*ctypes.ResultSignTx, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["SignTx"], - Params: []interface{}{tx, privAccounts}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultSignTx) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} - -func (c *ClientJSON) Status() (*ctypes.ResultStatus, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["Status"], - Params: []interface{}{}, - ID: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - response, err := unmarshalCheckResponse(body) - if err != nil { - return nil, err - } - if response.Result == nil { - return nil, nil - } - result, ok := response.Result.(*ctypes.ResultStatus) - if !ok { - return nil, fmt.Errorf("response result was wrong type") - } - return result, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/log.go deleted file mode 100644 index 54b638dc..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package core_client - -import ( - "github.com/tendermint/log15" -) - -var log = log15.New("module", "core_client") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/ws_client.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/ws_client.go deleted file mode 100644 index f2625ec3..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core_client/ws_client.go +++ /dev/null @@ -1,119 +0,0 @@ -package core_client - -import ( - "net/http" - "strings" - "time" - - "github.com/gorilla/websocket" - . "github.com/tendermint/tendermint/common" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/rpc/types" - "github.com/tendermint/tendermint/wire" -) - -const ( - wsEventsChannelCapacity = 10 - wsResultsChannelCapacity = 10 - wsWriteTimeoutSeconds = 10 -) - -type WSClient struct { - QuitService - Address string - *websocket.Conn - EventsCh chan ctypes.ResultEvent - ResultsCh chan ctypes.Result -} - -// create a new connection -func NewWSClient(addr string) *WSClient { - wsClient := &WSClient{ - Address: addr, - Conn: nil, - EventsCh: make(chan ctypes.ResultEvent, wsEventsChannelCapacity), - ResultsCh: make(chan ctypes.Result, wsResultsChannelCapacity), - } - wsClient.QuitService = *NewQuitService(log, "WSClient", wsClient) - return wsClient -} - -func (wsc *WSClient) OnStart() error { - wsc.QuitService.OnStart() - err := wsc.dial() - if err != nil { - return err - } - go wsc.receiveEventsRoutine() - return nil -} - -func (wsc *WSClient) dial() error { - // Dial - dialer := websocket.DefaultDialer - rHeader := http.Header{} - con, _, err := dialer.Dial(wsc.Address, rHeader) - if err != nil { - return err - } - // Set the ping/pong handlers - con.SetPingHandler(func(m string) error { - con.WriteControl(websocket.PongMessage, []byte(m), time.Now().Add(time.Second*wsWriteTimeoutSeconds)) - return nil - }) - con.SetPongHandler(func(m string) error { - return nil - }) - wsc.Conn = con - return nil -} - -func (wsc *WSClient) OnStop() { - wsc.QuitService.OnStop() -} - -func (wsc *WSClient) receiveEventsRoutine() { - for { - _, data, err := wsc.ReadMessage() - if err != nil { - log.Info("WSClient failed to read message", "error", err, "data", string(data)) - wsc.Stop() - break - } else { - var response ctypes.Response - wire.ReadJSON(&response, data, &err) - if err != nil { - log.Info("WSClient failed to parse message", "error", err) - wsc.Stop() - break - } - if strings.HasSuffix(response.ID, "#event") { - wsc.EventsCh <- *response.Result.(*ctypes.ResultEvent) - } else { - wsc.ResultsCh <- response.Result - } - } - } -} - -// subscribe to an event -func (wsc *WSClient) Subscribe(eventid string) error { - err := wsc.WriteJSON(rpctypes.RPCRequest{ - JSONRPC: "2.0", - ID: "", - Method: "subscribe", - Params: []interface{}{eventid}, - }) - return err -} - -// unsubscribe from an event -func (wsc *WSClient) Unsubscribe(eventid string) error { - err := wsc.WriteJSON(rpctypes.RPCRequest{ - JSONRPC: "2.0", - ID: "", - Method: "unsubscribe", - Params: []interface{}{eventid}, - }) - return err -} 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 index 69334367..42e59285 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/handlers.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/handlers.go @@ -11,13 +11,13 @@ import ( "sort" "time" - "github.com/gorilla/websocket" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - . "github.com/tendermint/tendermint/rpc/types" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + "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) { @@ -393,7 +393,7 @@ func (wsc *WSConnection) readRoutine() { // receives on a write channel and writes out on the socket func (wsc *WSConnection) writeRoutine() { defer wsc.baseConn.Close() - var n, err = int64(0), error(nil) + var n, err = int(0), error(nil) for { select { case <-wsc.Quit: 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 index 16f6a965..f3e4b2ce 100644 --- 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 @@ -10,10 +10,10 @@ import ( "runtime/debug" "time" - "github.com/tendermint/tendermint/alert" - . "github.com/tendermint/tendermint/common" - . "github.com/tendermint/tendermint/rpc/types" - "github.com/tendermint/tendermint/wire" + . "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) { @@ -33,7 +33,7 @@ func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, err } func WriteRPCResponse(w http.ResponseWriter, res RPCResponse) { - buf, n, err := new(bytes.Buffer), int64(0), error(nil) + 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) 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 index 704e22e3..aab9721f 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/log.go @@ -1,7 +1,7 @@ package rpcserver import ( - "github.com/tendermint/log15" + "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/test/client_rpc_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/client_rpc_test.go deleted file mode 100644 index 4b5e6d1e..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/client_rpc_test.go +++ /dev/null @@ -1,129 +0,0 @@ -package rpctest - -import ( - _ "github.com/tendermint/tendermint/config/tendermint_test" - "testing" -) - -// When run with `-test.short` we only run: -// TestHTTPStatus, TestHTTPBroadcast, TestJSONStatus, TestJSONBroadcast, TestWSConnect, TestWSSend - -//-------------------------------------------------------------------------------- -// Test the HTTP client - -func TestHTTPStatus(t *testing.T) { - testStatus(t, "HTTP") -} - -func TestHTTPGenPriv(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testGenPriv(t, "HTTP") -} - -func TestHTTPGetAccount(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testGetAccount(t, "HTTP") -} - -func TestHTTPSignedTx(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testSignedTx(t, "HTTP") -} - -func TestHTTPBroadcastTx(t *testing.T) { - testBroadcastTx(t, "HTTP") -} - -func TestHTTPGetStorage(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testGetStorage(t, "HTTP") -} - -func TestHTTPCallCode(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testCallCode(t, "HTTP") -} - -func TestHTTPCallContract(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testCall(t, "HTTP") -} - -func TestHTTPNameReg(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testNameReg(t, "HTTP") -} - -//-------------------------------------------------------------------------------- -// Test the JSONRPC client - -func TestJSONStatus(t *testing.T) { - testStatus(t, "JSONRPC") -} - -func TestJSONGenPriv(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testGenPriv(t, "JSONRPC") -} - -func TestJSONGetAccount(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testGetAccount(t, "JSONRPC") -} - -func TestJSONSignedTx(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testSignedTx(t, "JSONRPC") -} - -func TestJSONBroadcastTx(t *testing.T) { - testBroadcastTx(t, "JSONRPC") -} - -func TestJSONGetStorage(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testGetStorage(t, "JSONRPC") -} - -func TestJSONCallCode(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testCallCode(t, "JSONRPC") -} - -func TestJSONCallContract(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testCall(t, "JSONRPC") -} - -func TestJSONNameReg(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testNameReg(t, "JSONRPC") -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/client_ws_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/client_ws_test.go deleted file mode 100644 index 99176484..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/client_ws_test.go +++ /dev/null @@ -1,212 +0,0 @@ -package rpctest - -import ( - "fmt" - "testing" - - _ "github.com/tendermint/tendermint/config/tendermint_test" - "github.com/tendermint/tendermint/types" -) - -var wsTyp = "JSONRPC" - -//-------------------------------------------------------------------------------- -// Test the websocket service - -// make a simple connection to the server -func TestWSConnect(t *testing.T) { - con := newWSCon(t) - con.Close() -} - -// receive a new block message -func TestWSNewBlock(t *testing.T) { - con := newWSCon(t) - eid := types.EventStringNewBlock() - subscribe(t, con, eid) - defer func() { - unsubscribe(t, con, eid) - con.Close() - }() - waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error { - fmt.Println("Check:", string(b)) - return nil - }) -} - -// receive a few new block messages in a row, with increasing height -func TestWSBlockchainGrowth(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - con := newWSCon(t) - eid := types.EventStringNewBlock() - subscribe(t, con, eid) - defer func() { - unsubscribe(t, con, eid) - con.Close() - }() - // listen for NewBlock, ensure height increases by 1 - unmarshalValidateBlockchain(t, con, eid) -} - -// send a transaction and validate the events from listening for both sender and receiver -func TestWSSend(t *testing.T) { - toAddr := user[1].Address - amt := int64(100) - - con := newWSCon(t) - eidInput := types.EventStringAccInput(user[0].Address) - eidOutput := types.EventStringAccOutput(toAddr) - subscribe(t, con, eidInput) - subscribe(t, con, eidOutput) - defer func() { - unsubscribe(t, con, eidInput) - unsubscribe(t, con, eidOutput) - con.Close() - }() - waitForEvent(t, con, eidInput, true, func() { - tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt) - broadcastTx(t, wsTyp, tx) - }, unmarshalValidateSend(amt, toAddr)) - waitForEvent(t, con, eidOutput, true, func() {}, unmarshalValidateSend(amt, toAddr)) -} - -// ensure events are only fired once for a given transaction -func TestWSDoubleFire(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - con := newWSCon(t) - eid := types.EventStringAccInput(user[0].Address) - subscribe(t, con, eid) - defer func() { - unsubscribe(t, con, eid) - con.Close() - }() - amt := int64(100) - toAddr := user[1].Address - // broadcast the transaction, wait to hear about it - waitForEvent(t, con, eid, true, func() { - tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt) - broadcastTx(t, wsTyp, tx) - }, func(eid string, b []byte) error { - return nil - }) - // but make sure we don't hear about it twice - waitForEvent(t, con, eid, false, func() { - }, func(eid string, b []byte) error { - return nil - }) -} - -// create a contract, wait for the event, and send it a msg, validate the return -func TestWSCallWait(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - con := newWSCon(t) - eid1 := types.EventStringAccInput(user[0].Address) - subscribe(t, con, eid1) - defer func() { - unsubscribe(t, con, eid1) - con.Close() - }() - amt, gasLim, fee := int64(10000), int64(1000), int64(1000) - code, returnCode, returnVal := simpleContract() - var contractAddr []byte - // wait for the contract to be created - waitForEvent(t, con, eid1, true, func() { - tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee) - receipt := broadcastTx(t, wsTyp, tx) - contractAddr = receipt.ContractAddr - }, unmarshalValidateTx(amt, returnCode)) - - // susbscribe to the new contract - amt = int64(10001) - eid2 := types.EventStringAccOutput(contractAddr) - subscribe(t, con, eid2) - defer func() { - unsubscribe(t, con, eid2) - }() - // get the return value from a call - data := []byte{0x1} - waitForEvent(t, con, eid2, true, func() { - tx := makeDefaultCallTx(t, wsTyp, contractAddr, data, amt, gasLim, fee) - receipt := broadcastTx(t, wsTyp, tx) - contractAddr = receipt.ContractAddr - }, unmarshalValidateTx(amt, returnVal)) -} - -// create a contract and send it a msg without waiting. wait for contract event -// and validate return -func TestWSCallNoWait(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - con := newWSCon(t) - amt, gasLim, fee := int64(10000), int64(1000), int64(1000) - code, _, returnVal := simpleContract() - - tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee) - receipt := broadcastTx(t, wsTyp, tx) - contractAddr := receipt.ContractAddr - - // susbscribe to the new contract - amt = int64(10001) - eid := types.EventStringAccOutput(contractAddr) - subscribe(t, con, eid) - defer func() { - unsubscribe(t, con, eid) - con.Close() - }() - // get the return value from a call - data := []byte{0x1} - waitForEvent(t, con, eid, true, func() { - tx := makeDefaultCallTx(t, wsTyp, contractAddr, data, amt, gasLim, fee) - broadcastTx(t, wsTyp, tx) - }, unmarshalValidateTx(amt, returnVal)) -} - -// create two contracts, one of which calls the other -func TestWSCallCall(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - con := newWSCon(t) - amt, gasLim, fee := int64(10000), int64(1000), int64(1000) - code, _, returnVal := simpleContract() - txid := new([]byte) - - // deploy the two contracts - tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee) - receipt := broadcastTx(t, wsTyp, tx) - contractAddr1 := receipt.ContractAddr - - code, _, _ = simpleCallContract(contractAddr1) - tx = makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee) - receipt = broadcastTx(t, wsTyp, tx) - contractAddr2 := receipt.ContractAddr - - // susbscribe to the new contracts - amt = int64(10001) - eid1 := types.EventStringAccCall(contractAddr1) - subscribe(t, con, eid1) - defer func() { - unsubscribe(t, con, eid1) - con.Close() - }() - // call contract2, which should call contract1, and wait for ev1 - - // let the contract get created first - waitForEvent(t, con, eid1, true, func() { - }, func(eid string, b []byte) error { - return nil - }) - // call it - waitForEvent(t, con, eid1, true, func() { - tx := makeDefaultCallTx(t, wsTyp, contractAddr2, nil, amt, gasLim, fee) - broadcastTx(t, wsTyp, tx) - *txid = types.TxID(chainID, tx) - }, unmarshalValidateCall(user[0].Address, returnVal, txid)) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/config.go deleted file mode 100644 index ef5d5433..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package rpctest - -import ( - cfg "github.com/tendermint/tendermint/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/test/helpers.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/helpers.go deleted file mode 100644 index e49c3f08..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/helpers.go +++ /dev/null @@ -1,282 +0,0 @@ -package rpctest - -import ( - "bytes" - "strconv" - "testing" - - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - nm "github.com/tendermint/tendermint/node" - "github.com/tendermint/tendermint/p2p" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - cclient "github.com/tendermint/tendermint/rpc/core_client" - "github.com/tendermint/tendermint/types" -) - -// global variables for use across all tests -var ( - rpcAddr = "127.0.0.1:36657" // Not 46657 - requestAddr = "http://" + rpcAddr + "/" - websocketAddr = "ws://" + rpcAddr + "/websocket" - - node *nm.Node - - mempoolCount = 0 - - // make keys - user = makeUsers(5) - - chainID string - - clients = map[string]cclient.Client{ - "JSONRPC": cclient.NewClient(requestAddr, "JSONRPC"), - "HTTP": cclient.NewClient(requestAddr, "HTTP"), - } -) - -// deterministic account generation, synced with genesis file in config/tendermint_test/config.go -func makeUsers(n int) []*acm.PrivAccount { - accounts := []*acm.PrivAccount{} - for i := 0; i < n; i++ { - secret := ("mysecret" + strconv.Itoa(i)) - user := acm.GenPrivAccountFromSecret(secret) - accounts = append(accounts, user) - } - return accounts -} - -// create a new node and sleep forever -func newNode(ready chan struct{}) { - // Create & start node - node = nm.NewNode() - l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr")) - node.AddListener(l) - node.Start() - - // Run the RPC server. - node.StartRPC() - ready <- struct{}{} - - // Sleep forever - ch := make(chan struct{}) - <-ch -} - -// initialize config and create new node -func init() { - chainID = config.GetString("chain_id") - - // Save new priv_validator file. - priv := &types.PrivValidator{ - Address: user[0].Address, - PubKey: acm.PubKeyEd25519(user[0].PubKey.(acm.PubKeyEd25519)), - PrivKey: acm.PrivKeyEd25519(user[0].PrivKey.(acm.PrivKeyEd25519)), - } - priv.SetFile(config.GetString("priv_validator_file")) - priv.Save() - - // TODO: change consensus/state.go timeouts to be shorter - - // start a node - ready := make(chan struct{}) - go newNode(ready) - <-ready -} - -//------------------------------------------------------------------------------- -// some default transaction functions - -func makeDefaultSendTx(t *testing.T, typ string, addr []byte, amt int64) *types.SendTx { - nonce := getNonce(t, typ, user[0].Address) - tx := types.NewSendTx() - tx.AddInputWithNonce(user[0].PubKey, amt, nonce+1) - tx.AddOutput(addr, amt) - return tx -} - -func makeDefaultSendTxSigned(t *testing.T, typ string, addr []byte, amt int64) *types.SendTx { - tx := makeDefaultSendTx(t, typ, addr, amt) - tx.SignInput(chainID, 0, user[0]) - return tx -} - -func makeDefaultCallTx(t *testing.T, typ string, addr, code []byte, amt, gasLim, fee int64) *types.CallTx { - nonce := getNonce(t, typ, user[0].Address) - tx := types.NewCallTxWithNonce(user[0].PubKey, addr, code, amt, gasLim, fee, nonce+1) - tx.Sign(chainID, user[0]) - return tx -} - -func makeDefaultNameTx(t *testing.T, typ string, name, value string, amt, fee int64) *types.NameTx { - nonce := getNonce(t, typ, user[0].Address) - tx := types.NewNameTxWithNonce(user[0].PubKey, name, value, amt, fee, nonce+1) - tx.Sign(chainID, user[0]) - return tx -} - -//------------------------------------------------------------------------------- -// rpc call wrappers (fail on err) - -// get an account's nonce -func getNonce(t *testing.T, typ string, addr []byte) int { - client := clients[typ] - ac, err := client.GetAccount(addr) - if err != nil { - t.Fatal(err) - } - if ac.Account == nil { - return 0 - } - return ac.Account.Sequence -} - -// get the account -func getAccount(t *testing.T, typ string, addr []byte) *acm.Account { - client := clients[typ] - ac, err := client.GetAccount(addr) - if err != nil { - t.Fatal(err) - } - return ac.Account -} - -// sign transaction -func signTx(t *testing.T, typ string, tx types.Tx, privAcc *acm.PrivAccount) types.Tx { - client := clients[typ] - signedTx, err := client.SignTx(tx, []*acm.PrivAccount{privAcc}) - if err != nil { - t.Fatal(err) - } - return signedTx.Tx -} - -// broadcast transaction -func broadcastTx(t *testing.T, typ string, tx types.Tx) ctypes.Receipt { - client := clients[typ] - rec, err := client.BroadcastTx(tx) - if err != nil { - t.Fatal(err) - } - mempoolCount += 1 - return rec.Receipt -} - -// dump all storage for an account. currently unused -func dumpStorage(t *testing.T, addr []byte) ctypes.ResultDumpStorage { - client := clients["HTTP"] - resp, err := client.DumpStorage(addr) - if err != nil { - t.Fatal(err) - } - return *resp -} - -func getStorage(t *testing.T, typ string, addr, key []byte) []byte { - client := clients[typ] - resp, err := client.GetStorage(addr, key) - if err != nil { - t.Fatal(err) - } - return resp.Value -} - -func callCode(t *testing.T, client cclient.Client, fromAddress, code, data, expected []byte) { - resp, err := client.CallCode(fromAddress, code, data) - if err != nil { - t.Fatal(err) - } - ret := resp.Return - // NOTE: we don't flip memory when it comes out of RETURN (?!) - if bytes.Compare(ret, LeftPadWord256(expected).Bytes()) != 0 { - t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected) - } -} - -func callContract(t *testing.T, client cclient.Client, fromAddress, toAddress, data, expected []byte) { - resp, err := client.Call(fromAddress, toAddress, data) - if err != nil { - t.Fatal(err) - } - ret := resp.Return - // NOTE: we don't flip memory when it comes out of RETURN (?!) - if bytes.Compare(ret, LeftPadWord256(expected).Bytes()) != 0 { - t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected) - } -} - -// get the namereg entry -func getNameRegEntry(t *testing.T, typ string, name string) *types.NameRegEntry { - client := clients[typ] - entry, err := client.GetName(name) - if err != nil { - t.Fatal(err) - } - return entry.Entry -} - -//-------------------------------------------------------------------------------- -// utility verification function - -func checkTx(t *testing.T, fromAddr []byte, priv *acm.PrivAccount, tx *types.SendTx) { - if bytes.Compare(tx.Inputs[0].Address, fromAddr) != 0 { - t.Fatal("Tx input addresses don't match!") - } - - signBytes := acm.SignBytes(chainID, tx) - in := tx.Inputs[0] //(*types.SendTx).Inputs[0] - - if err := in.ValidateBasic(); err != nil { - t.Fatal(err) - } - // Check signatures - // acc := getAccount(t, byteAddr) - // NOTE: using the acc here instead of the in fails; it is nil. - if !in.PubKey.VerifyBytes(signBytes, in.Signature) { - t.Fatal(types.ErrTxInvalidSignature) - } -} - -// simple contract returns 5 + 6 = 0xb -func simpleContract() ([]byte, []byte, []byte) { - // this is the code we want to run when the contract is called - contractCode := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60, 0x0, 0xf3} - // the is the code we need to return the contractCode when the contract is initialized - lenCode := len(contractCode) - // push code to the stack - //code := append([]byte{byte(0x60 + lenCode - 1)}, RightPadWord256(contractCode).Bytes()...) - code := append([]byte{0x7f}, RightPadWord256(contractCode).Bytes()...) - // store it in memory - code = append(code, []byte{0x60, 0x0, 0x52}...) - // return whats in memory - //code = append(code, []byte{0x60, byte(32 - lenCode), 0x60, byte(lenCode), 0xf3}...) - code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...) - // return init code, contract code, expected return - return code, contractCode, LeftPadBytes([]byte{0xb}, 32) -} - -// simple call contract calls another contract -func simpleCallContract(addr []byte) ([]byte, []byte, []byte) { - gas1, gas2 := byte(0x1), byte(0x1) - value := byte(0x1) - inOff, inSize := byte(0x0), byte(0x0) // no call data - retOff, retSize := byte(0x0), byte(0x20) - // this is the code we want to run (call a contract and return) - contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, 0x60, value, 0x73} - contractCode = append(contractCode, addr...) - contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...) - - // the is the code we need to return; the contractCode when the contract is initialized - // it should copy the code from the input into memory - lenCode := len(contractCode) - memOff := byte(0x0) - inOff = byte(0xc) // length of code before codeContract - length := byte(lenCode) - - code := []byte{0x60, length, 0x60, inOff, 0x60, memOff, 0x37} - // return whats in memory - code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...) - code = append(code, contractCode...) - // return init code, contract code, expected return - return code, contractCode, LeftPadBytes([]byte{0xb}, 32) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/tests.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/tests.go deleted file mode 100644 index e684bbef..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/tests.go +++ /dev/null @@ -1,281 +0,0 @@ -package rpctest - -import ( - "bytes" - "fmt" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" - "testing" -) - -var doNothing = func(eid string, b []byte) error { return nil } - -func testStatus(t *testing.T, typ string) { - client := clients[typ] - resp, err := client.Status() - if err != nil { - t.Fatal(err) - } - if resp.NodeInfo.ChainID != chainID { - t.Fatal(fmt.Errorf("ChainID mismatch: got %s expected %s", - resp.NodeInfo.ChainID, chainID)) - } -} - -func testGenPriv(t *testing.T, typ string) { - client := clients[typ] - privAcc, err := client.GenPrivAccount() - if err != nil { - t.Fatal(err) - } - if len(privAcc.PrivAccount.Address) == 0 { - t.Fatal("Failed to generate an address") - } -} - -func testGetAccount(t *testing.T, typ string) { - acc := getAccount(t, typ, user[0].Address) - if acc == nil { - t.Fatalf("Account was nil") - } - if bytes.Compare(acc.Address, user[0].Address) != 0 { - t.Fatalf("Failed to get correct account. Got %x, expected %x", acc.Address, user[0].Address) - } -} - -func testSignedTx(t *testing.T, typ string) { - amt := int64(100) - toAddr := user[1].Address - testOneSignTx(t, typ, toAddr, amt) - - toAddr = user[2].Address - testOneSignTx(t, typ, toAddr, amt) - - toAddr = user[3].Address - testOneSignTx(t, typ, toAddr, amt) -} - -func testOneSignTx(t *testing.T, typ string, addr []byte, amt int64) { - tx := makeDefaultSendTx(t, typ, addr, amt) - tx2 := signTx(t, typ, tx, user[0]) - tx2hash := types.TxID(chainID, tx2) - tx.SignInput(chainID, 0, user[0]) - txhash := types.TxID(chainID, tx) - if bytes.Compare(txhash, tx2hash) != 0 { - t.Fatal("Got different signatures for signing via rpc vs tx_utils") - } - - tx_ := signTx(t, typ, tx, user[0]) - tx = tx_.(*types.SendTx) - checkTx(t, user[0].Address, user[0], tx) -} - -func testBroadcastTx(t *testing.T, typ string) { - amt := int64(100) - toAddr := user[1].Address - tx := makeDefaultSendTxSigned(t, typ, toAddr, amt) - receipt := broadcastTx(t, typ, tx) - if receipt.CreatesContract > 0 { - t.Fatal("This tx does not create a contract") - } - if len(receipt.TxHash) == 0 { - t.Fatal("Failed to compute tx hash") - } - pool := node.MempoolReactor().Mempool - txs := pool.GetProposalTxs() - if len(txs) != mempoolCount { - t.Fatalf("The mem pool has %d txs. Expected %d", len(txs), mempoolCount) - } - tx2 := txs[mempoolCount-1].(*types.SendTx) - n, err := new(int64), new(error) - buf1, buf2 := new(bytes.Buffer), new(bytes.Buffer) - tx.WriteSignBytes(chainID, buf1, n, err) - tx2.WriteSignBytes(chainID, buf2, n, err) - if bytes.Compare(buf1.Bytes(), buf2.Bytes()) != 0 { - t.Fatal("inconsistent hashes for mempool tx and sent tx") - } -} - -func testGetStorage(t *testing.T, typ string) { - con := newWSCon(t) - eid := types.EventStringNewBlock() - subscribe(t, con, eid) - defer func() { - unsubscribe(t, con, eid) - con.Close() - }() - - amt, gasLim, fee := int64(1100), int64(1000), int64(1000) - code := []byte{0x60, 0x5, 0x60, 0x1, 0x55} - tx := makeDefaultCallTx(t, typ, nil, code, amt, gasLim, fee) - receipt := broadcastTx(t, typ, tx) - if receipt.CreatesContract == 0 { - t.Fatal("This tx creates a contract") - } - if len(receipt.TxHash) == 0 { - t.Fatal("Failed to compute tx hash") - } - contractAddr := receipt.ContractAddr - if len(contractAddr) == 0 { - t.Fatal("Creates contract but resulting address is empty") - } - - // allow it to get mined - waitForEvent(t, con, eid, true, func() {}, doNothing) - mempoolCount = 0 - - v := getStorage(t, typ, contractAddr, []byte{0x1}) - got := LeftPadWord256(v) - expected := LeftPadWord256([]byte{0x5}) - if got.Compare(expected) != 0 { - t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(), expected.Bytes()) - } -} - -func testCallCode(t *testing.T, typ string) { - client := clients[typ] - - // add two integers and return the result - code := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60, 0x0, 0xf3} - data := []byte{} - expected := []byte{0xb} - callCode(t, client, user[0].PubKey.Address(), code, data, expected) - - // pass two ints as calldata, add, and return the result - code = []byte{0x60, 0x0, 0x35, 0x60, 0x20, 0x35, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60, 0x0, 0xf3} - data = append(LeftPadWord256([]byte{0x5}).Bytes(), LeftPadWord256([]byte{0x6}).Bytes()...) - expected = []byte{0xb} - callCode(t, client, user[0].PubKey.Address(), code, data, expected) -} - -func testCall(t *testing.T, typ string) { - con := newWSCon(t) - eid := types.EventStringNewBlock() - subscribe(t, con, eid) - defer func() { - unsubscribe(t, con, eid) - con.Close() - }() - - client := clients[typ] - - // create the contract - amt, gasLim, fee := int64(6969), int64(1000), int64(1000) - code, _, _ := simpleContract() - tx := makeDefaultCallTx(t, typ, nil, code, amt, gasLim, fee) - receipt := broadcastTx(t, typ, tx) - - if receipt.CreatesContract == 0 { - t.Fatal("This tx creates a contract") - } - if len(receipt.TxHash) == 0 { - t.Fatal("Failed to compute tx hash") - } - contractAddr := receipt.ContractAddr - if len(contractAddr) == 0 { - t.Fatal("Creates contract but resulting address is empty") - } - - // allow it to get mined - waitForEvent(t, con, eid, true, func() {}, doNothing) - mempoolCount = 0 - - // run a call through the contract - data := []byte{} - expected := []byte{0xb} - callContract(t, client, user[0].PubKey.Address(), contractAddr, data, expected) -} - -func testNameReg(t *testing.T, typ string) { - client := clients[typ] - con := newWSCon(t) - - types.MinNameRegistrationPeriod = 1 - - // register a new name, check if its there - // since entries ought to be unique and these run against different clients, we append the typ - name := "ye_old_domain_name_" + typ - data := "if not now, when" - fee := int64(1000) - numDesiredBlocks := int64(2) - amt := fee + numDesiredBlocks*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data) - - eid := types.EventStringNameReg(name) - subscribe(t, con, eid) - - tx := makeDefaultNameTx(t, typ, name, data, amt, fee) - broadcastTx(t, typ, tx) - // verify the name by both using the event and by checking get_name - waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error { - // TODO: unmarshal the response - tx, err := unmarshalResponseNameReg(b) - if err != nil { - return err - } - if tx.Name != name { - t.Fatal(fmt.Sprintf("Err on received event tx.Name: Got %s, expected %s", tx.Name, name)) - } - if tx.Data != data { - t.Fatal(fmt.Sprintf("Err on received event tx.Data: Got %s, expected %s", tx.Data, data)) - } - return nil - }) - mempoolCount = 0 - entry := getNameRegEntry(t, typ, name) - if entry.Data != data { - t.Fatal(fmt.Sprintf("Err on entry.Data: Got %s, expected %s", entry.Data, data)) - } - if bytes.Compare(entry.Owner, user[0].Address) != 0 { - t.Fatal(fmt.Sprintf("Err on entry.Owner: Got %s, expected %s", entry.Owner, user[0].Address)) - } - - unsubscribe(t, con, eid) - - // for the rest we just use new block event - // since we already tested the namereg event - eid = types.EventStringNewBlock() - subscribe(t, con, eid) - defer func() { - unsubscribe(t, con, eid) - con.Close() - }() - - // update the data as the owner, make sure still there - numDesiredBlocks = int64(2) - data = "these are amongst the things I wish to bestow upon the youth of generations come: a safe supply of honey, and a better money. For what else shall they need" - amt = fee + numDesiredBlocks*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data) - tx = makeDefaultNameTx(t, typ, name, data, amt, fee) - broadcastTx(t, typ, tx) - // commit block - waitForEvent(t, con, eid, true, func() {}, doNothing) - mempoolCount = 0 - entry = getNameRegEntry(t, typ, name) - if entry.Data != data { - t.Fatal(fmt.Sprintf("Err on entry.Data: Got %s, expected %s", entry.Data, data)) - } - - // try to update as non owner, should fail - nonce := getNonce(t, typ, user[1].Address) - data2 := "this is not my beautiful house" - tx = types.NewNameTxWithNonce(user[1].PubKey, name, data2, amt, fee, nonce+1) - tx.Sign(chainID, user[1]) - _, err := client.BroadcastTx(tx) - if err == nil { - t.Fatal("Expected error on NameTx") - } - - // commit block - waitForEvent(t, con, eid, true, func() {}, doNothing) - - // now the entry should be expired, so we can update as non owner - _, err = client.BroadcastTx(tx) - waitForEvent(t, con, eid, true, func() {}, doNothing) - mempoolCount = 0 - entry = getNameRegEntry(t, typ, name) - if entry.Data != data2 { - t.Fatal(fmt.Sprintf("Error on entry.Data: Got %s, expected %s", entry.Data, data2)) - } - if bytes.Compare(entry.Owner, user[1].Address) != 0 { - t.Fatal(fmt.Sprintf("Err on entry.Owner: Got %s, expected %s", entry.Owner, user[1].Address)) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/ws_helpers.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/ws_helpers.go deleted file mode 100644 index b86987bb..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/test/ws_helpers.go +++ /dev/null @@ -1,271 +0,0 @@ -package rpctest - -import ( - "bytes" - "fmt" - "net/http" - "testing" - "time" - - "github.com/gorilla/websocket" - _ "github.com/tendermint/tendermint/config/tendermint_test" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/rpc/types" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" -) - -//-------------------------------------------------------------------------------- -// Utilities for testing the websocket service - -// create a new connection -func newWSCon(t *testing.T) *websocket.Conn { - dialer := websocket.DefaultDialer - rHeader := http.Header{} - con, r, err := dialer.Dial(websocketAddr, rHeader) - fmt.Println("response", r) - if err != nil { - t.Fatal(err) - } - return con -} - -// subscribe to an event -func subscribe(t *testing.T, con *websocket.Conn, eventid string) { - err := con.WriteJSON(rpctypes.RPCRequest{ - JSONRPC: "2.0", - ID: "", - Method: "subscribe", - Params: []interface{}{eventid}, - }) - if err != nil { - t.Fatal(err) - } -} - -// unsubscribe from an event -func unsubscribe(t *testing.T, con *websocket.Conn, eventid string) { - err := con.WriteJSON(rpctypes.RPCRequest{ - JSONRPC: "2.0", - ID: "", - Method: "unsubscribe", - Params: []interface{}{eventid}, - }) - if err != nil { - t.Fatal(err) - } -} - -// wait for an event; do things that might trigger events, and check them when they are received -// the check function takes an event id and the byte slice read off the ws -func waitForEvent(t *testing.T, con *websocket.Conn, eventid string, dieOnTimeout bool, f func(), check func(string, []byte) error) { - // go routine to wait for webscoket msg - goodCh := make(chan []byte) - errCh := make(chan error) - quitCh := make(chan struct{}) - defer close(quitCh) - - // Read message - go func() { - for { - _, p, err := con.ReadMessage() - if err != nil { - errCh <- err - break - } else { - // if the event id isnt what we're waiting on - // ignore it - var response ctypes.Response - var err error - wire.ReadJSON(&response, p, &err) - if err != nil { - errCh <- err - break - } - event, ok := response.Result.(*ctypes.ResultEvent) - if ok && event.Event == eventid { - goodCh <- p - break - } - } - } - }() - - // do stuff (transactions) - f() - - // wait for an event or timeout - timeout := time.NewTimer(10 * time.Second) - select { - case <-timeout.C: - if dieOnTimeout { - con.Close() - t.Fatalf("%s event was not received in time", eventid) - } - // else that's great, we didn't hear the event - // and we shouldn't have - case p := <-goodCh: - if dieOnTimeout { - // message was received and expected - // run the check - err := check(eventid, p) - if err != nil { - t.Fatal(err) - panic(err) // Show the stack trace. - } - } else { - con.Close() - t.Fatalf("%s event was not expected", eventid) - } - case err := <-errCh: - t.Fatal(err) - panic(err) // Show the stack trace. - } -} - -//-------------------------------------------------------------------------------- - -func unmarshalResponseNewBlock(b []byte) (*types.Block, error) { - // unmarshall and assert somethings - var response ctypes.Response - var err error - wire.ReadJSON(&response, b, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - block := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataNewBlock).Block - return block, nil -} - -func unmarshalResponseNameReg(b []byte) (*types.NameTx, error) { - // unmarshall and assert somethings - var response ctypes.Response - var err error - wire.ReadJSON(&response, b, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - tx := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataTx).Tx.(*types.NameTx) - return tx, nil -} - -func unmarshalValidateBlockchain(t *testing.T, con *websocket.Conn, eid string) { - var initBlockN int - for i := 0; i < 2; i++ { - waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error { - block, err := unmarshalResponseNewBlock(b) - if err != nil { - return err - } - if i == 0 { - initBlockN = block.Header.Height - } else { - if block.Header.Height != initBlockN+i { - return fmt.Errorf("Expected block %d, got block %d", i, block.Header.Height) - } - } - - return nil - }) - } -} - -func unmarshalValidateSend(amt int64, toAddr []byte) func(string, []byte) error { - return func(eid string, b []byte) error { - // unmarshal and assert correctness - var response ctypes.Response - var err error - wire.ReadJSON(&response, b, &err) - if err != nil { - return err - } - if response.Error != "" { - return fmt.Errorf(response.Error) - } - if eid != response.Result.(*ctypes.ResultEvent).Event { - return fmt.Errorf("Eventid is not correct. Got %s, expected %s", response.Result.(*ctypes.ResultEvent).Event, eid) - } - tx := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataTx).Tx.(*types.SendTx) - if !bytes.Equal(tx.Inputs[0].Address, user[0].Address) { - return fmt.Errorf("Senders do not match up! Got %x, expected %x", tx.Inputs[0].Address, user[0].Address) - } - if tx.Inputs[0].Amount != amt { - return fmt.Errorf("Amt does not match up! Got %d, expected %d", tx.Inputs[0].Amount, amt) - } - if !bytes.Equal(tx.Outputs[0].Address, toAddr) { - return fmt.Errorf("Receivers do not match up! Got %x, expected %x", tx.Outputs[0].Address, user[0].Address) - } - return nil - } -} - -func unmarshalValidateTx(amt int64, returnCode []byte) func(string, []byte) error { - return func(eid string, b []byte) error { - // unmarshall and assert somethings - var response ctypes.Response - var err error - wire.ReadJSON(&response, b, &err) - if err != nil { - return err - } - if response.Error != "" { - return fmt.Errorf(response.Error) - } - var data = response.Result.(*ctypes.ResultEvent).Data.(types.EventDataTx) - if data.Exception != "" { - return fmt.Errorf(data.Exception) - } - tx := data.Tx.(*types.CallTx) - if !bytes.Equal(tx.Input.Address, user[0].Address) { - return fmt.Errorf("Senders do not match up! Got %x, expected %x", - tx.Input.Address, user[0].Address) - } - if tx.Input.Amount != amt { - return fmt.Errorf("Amt does not match up! Got %d, expected %d", - tx.Input.Amount, amt) - } - ret := data.Return - if !bytes.Equal(ret, returnCode) { - return fmt.Errorf("Tx did not return correctly. Got %x, expected %x", ret, returnCode) - } - return nil - } -} - -func unmarshalValidateCall(origin, returnCode []byte, txid *[]byte) func(string, []byte) error { - return func(eid string, b []byte) error { - // unmarshall and assert somethings - var response ctypes.Response - var err error - wire.ReadJSON(&response, b, &err) - if err != nil { - return err - } - if response.Error != "" { - return fmt.Errorf(response.Error) - } - var data = response.Result.(*ctypes.ResultEvent).Data.(types.EventDataCall) - if data.Exception != "" { - return fmt.Errorf(data.Exception) - } - if !bytes.Equal(data.Origin, origin) { - return fmt.Errorf("Origin does not match up! Got %x, expected %x", - data.Origin, origin) - } - ret := data.Return - if !bytes.Equal(ret, returnCode) { - return fmt.Errorf("Call did not return correctly. Got %x, expected %x", ret, returnCode) - } - if !bytes.Equal(data.TxID, *txid) { - return fmt.Errorf("TxIDs do not match up! Got %x, expected %x", - data.TxID, *txid) - } - return nil - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/block_cache.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/block_cache.go deleted file mode 100644 index 0bbab6fa..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/block_cache.go +++ /dev/null @@ -1,293 +0,0 @@ -package state - -import ( - "bytes" - "sort" - - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - dbm "github.com/tendermint/tendermint/db" - "github.com/tendermint/tendermint/merkle" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" -) - -func makeStorage(db dbm.DB, root []byte) merkle.Tree { - storage := merkle.NewIAVLTree( - wire.BasicCodec, - wire.BasicCodec, - 1024, - db, - ) - storage.Load(root) - return storage -} - -// The blockcache helps prevent unnecessary IAVLTree updates and garbage generation. -type BlockCache struct { - db dbm.DB - backend *State - accounts map[string]accountInfo - storages map[Tuple256]storageInfo - names map[string]nameInfo -} - -func NewBlockCache(backend *State) *BlockCache { - return &BlockCache{ - db: backend.DB, - backend: backend, - accounts: make(map[string]accountInfo), - storages: make(map[Tuple256]storageInfo), - names: make(map[string]nameInfo), - } -} - -func (cache *BlockCache) State() *State { - return cache.backend -} - -//------------------------------------- -// BlockCache.account - -func (cache *BlockCache) GetAccount(addr []byte) *acm.Account { - acc, _, removed, _ := cache.accounts[string(addr)].unpack() - if removed { - return nil - } else if acc != nil { - return acc - } else { - acc = cache.backend.GetAccount(addr) - cache.accounts[string(addr)] = accountInfo{acc, nil, false, false} - return acc - } -} - -func (cache *BlockCache) UpdateAccount(acc *acm.Account) { - addr := acc.Address - _, storage, removed, _ := cache.accounts[string(addr)].unpack() - if removed { - PanicSanity("UpdateAccount on a removed account") - } - cache.accounts[string(addr)] = accountInfo{acc, storage, false, true} -} - -func (cache *BlockCache) RemoveAccount(addr []byte) { - _, _, removed, _ := cache.accounts[string(addr)].unpack() - if removed { - PanicSanity("RemoveAccount on a removed account") - } - cache.accounts[string(addr)] = accountInfo{nil, nil, true, false} -} - -// BlockCache.account -//------------------------------------- -// BlockCache.storage - -func (cache *BlockCache) GetStorage(addr Word256, key Word256) (value Word256) { - // Check cache - info, ok := cache.storages[Tuple256{addr, key}] - if ok { - return info.value - } - - // Get or load storage - acc, storage, removed, dirty := cache.accounts[string(addr.Postfix(20))].unpack() - if removed { - PanicSanity("GetStorage() on removed account") - } - if acc != nil && storage == nil { - storage = makeStorage(cache.db, acc.StorageRoot) - cache.accounts[string(addr.Postfix(20))] = accountInfo{acc, storage, false, dirty} - } else if acc == nil { - return Zero256 - } - - // Load and set cache - _, val_ := storage.Get(key.Bytes()) - value = Zero256 - if val_ != nil { - value = LeftPadWord256(val_.([]byte)) - } - cache.storages[Tuple256{addr, key}] = storageInfo{value, false} - return value -} - -// NOTE: Set value to zero to removed from the trie. -func (cache *BlockCache) SetStorage(addr Word256, key Word256, value Word256) { - _, _, removed, _ := cache.accounts[string(addr.Postfix(20))].unpack() - if removed { - PanicSanity("SetStorage() on a removed account") - } - cache.storages[Tuple256{addr, key}] = storageInfo{value, true} -} - -// BlockCache.storage -//------------------------------------- -// BlockCache.names - -func (cache *BlockCache) GetNameRegEntry(name string) *types.NameRegEntry { - entry, removed, _ := cache.names[name].unpack() - if removed { - return nil - } else if entry != nil { - return entry - } else { - entry = cache.backend.GetNameRegEntry(name) - cache.names[name] = nameInfo{entry, false, false} - return entry - } -} - -func (cache *BlockCache) UpdateNameRegEntry(entry *types.NameRegEntry) { - name := entry.Name - cache.names[name] = nameInfo{entry, false, true} -} - -func (cache *BlockCache) RemoveNameRegEntry(name string) { - _, removed, _ := cache.names[name].unpack() - if removed { - PanicSanity("RemoveNameRegEntry on a removed entry") - } - cache.names[name] = nameInfo{nil, true, false} -} - -// BlockCache.names -//------------------------------------- - -// CONTRACT the updates are in deterministic order. -func (cache *BlockCache) Sync() { - - // Determine order for storage updates - // The address comes first so it'll be grouped. - storageKeys := make([]Tuple256, 0, len(cache.storages)) - for keyTuple := range cache.storages { - storageKeys = append(storageKeys, keyTuple) - } - Tuple256Slice(storageKeys).Sort() - - // Update storage for all account/key. - // Later we'll iterate over all the users and save storage + update storage root. - var ( - curAddr Word256 - curAcc *acm.Account - curAccRemoved bool - curStorage merkle.Tree - ) - for _, storageKey := range storageKeys { - addr, key := Tuple256Split(storageKey) - if addr != curAddr || curAcc == nil { - acc, storage, removed, _ := cache.accounts[string(addr.Postfix(20))].unpack() - if !removed && storage == nil { - storage = makeStorage(cache.db, acc.StorageRoot) - } - curAddr = addr - curAcc = acc - curAccRemoved = removed - curStorage = storage - } - if curAccRemoved { - continue - } - value, dirty := cache.storages[storageKey].unpack() - if !dirty { - continue - } - if value.IsZero() { - curStorage.Remove(key.Bytes()) - } else { - curStorage.Set(key.Bytes(), value.Bytes()) - cache.accounts[string(addr.Postfix(20))] = accountInfo{curAcc, curStorage, false, true} - } - } - - // Determine order for accounts - addrStrs := []string{} - for addrStr := range cache.accounts { - addrStrs = append(addrStrs, addrStr) - } - sort.Strings(addrStrs) - - // Update or delete accounts. - for _, addrStr := range addrStrs { - acc, storage, removed, dirty := cache.accounts[addrStr].unpack() - if removed { - removed := cache.backend.RemoveAccount([]byte(addrStr)) - if !removed { - PanicCrisis(Fmt("Could not remove account to be removed: %X", acc.Address)) - } - } else { - if acc == nil { - continue - } - if storage != nil { - newStorageRoot := storage.Save() - if !bytes.Equal(newStorageRoot, acc.StorageRoot) { - acc.StorageRoot = newStorageRoot - dirty = true - } - } - if dirty { - cache.backend.UpdateAccount(acc) - } - } - } - - // Determine order for names - // note names may be of any length less than some limit - nameStrs := []string{} - for nameStr := range cache.names { - nameStrs = append(nameStrs, nameStr) - } - sort.Strings(nameStrs) - - // Update or delete names. - for _, nameStr := range nameStrs { - entry, removed, dirty := cache.names[nameStr].unpack() - if removed { - removed := cache.backend.RemoveNameRegEntry(nameStr) - if !removed { - PanicCrisis(Fmt("Could not remove namereg entry to be removed: %s", nameStr)) - } - } else { - if entry == nil { - continue - } - if dirty { - cache.backend.UpdateNameRegEntry(entry) - } - } - } - -} - -//----------------------------------------------------------------------------- - -type accountInfo struct { - account *acm.Account - storage merkle.Tree - removed bool - dirty bool -} - -func (accInfo accountInfo) unpack() (*acm.Account, merkle.Tree, bool, bool) { - return accInfo.account, accInfo.storage, accInfo.removed, accInfo.dirty -} - -type storageInfo struct { - value Word256 - dirty bool -} - -func (stjInfo storageInfo) unpack() (Word256, bool) { - return stjInfo.value, stjInfo.dirty -} - -type nameInfo struct { - name *types.NameRegEntry - removed bool - dirty bool -} - -func (nInfo nameInfo) unpack() (*types.NameRegEntry, bool, bool) { - return nInfo.name, nInfo.removed, nInfo.dirty -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/common.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/common.go deleted file mode 100644 index 0adad0aa..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/common.go +++ /dev/null @@ -1,18 +0,0 @@ -package state - -import ( - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/vm" -) - -type AccountGetter interface { - GetAccount(addr []byte) *acm.Account -} - -type VMAccountState interface { - GetAccount(addr Word256) *vm.Account - UpdateAccount(acc *vm.Account) - RemoveAccount(acc *vm.Account) - CreateAccount(creator *vm.Account) *vm.Account -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go index bdb858ab..f323c19b 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go @@ -5,989 +5,177 @@ import ( "errors" "fmt" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - ptypes "github.com/tendermint/tendermint/permission/types" // for GlobalPermissionAddress ... - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/vm" + . "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" ) -// NOTE: If an error occurs during block execution, state will be left -// at an invalid state. Copy the state before calling ExecBlock! -func ExecBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeader) error { - err := execBlock(s, block, blockPartsHeader) - if err != nil { - return err - } - // State.Hash should match block.StateHash - stateHash := s.Hash() - if !bytes.Equal(stateHash, block.StateHash) { - return errors.New(Fmt("Invalid state hash. Expected %X, got %X", - stateHash, block.StateHash)) - } - return nil -} +// 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 { -// executes transactions of a block, does not check block.StateHash -// NOTE: If an error occurs during block execution, state will be left -// at an invalid state. Copy the state before calling execBlock! -func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeader) error { - // Basic block validation. - err := block.ValidateBasic(s.ChainID, s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime) + // Validate the block. + err := s.validateBlock(block) 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.LastBondedValidators.Size() { - return errors.New(Fmt("Invalid block validation size. Expected %v, got %v", - s.LastBondedValidators.Size(), len(block.LastValidation.Precommits))) - } - err := s.LastBondedValidators.VerifyValidation( - s.ChainID, s.LastBlockHash, s.LastBlockParts, block.Height-1, block.LastValidation) - if err != nil { - return err - } - } - - // Update Validator.LastCommitHeight as necessary. - for i, precommit := range block.LastValidation.Precommits { - if precommit == nil { - continue - } - _, val := s.LastBondedValidators.GetByIndex(i) - if val == nil { - PanicCrisis(Fmt("Failed to fetch validator at index %v", i)) - } - if _, val_ := s.BondedValidators.GetByAddress(val.Address); val_ != nil { - val_.LastCommitHeight = block.Height - 1 - updated := s.BondedValidators.Update(val_) - if !updated { - PanicCrisis("Failed to update bonded validator LastCommitHeight") - } - } else if _, val_ := s.UnbondingValidators.GetByAddress(val.Address); val_ != nil { - val_.LastCommitHeight = block.Height - 1 - updated := s.UnbondingValidators.Update(val_) - if !updated { - PanicCrisis("Failed to update unbonding validator LastCommitHeight") - } - } else { - PanicCrisis("Could not find validator") - } - } - - // Remember LastBondedValidators - s.LastBondedValidators = s.BondedValidators.Copy() - - // Create BlockCache to cache changes to state. - blockCache := NewBlockCache(s) - - // Execute each tx - for _, tx := range block.Data.Txs { - err := ExecTx(blockCache, tx, true, s.evc) - if err != nil { - return InvalidTxError{tx, err} - } - } - - // Now sync the BlockCache to the backend. - blockCache.Sync() + // 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() - // If any unbonding periods are over, - // reward account with bonded coins. - toRelease := []*types.Validator{} - s.UnbondingValidators.Iterate(func(index int, val *types.Validator) bool { - if val.UnbondHeight+unbondingPeriodBlocks < block.Height { - toRelease = append(toRelease, val) - } - return false - }) - for _, val := range toRelease { - s.releaseValidator(val) + // First, rollback. + if err != nil { + proxyAppCtx.RollbackSync() + return err } - // If any validators haven't signed in a while, - // unbond them, they have timed out. - toTimeout := []*types.Validator{} - s.BondedValidators.Iterate(func(index int, val *types.Validator) bool { - lastActivityHeight := MaxInt(val.BondHeight, val.LastCommitHeight) - if lastActivityHeight+validatorTimeoutBlocks < block.Height { - log.Notice("Validator timeout", "validator", val, "height", block.Height) - toTimeout = append(toTimeout, val) - } - return false - }) - for _, val := range toTimeout { - s.unbondValidator(val) + // Execute, or rollback. (Does not commit) + err = s.execBlockOnProxyApp(proxyAppCtx, block) + if err != nil { + proxyAppCtx.RollbackSync() + return err } - // Increment validator AccumPowers - s.BondedValidators.IncrementAccum(1) + // 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 } -// The accounts from the TxInputs must either already have -// acm.PubKey.(type) != nil, (it must be known), -// or it must be specified in the TxInput. If redeclared, -// the TxInput is modified and input.PubKey set to nil. -func getInputs(state AccountGetter, ins []*types.TxInput) (map[string]*acm.Account, error) { - accounts := map[string]*acm.Account{} - for _, in := range ins { - // Account shouldn't be duplicated - if _, ok := accounts[string(in.Address)]; ok { - return nil, types.ErrTxDuplicateAddress - } - acc := state.GetAccount(in.Address) - if acc == nil { - return nil, types.ErrTxInvalidAddress - } - // PubKey should be present in either "account" or "in" - if err := checkInputPubKey(acc, in); err != nil { - return nil, err - } - accounts[string(in.Address)] = acc - } - return accounts, nil +// Commits block on proxyAppCtx. +func (s *State) Commit(proxyAppCtx proxy.AppContext) error { + err := proxyAppCtx.CommitSync() + return err } -func getOrMakeOutputs(state AccountGetter, accounts map[string]*acm.Account, outs []*types.TxOutput) (map[string]*acm.Account, error) { - if accounts == nil { - accounts = make(map[string]*acm.Account) - } - - // we should err if an account is being created but the inputs don't have permission - var checkedCreatePerms bool - for _, out := range outs { - // Account shouldn't be duplicated - if _, ok := accounts[string(out.Address)]; ok { - return nil, types.ErrTxDuplicateAddress - } - acc := state.GetAccount(out.Address) - // output account may be nil (new) - if acc == nil { - if !checkedCreatePerms { - if !hasCreateAccountPermission(state, accounts) { - return nil, fmt.Errorf("At least one input does not have permission to create accounts") +// 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} } - checkedCreatePerms = true } - acc = &acm.Account{ - Address: out.Address, - PubKey: nil, - Sequence: 0, - Balance: 0, - Permissions: ptypes.ZeroAccountPermissions, - } - } - accounts[string(out.Address)] = acc - } - return accounts, nil -} - -func checkInputPubKey(acc *acm.Account, in *types.TxInput) error { - if acc.PubKey == nil { - if in.PubKey == nil { - return types.ErrTxUnknownPubKey + case tmsp.ResponseEvent: + s.evc.FireEvent(types.EventStringApp(), types.EventDataApp{res.Key, res.Data}) } - if !bytes.Equal(in.PubKey.Address(), acc.Address) { - return types.ErrTxInvalidPubKey - } - acc.PubKey = in.PubKey - } else { - in.PubKey = nil } - return nil -} - -func validateInputs(accounts map[string]*acm.Account, signBytes []byte, ins []*types.TxInput) (total int64, err error) { - for _, in := range ins { - acc := accounts[string(in.Address)] - if acc == nil { - PanicSanity("validateInputs() expects account in accounts") - } - err = validateInput(acc, signBytes, in) - if err != nil { - return + proxyAppCtx.SetResponseCallback(proxyCb) + for _, tx := range block.Data.Txs { + proxyAppCtx.AppendTxAsync(tx) + if err := proxyAppCtx.Error(); err != nil { + return err } - // Good. Add amount to total - total += in.Amount } - return total, nil -} - -func validateInput(acc *acm.Account, signBytes []byte, in *types.TxInput) (err error) { - // Check TxInput basic - if err := in.ValidateBasic(); err != nil { + hash, err := proxyAppCtx.GetHashSync() + if err != nil { + log.Warn("Error computing proxyAppCtx hash", "error", err) return err } - // Check signatures - if !acc.PubKey.VerifyBytes(signBytes, in.Signature) { - return types.ErrTxInvalidSignature - } - // Check sequences - if acc.Sequence+1 != in.Sequence { - return types.ErrTxInvalidSequence{ - Got: in.Sequence, - Expected: acc.Sequence + 1, - } - } - // Check amount - if acc.Balance < in.Amount { - return types.ErrTxInsufficientFunds + if invalidTxErr != nil { + log.Warn("Invalid transaction in block") + return invalidTxErr } - return nil -} -func validateOutputs(outs []*types.TxOutput) (total int64, err error) { - for _, out := range outs { - // Check TxOutput basic - if err := out.ValidateBasic(); err != nil { - return 0, err - } - // Good. Add amount to total - total += out.Amount + // 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 total, nil -} -func adjustByInputs(accounts map[string]*acm.Account, ins []*types.TxInput) { - for _, in := range ins { - acc := accounts[string(in.Address)] - if acc == nil { - PanicSanity("adjustByInputs() expects account in accounts") - } - if acc.Balance < in.Amount { - PanicSanity("adjustByInputs() expects sufficient funds") - } - acc.Balance -= in.Amount - acc.Sequence += 1 - } + return nil } -func adjustByOutputs(accounts map[string]*acm.Account, outs []*types.TxOutput) { - for _, out := range outs { - acc := accounts[string(out.Address)] - if acc == nil { - PanicSanity("adjustByOutputs() expects account in accounts") - } - acc.Balance += out.Amount +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 } -} - -// If the tx is invalid, an error will be returned. -// Unlike ExecBlock(), state will not be altered. -func ExecTx(blockCache *BlockCache, tx types.Tx, runCall bool, evc events.Fireable) (err error) { - - // TODO: do something with fees - fees := int64(0) - _s := blockCache.State() // hack to access validators and block height - - // Exec tx - switch tx := tx.(type) { - case *types.SendTx: - accounts, err := getInputs(blockCache, tx.Inputs) - if err != nil { - return err - } - - // ensure all inputs have send permissions - if !hasSendPermission(blockCache, accounts) { - return fmt.Errorf("At least one input lacks permission for SendTx") - } - - // add outputs to accounts map - // if any outputs don't exist, all inputs must have CreateAccount perm - accounts, err = getOrMakeOutputs(blockCache, accounts, tx.Outputs) - if err != nil { - return err - } - - signBytes := acm.SignBytes(_s.ChainID, tx) - inTotal, err := validateInputs(accounts, signBytes, tx.Inputs) - if err != nil { - return err - } - outTotal, err := validateOutputs(tx.Outputs) - if err != nil { - return err - } - if outTotal > inTotal { - return types.ErrTxInsufficientFunds - } - fee := inTotal - outTotal - fees += fee - - // Good! Adjust accounts - adjustByInputs(accounts, tx.Inputs) - adjustByOutputs(accounts, tx.Outputs) - for _, acc := range accounts { - blockCache.UpdateAccount(acc) - } - - // if the evc is nil, nothing will happen - if evc != nil { - for _, i := range tx.Inputs { - evc.FireEvent(types.EventStringAccInput(i.Address), types.EventDataTx{tx, nil, ""}) - } - - for _, o := range tx.Outputs { - evc.FireEvent(types.EventStringAccOutput(o.Address), types.EventDataTx{tx, nil, ""}) - } - } - return nil - - case *types.CallTx: - var inAcc, outAcc *acm.Account - - // Validate input - inAcc = blockCache.GetAccount(tx.Input.Address) - if inAcc == nil { - log.Info(Fmt("Can't find in account %X", tx.Input.Address)) - return types.ErrTxInvalidAddress - } - - createContract := len(tx.Address) == 0 - if createContract { - if !hasCreateContractPermission(blockCache, inAcc) { - return fmt.Errorf("Account %X does not have CreateContract permission", tx.Input.Address) - } - } else { - if !hasCallPermission(blockCache, inAcc) { - return fmt.Errorf("Account %X does not have Call permission", tx.Input.Address) - } - } - - // pubKey should be present in either "inAcc" or "tx.Input" - if err := checkInputPubKey(inAcc, tx.Input); err != nil { - log.Info(Fmt("Can't find pubkey for %X", tx.Input.Address)) - return err - } - signBytes := acm.SignBytes(_s.ChainID, tx) - err := validateInput(inAcc, signBytes, tx.Input) - if err != nil { - log.Info(Fmt("validateInput failed on %X: %v", tx.Input.Address, err)) - return err - } - if tx.Input.Amount < tx.Fee { - log.Info(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address)) - return types.ErrTxInsufficientFunds - } - - if !createContract { - // Validate output - if len(tx.Address) != 20 { - log.Info(Fmt("Destination address is not 20 bytes %X", tx.Address)) - return types.ErrTxInvalidAddress - } - // check if its a native contract - if vm.RegisteredNativeContract(LeftPadWord256(tx.Address)) { - return fmt.Errorf("NativeContracts can not be called using CallTx. Use a contract or the appropriate tx type (eg. PermissionsTx, NameTx)") - } - - // Output account may be nil if we are still in mempool and contract was created in same block as this tx - // but that's fine, because the account will be created properly when the create tx runs in the block - // and then this won't return nil. otherwise, we take their fee - outAcc = blockCache.GetAccount(tx.Address) - } - - log.Info(Fmt("Out account: %v", outAcc)) - - // Good! - value := tx.Input.Amount - tx.Fee - inAcc.Sequence += 1 - inAcc.Balance -= tx.Fee - blockCache.UpdateAccount(inAcc) - - // The logic in runCall MUST NOT return. - if runCall { - - // VM call variables - var ( - gas int64 = tx.GasLimit - err error = nil - caller *vm.Account = toVMAccount(inAcc) - callee *vm.Account = nil // initialized below - code []byte = nil - ret []byte = nil - txCache = NewTxCache(blockCache) - params = vm.Params{ - BlockHeight: int64(_s.LastBlockHeight), - BlockHash: LeftPadWord256(_s.LastBlockHash), - BlockTime: _s.LastBlockTime.Unix(), - GasLimit: _s.GetGasLimit(), - } - ) - - if !createContract && (outAcc == nil || len(outAcc.Code) == 0) { - // if you call an account that doesn't exist - // or an account with no code then we take fees (sorry pal) - // NOTE: it's fine to create a contract and call it within one - // block (nonce will prevent re-ordering of those txs) - // but to create with one contract and call with another - // you have to wait a block to avoid a re-ordering attack - // that will take your fees - if outAcc == nil { - log.Info(Fmt("%X tries to call %X but it does not exist.", - inAcc.Address, tx.Address)) - } else { - log.Info(Fmt("%X tries to call %X but code is blank.", - inAcc.Address, tx.Address)) - } - err = types.ErrTxInvalidAddress - goto CALL_COMPLETE - } - - // get or create callee - if createContract { - // We already checked for permission - callee = txCache.CreateAccount(caller) - log.Info(Fmt("Created new contract %X", callee.Address)) - code = tx.Data - } else { - callee = toVMAccount(outAcc) - log.Info(Fmt("Calling contract %X with code %X", callee.Address, callee.Code)) - code = callee.Code - } - log.Info(Fmt("Code for this contract: %X", code)) - - // Run VM call and sync txCache to blockCache. - { // Capture scope for goto. - // Write caller/callee to txCache. - txCache.UpdateAccount(caller) - txCache.UpdateAccount(callee) - vmach := vm.NewVM(txCache, params, caller.Address, types.TxID(_s.ChainID, tx)) - vmach.SetFireable(evc) - // NOTE: Call() transfers the value from caller to callee iff call succeeds. - ret, err = vmach.Call(caller, callee, code, tx.Data, value, &gas) - if err != nil { - // Failure. Charge the gas fee. The 'value' was otherwise not transferred. - log.Info(Fmt("Error on execution: %v", err)) - goto CALL_COMPLETE - } - - log.Info("Successful execution") - if createContract { - callee.Code = ret - } - txCache.Sync() - } - - CALL_COMPLETE: // err may or may not be nil. - - // Create a receipt from the ret and whether errored. - log.Notice("VM call complete", "caller", caller, "callee", callee, "return", ret, "err", err) - - // Fire Events for sender and receiver - // a separate event will be fired from vm for each additional call - if evc != nil { - exception := "" - if err != nil { - exception = err.Error() - } - evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventDataTx{tx, ret, exception}) - evc.FireEvent(types.EventStringAccOutput(tx.Address), types.EventDataTx{tx, ret, exception}) - } - } else { - // The mempool does not call txs until - // the proposer determines the order of txs. - // So mempool will skip the actual .Call(), - // and only deduct from the caller's balance. - inAcc.Balance -= value - if createContract { - inAcc.Sequence += 1 - } - blockCache.UpdateAccount(inAcc) - } - - return nil - - case *types.NameTx: - var inAcc *acm.Account - - // Validate input - inAcc = blockCache.GetAccount(tx.Input.Address) - if inAcc == nil { - log.Info(Fmt("Can't find in account %X", tx.Input.Address)) - return types.ErrTxInvalidAddress - } - // check permission - if !hasNamePermission(blockCache, inAcc) { - return fmt.Errorf("Account %X does not have Name permission", tx.Input.Address) - } - // pubKey should be present in either "inAcc" or "tx.Input" - if err := checkInputPubKey(inAcc, tx.Input); err != nil { - log.Info(Fmt("Can't find pubkey for %X", tx.Input.Address)) - return err - } - signBytes := acm.SignBytes(_s.ChainID, tx) - err := validateInput(inAcc, signBytes, tx.Input) - if err != nil { - log.Info(Fmt("validateInput failed on %X: %v", tx.Input.Address, err)) - return err - } - // fee is in addition to the amount which is used to determine the TTL - if tx.Input.Amount < tx.Fee { - log.Info(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address)) - return types.ErrTxInsufficientFunds - } - - // validate the input strings - if err := tx.ValidateStrings(); err != nil { - return err - } - - value := tx.Input.Amount - tx.Fee - - // let's say cost of a name for one block is len(data) + 32 - costPerBlock := types.NameCostPerBlock(types.NameBaseCost(tx.Name, tx.Data)) - expiresIn := int(value / costPerBlock) - lastBlockHeight := _s.LastBlockHeight - - log.Info("New NameTx", "value", value, "costPerBlock", costPerBlock, "expiresIn", expiresIn, "lastBlock", lastBlockHeight) - - // check if the name exists - entry := blockCache.GetNameRegEntry(tx.Name) - - if entry != nil { - var expired bool - // if the entry already exists, and hasn't expired, we must be owner - if entry.Expires > lastBlockHeight { - // ensure we are owner - if bytes.Compare(entry.Owner, tx.Input.Address) != 0 { - log.Info(Fmt("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name)) - return types.ErrTxPermissionDenied - } - } else { - expired = true - } - - // no value and empty data means delete the entry - if value == 0 && len(tx.Data) == 0 { - // maybe we reward you for telling us we can delete this crap - // (owners if not expired, anyone if expired) - log.Info("Removing namereg entry", "name", entry.Name) - blockCache.RemoveNameRegEntry(entry.Name) - } else { - // update the entry by bumping the expiry - // and changing the data - if expired { - if expiresIn < types.MinNameRegistrationPeriod { - return errors.New(Fmt("Names must be registered for at least %d blocks", types.MinNameRegistrationPeriod)) - } - entry.Expires = lastBlockHeight + expiresIn - entry.Owner = tx.Input.Address - log.Info("An old namereg entry has expired and been reclaimed", "name", entry.Name, "expiresIn", expiresIn, "owner", entry.Owner) - } else { - // since the size of the data may have changed - // we use the total amount of "credit" - oldCredit := int64(entry.Expires-lastBlockHeight) * types.NameBaseCost(entry.Name, entry.Data) - credit := oldCredit + value - expiresIn = int(credit / costPerBlock) - if expiresIn < types.MinNameRegistrationPeriod { - return errors.New(Fmt("Names must be registered for at least %d blocks", types.MinNameRegistrationPeriod)) - } - entry.Expires = lastBlockHeight + expiresIn - log.Info("Updated namereg entry", "name", entry.Name, "expiresIn", expiresIn, "oldCredit", oldCredit, "value", value, "credit", credit) - } - entry.Data = tx.Data - blockCache.UpdateNameRegEntry(entry) - } - } else { - if expiresIn < types.MinNameRegistrationPeriod { - return errors.New(Fmt("Names must be registered for at least %d blocks", types.MinNameRegistrationPeriod)) - } - // entry does not exist, so create it - entry = &types.NameRegEntry{ - Name: tx.Name, - Owner: tx.Input.Address, - Data: tx.Data, - Expires: lastBlockHeight + expiresIn, - } - log.Info("Creating namereg entry", "name", entry.Name, "expiresIn", expiresIn) - blockCache.UpdateNameRegEntry(entry) - } - - // TODO: something with the value sent? - - // Good! - inAcc.Sequence += 1 - inAcc.Balance -= value - blockCache.UpdateAccount(inAcc) - - // TODO: maybe we want to take funds on error and allow txs in that don't do anythingi? - - if evc != nil { - evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventDataTx{tx, nil, ""}) - evc.FireEvent(types.EventStringNameReg(tx.Name), types.EventDataTx{tx, nil, ""}) - } - - return nil - - case *types.BondTx: - valInfo := blockCache.State().GetValidatorInfo(tx.PubKey.Address()) - if valInfo != nil { - // TODO: In the future, check that the validator wasn't destroyed, - // add funds, merge UnbondTo outputs, and unbond validator. - return errors.New("Adding coins to existing validators not yet supported") - } - accounts, err := getInputs(blockCache, tx.Inputs) - if err != nil { - return err - } - - // add outputs to accounts map - // if any outputs don't exist, all inputs must have CreateAccount perm - // though outputs aren't created until unbonding/release time - canCreate := hasCreateAccountPermission(blockCache, accounts) - for _, out := range tx.UnbondTo { - acc := blockCache.GetAccount(out.Address) - if acc == nil && !canCreate { - return fmt.Errorf("At least one input does not have permission to create accounts") - } - } - - bondAcc := blockCache.GetAccount(tx.PubKey.Address()) - if !hasBondPermission(blockCache, bondAcc) { - return fmt.Errorf("The bonder does not have permission to bond") - } - - if !hasBondOrSendPermission(blockCache, accounts) { - return fmt.Errorf("At least one input lacks permission to bond") - } - - signBytes := acm.SignBytes(_s.ChainID, tx) - inTotal, err := validateInputs(accounts, signBytes, tx.Inputs) - 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") } - if !tx.PubKey.VerifyBytes(signBytes, tx.Signature) { - return types.ErrTxInvalidSignature + } 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)) } - outTotal, err := validateOutputs(tx.UnbondTo) + err := s.LastValidators.VerifyValidation( + s.ChainID, s.LastBlockHash, s.LastBlockParts, block.Height-1, block.LastValidation) if err != nil { return err } - if outTotal > inTotal { - return types.ErrTxInsufficientFunds - } - fee := inTotal - outTotal - fees += fee - - // Good! Adjust accounts - adjustByInputs(accounts, tx.Inputs) - for _, acc := range accounts { - blockCache.UpdateAccount(acc) - } - // Add ValidatorInfo - _s.SetValidatorInfo(&types.ValidatorInfo{ - Address: tx.PubKey.Address(), - PubKey: tx.PubKey, - UnbondTo: tx.UnbondTo, - FirstBondHeight: _s.LastBlockHeight + 1, - FirstBondAmount: outTotal, - }) - // Add Validator - added := _s.BondedValidators.Add(&types.Validator{ - Address: tx.PubKey.Address(), - PubKey: tx.PubKey, - BondHeight: _s.LastBlockHeight + 1, - VotingPower: outTotal, - Accum: 0, - }) - if !added { - PanicCrisis("Failed to add validator") - } - if evc != nil { - // TODO: fire for all inputs - evc.FireEvent(types.EventStringBond(), types.EventDataTx{tx, nil, ""}) - } - return nil - - case *types.UnbondTx: - // The validator must be active - _, val := _s.BondedValidators.GetByAddress(tx.Address) - if val == nil { - return types.ErrTxInvalidAddress - } + } - // Verify the signature - signBytes := acm.SignBytes(_s.ChainID, tx) - if !val.PubKey.VerifyBytes(signBytes, tx.Signature) { - return types.ErrTxInvalidSignature - } + return nil +} - // tx.Height must be greater than val.LastCommitHeight - if tx.Height <= val.LastCommitHeight { - return errors.New("Invalid unbond height") - } +// 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) { - // Good! - _s.unbondValidator(val) - if evc != nil { - evc.FireEvent(types.EventStringUnbond(), types.EventDataTx{tx, nil, ""}) + for i, precommit := range block.LastValidation.Precommits { + if precommit == nil { + continue } - return nil - - case *types.RebondTx: - // The validator must be inactive - _, val := _s.UnbondingValidators.GetByAddress(tx.Address) + _, val := lastValSet.GetByIndex(i) if val == nil { - return types.ErrTxInvalidAddress - } - - // Verify the signature - signBytes := acm.SignBytes(_s.ChainID, tx) - if !val.PubKey.VerifyBytes(signBytes, tx.Signature) { - return types.ErrTxInvalidSignature - } - - // tx.Height must be in a suitable range - minRebondHeight := _s.LastBlockHeight - (validatorTimeoutBlocks / 2) - maxRebondHeight := _s.LastBlockHeight + 2 - if !((minRebondHeight <= tx.Height) && (tx.Height <= maxRebondHeight)) { - return errors.New(Fmt("Rebond height not in range. Expected %v <= %v <= %v", - minRebondHeight, tx.Height, maxRebondHeight)) - } - - // Good! - _s.rebondValidator(val) - if evc != nil { - evc.FireEvent(types.EventStringRebond(), types.EventDataTx{tx, nil, ""}) - } - return nil - - case *types.DupeoutTx: - // Verify the signatures - _, accused := _s.BondedValidators.GetByAddress(tx.Address) - if accused == nil { - _, accused = _s.UnbondingValidators.GetByAddress(tx.Address) - if accused == nil { - return types.ErrTxInvalidAddress - } - } - voteASignBytes := acm.SignBytes(_s.ChainID, &tx.VoteA) - voteBSignBytes := acm.SignBytes(_s.ChainID, &tx.VoteB) - if !accused.PubKey.VerifyBytes(voteASignBytes, tx.VoteA.Signature) || - !accused.PubKey.VerifyBytes(voteBSignBytes, tx.VoteB.Signature) { - return types.ErrTxInvalidSignature - } - - // Verify equivocation - // TODO: in the future, just require one vote from a previous height that - // doesn't exist on this chain. - if tx.VoteA.Height != tx.VoteB.Height { - return errors.New("DupeoutTx heights don't match") - } - if tx.VoteA.Round != tx.VoteB.Round { - return errors.New("DupeoutTx rounds don't match") - } - if tx.VoteA.Type != tx.VoteB.Type { - return errors.New("DupeoutTx types don't match") - } - if bytes.Equal(tx.VoteA.BlockHash, tx.VoteB.BlockHash) { - return errors.New("DupeoutTx blockhashes shouldn't match") - } - - // Good! (Bad validator!) - _s.destroyValidator(accused) - if evc != nil { - evc.FireEvent(types.EventStringDupeout(), types.EventDataTx{tx, nil, ""}) - } - return nil - - case *types.PermissionsTx: - var inAcc *acm.Account - - // Validate input - inAcc = blockCache.GetAccount(tx.Input.Address) - if inAcc == nil { - log.Debug(Fmt("Can't find in account %X", tx.Input.Address)) - return types.ErrTxInvalidAddress - } - - permFlag := tx.PermArgs.PermFlag() - // check permission - if !HasPermission(blockCache, inAcc, permFlag) { - return fmt.Errorf("Account %X does not have moderator permission %s (%b)", tx.Input.Address, ptypes.PermFlagToString(permFlag), permFlag) - } - - // pubKey should be present in either "inAcc" or "tx.Input" - if err := checkInputPubKey(inAcc, tx.Input); err != nil { - log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address)) - return err - } - signBytes := acm.SignBytes(_s.ChainID, tx) - err := validateInput(inAcc, signBytes, tx.Input) - if err != nil { - log.Debug(Fmt("validateInput failed on %X: %v", tx.Input.Address, err)) - return err + PanicCrisis(Fmt("Failed to fetch validator at index %v", i)) } - - value := tx.Input.Amount - - log.Debug("New PermissionsTx", "function", ptypes.PermFlagToString(permFlag), "args", tx.PermArgs) - - var permAcc *acm.Account - switch args := tx.PermArgs.(type) { - case *ptypes.HasBaseArgs: - // this one doesn't make sense from txs - return fmt.Errorf("HasBase is for contracts, not humans. Just look at the blockchain") - case *ptypes.SetBaseArgs: - if permAcc = blockCache.GetAccount(args.Address); permAcc == nil { - return fmt.Errorf("Trying to update permissions for unknown account %X", args.Address) - } - err = permAcc.Permissions.Base.Set(args.Permission, args.Value) - case *ptypes.UnsetBaseArgs: - if permAcc = blockCache.GetAccount(args.Address); permAcc == nil { - return fmt.Errorf("Trying to update permissions for unknown account %X", args.Address) - } - err = permAcc.Permissions.Base.Unset(args.Permission) - case *ptypes.SetGlobalArgs: - if permAcc = blockCache.GetAccount(ptypes.GlobalPermissionsAddress); permAcc == nil { - PanicSanity("can't find global permissions account") - } - err = permAcc.Permissions.Base.Set(args.Permission, args.Value) - case *ptypes.HasRoleArgs: - return fmt.Errorf("HasRole is for contracts, not humans. Just look at the blockchain") - case *ptypes.AddRoleArgs: - if permAcc = blockCache.GetAccount(args.Address); permAcc == nil { - return fmt.Errorf("Trying to update roles for unknown account %X", args.Address) - } - if !permAcc.Permissions.AddRole(args.Role) { - return fmt.Errorf("Role (%s) already exists for account %X", args.Role, args.Address) - } - case *ptypes.RmRoleArgs: - if permAcc = blockCache.GetAccount(args.Address); permAcc == nil { - return fmt.Errorf("Trying to update roles for unknown account %X", args.Address) - } - if !permAcc.Permissions.RmRole(args.Role) { - return fmt.Errorf("Role (%s) does not exist for account %X", args.Role, args.Address) + 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") } - default: - PanicSanity(Fmt("invalid permission function: %s", ptypes.PermFlagToString(permFlag))) - } - - // TODO: maybe we want to take funds on error and allow txs in that don't do anythingi? - if err != nil { - return err - } - - // Good! - inAcc.Sequence += 1 - inAcc.Balance -= value - blockCache.UpdateAccount(inAcc) - if permAcc != nil { - blockCache.UpdateAccount(permAcc) - } - - if evc != nil { - evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventDataTx{tx, nil, ""}) - evc.FireEvent(types.EventStringPermissions(ptypes.PermFlagToString(permFlag)), types.EventDataTx{tx, nil, ""}) - } - - return nil - - default: - // binary decoding should not let this happen - PanicSanity("Unknown Tx type") - return nil - } -} - -//--------------------------------------------------------------- - -// Get permission on an account or fall back to global value -func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag) bool { - if perm > ptypes.AllPermFlags { - PanicSanity("Checking an unknown permission in state should never happen") - } - - if acc == nil { - // TODO - // this needs to fall back to global or do some other specific things - // eg. a bondAcc may be nil and so can only bond if global bonding is true - } - permString := ptypes.PermFlagToString(perm) - - v, err := acc.Permissions.Base.Get(perm) - if _, ok := err.(ptypes.ErrValueNotSet); ok { - if state == nil { - PanicSanity("All known global permissions should be set!") - } - log.Info("Permission for account is not set. Querying GlobalPermissionsAddress", "perm", permString) - return HasPermission(nil, state.GetAccount(ptypes.GlobalPermissionsAddress), perm) - } else if v { - log.Info("Account has permission", "address", Fmt("%X", acc.Address), "perm", permString) - } else { - log.Info("Account does not have permission", "address", Fmt("%X", acc.Address), "perm", permString) - } - return v -} - -// TODO: for debug log the failed accounts -func hasSendPermission(state AccountGetter, accs map[string]*acm.Account) bool { - for _, acc := range accs { - if !HasPermission(state, acc, ptypes.Send) { - return false + } 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") } } - return true -} - -func hasNamePermission(state AccountGetter, acc *acm.Account) bool { - return HasPermission(state, acc, ptypes.Name) -} -func hasCallPermission(state AccountGetter, acc *acm.Account) bool { - return HasPermission(state, acc, ptypes.Call) } -func hasCreateContractPermission(state AccountGetter, acc *acm.Account) bool { - return HasPermission(state, acc, ptypes.CreateContract) -} - -func hasCreateAccountPermission(state AccountGetter, accs map[string]*acm.Account) bool { - for _, acc := range accs { - if !HasPermission(state, acc, ptypes.CreateAccount) { - return false - } - } - return true -} +//----------------------------------------------------------------------------- -func hasBondPermission(state AccountGetter, acc *acm.Account) bool { - return HasPermission(state, acc, ptypes.Bond) +type InvalidTxError struct { + Tx types.Tx + tmsp.RetCode } -func hasBondOrSendPermission(state AccountGetter, accs map[string]*acm.Account) bool { - for _, acc := range accs { - if !HasPermission(state, acc, ptypes.Bond) { - if !HasPermission(state, acc, ptypes.Send) { - return false - } - } - } - return true +func (txErr InvalidTxError) Error() string { + return Fmt("Invalid tx: [%v] code: [%v]", txErr.Tx, txErr.RetCode) } -//----------------------------------------------------------------------------- - -type InvalidTxError struct { - Tx types.Tx - Reason error +type InvalidAppHashError struct { + Expected []byte + Got []byte } -func (txErr InvalidTxError) Error() string { - return Fmt("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason) +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/genesis_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/genesis_test.go deleted file mode 100644 index dfa66339..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/genesis_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package state - -import ( - "bytes" - "encoding/hex" - "fmt" - "testing" - - tdb "github.com/tendermint/tendermint/db" - ptypes "github.com/tendermint/tendermint/permission/types" - . "github.com/tendermint/tendermint/state/types" -) - -var chain_id = "lone_ranger" -var addr1, _ = hex.DecodeString("964B1493BBE3312278B7DEB94C39149F7899A345") -var send1, name1, call1 = 1, 1, 0 -var perms, setbit = 66, 70 -var accName = "me" -var roles1 = []string{"master", "universal-ruler"} -var amt1 int64 = 1000000 -var g1 = fmt.Sprintf(` -{ - "chain_id":"%s", - "accounts": [ - { - "address": "%X", - "amount": %d, - "name": "%s", - "permissions": { - "base": { - "perms": %d, - "set": %d - }, - "roles": [ - "%s", - "%s" - ] - } - } - ], - "validators": [ - { - "amount": 100000000, - "pub_key": [1,"F6C79CF0CB9D66B677988BCB9B8EADD9A091CD465A60542A8AB85476256DBA92"], - "unbond_to": [ - { - "address": "964B1493BBE3312278B7DEB94C39149F7899A345", - "amount": 10000000 - } - ] - } - ] -} -`, chain_id, addr1, amt1, accName, perms, setbit, roles1[0], roles1[1]) - -func TestGenesisReadable(t *testing.T) { - genDoc := GenesisDocFromJSON([]byte(g1)) - if genDoc.ChainID != chain_id { - t.Fatalf("Incorrect chain id. Got %d, expected %d\n", genDoc.ChainID, chain_id) - } - acc := genDoc.Accounts[0] - if bytes.Compare(acc.Address, addr1) != 0 { - t.Fatalf("Incorrect address for account. Got %X, expected %X\n", acc.Address, addr1) - } - if acc.Amount != amt1 { - t.Fatalf("Incorrect amount for account. Got %d, expected %d\n", acc.Amount, amt1) - } - if acc.Name != accName { - t.Fatalf("Incorrect name for account. Got %s, expected %s\n", acc.Name, accName) - } - - perm, _ := acc.Permissions.Base.Get(ptypes.Send) - if perm != (send1 > 0) { - t.Fatalf("Incorrect permission for send. Got %v, expected %v\n", perm, send1 > 0) - } -} - -func TestGenesisMakeState(t *testing.T) { - genDoc := GenesisDocFromJSON([]byte(g1)) - db := tdb.NewMemDB() - st := MakeGenesisState(db, genDoc) - acc := st.GetAccount(addr1) - v, _ := acc.Permissions.Base.Get(ptypes.Send) - if v != (send1 > 0) { - t.Fatalf("Incorrect permission for send. Got %v, expected %v\n", v, send1 > 0) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go index 7f1d3eba..316471ea 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go @@ -1,7 +1,7 @@ package state import ( - "github.com/tendermint/tendermint/logger" + "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/permissions_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/permissions_test.go deleted file mode 100644 index 34dfc9e5..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/permissions_test.go +++ /dev/null @@ -1,1265 +0,0 @@ -package state - -import ( - "bytes" - "fmt" - "strconv" - "testing" - "time" - - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - dbm "github.com/tendermint/tendermint/db" - "github.com/tendermint/tendermint/events" - ptypes "github.com/tendermint/tendermint/permission/types" - . "github.com/tendermint/tendermint/state/types" - "github.com/tendermint/tendermint/types" -) - -/* -Permission Tests: - -- SendTx: -x - 1 input, no perm, call perm, create perm -x - 1 input, perm -x - 2 inputs, one with perm one without - -- CallTx, CALL -x - 1 input, no perm, send perm, create perm -x - 1 input, perm -x - contract runs call but doesn't have call perm -x - contract runs call and has call perm -x - contract runs call (with perm), runs contract that runs call (without perm) -x - contract runs call (with perm), runs contract that runs call (with perm) - -- CallTx for Create, CREATE -x - 1 input, no perm, send perm, call perm -x - 1 input, perm -x - contract runs create but doesn't have create perm -x - contract runs create but has perm -x - contract runs call with empty address (has call and create perm) - -- NameTx - - no perm, send perm, call perm - - with perm - -- BondTx -x - 1 input, no perm -x - 1 input, perm -x - 1 bonder with perm, input without send or bond -x - 1 bonder with perm, input with send -x - 1 bonder with perm, input with bond -x - 2 inputs, one with perm one without - -- SendTx for new account -x - 1 input, 1 unknown ouput, input with send, not create (fail) -x - 1 input, 1 unknown ouput, input with send and create (pass) -x - 2 inputs, 1 unknown ouput, both inputs with send, one with create, one without (fail) -x - 2 inputs, 1 known output, 1 unknown ouput, one input with create, one without (fail) -x - 2 inputs, 1 unknown ouput, both inputs with send, both inputs with create (pass ) -x - 2 inputs, 1 known output, 1 unknown ouput, both inputs with create, (pass) - - -- CALL for new account -x - unknown output, without create (fail) -x - unknown output, with create (pass) - - -- SNative (CallTx, CALL): - - for each of CallTx, Call -x - call each snative without permission, fails -x - call each snative with permission, pass - - list: -x - base: has,set,unset -x - globals: set -x - roles: has, add, rm - - -*/ - -// keys -var user = makeUsers(10) -var chainID = "testchain" - -func makeUsers(n int) []*acm.PrivAccount { - accounts := []*acm.PrivAccount{} - for i := 0; i < n; i++ { - secret := ("mysecret" + strconv.Itoa(i)) - user := acm.GenPrivAccountFromSecret(secret) - accounts = append(accounts, user) - } - return accounts -} - -var ( - PermsAllFalse = ptypes.ZeroAccountPermissions -) - -func newBaseGenDoc(globalPerm, accountPerm ptypes.AccountPermissions) GenesisDoc { - genAccounts := []GenesisAccount{} - for _, u := range user[:5] { - accountPermCopy := accountPerm // Create new instance for custom overridability. - genAccounts = append(genAccounts, GenesisAccount{ - Address: u.Address, - Amount: 1000000, - Permissions: &accountPermCopy, - }) - } - - return GenesisDoc{ - GenesisTime: time.Now(), - ChainID: chainID, - Params: &GenesisParams{ - GlobalPermissions: &globalPerm, - }, - Accounts: genAccounts, - Validators: []GenesisValidator{ - GenesisValidator{ - PubKey: user[0].PubKey.(acm.PubKeyEd25519), - Amount: 10, - UnbondTo: []BasicAccount{ - BasicAccount{ - Address: user[0].Address, - }, - }, - }, - }, - } -} - -func TestSendFails(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true) - genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true) - genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true) - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - - //------------------- - // send txs - - // simple send tx should fail - tx := types.NewSendTx() - if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[1].Address, 5) - tx.SignInput(chainID, 0, user[0]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // simple send tx with call perm should fail - tx = types.NewSendTx() - if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[4].Address, 5) - tx.SignInput(chainID, 0, user[2]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // simple send tx with create perm should fail - tx = types.NewSendTx() - if err := tx.AddInput(blockCache, user[3].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[4].Address, 5) - tx.SignInput(chainID, 0, user[3]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // simple send tx to unknown account without create_account perm should fail - acc := blockCache.GetAccount(user[3].Address) - acc.Permissions.Base.Set(ptypes.Send, true) - blockCache.UpdateAccount(acc) - tx = types.NewSendTx() - if err := tx.AddInput(blockCache, user[3].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[6].Address, 5) - tx.SignInput(chainID, 0, user[3]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } -} - -func TestName(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) - genDoc.Accounts[1].Permissions.Base.Set(ptypes.Name, true) - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - - //------------------- - // name txs - - // simple name tx without perm should fail - tx, err := types.NewNameTx(st, user[0].PubKey, "somename", "somedata", 10000, 100) - if err != nil { - t.Fatal(err) - } - tx.Sign(chainID, user[0]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // simple name tx with perm should pass - tx, err = types.NewNameTx(st, user[1].PubKey, "somename", "somedata", 10000, 100) - if err != nil { - t.Fatal(err) - } - tx.Sign(chainID, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal(err) - } -} - -func TestCallFails(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true) - genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true) - genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true) - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - - //------------------- - // call txs - - // simple call tx should fail - tx, _ := types.NewCallTx(blockCache, user[0].PubKey, user[4].Address, nil, 100, 100, 100) - tx.Sign(chainID, user[0]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // simple call tx with send permission should fail - tx, _ = types.NewCallTx(blockCache, user[1].PubKey, user[4].Address, nil, 100, 100, 100) - tx.Sign(chainID, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // simple call tx with create permission should fail - tx, _ = types.NewCallTx(blockCache, user[3].PubKey, user[4].Address, nil, 100, 100, 100) - tx.Sign(chainID, user[3]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - //------------------- - // create txs - - // simple call create tx should fail - tx, _ = types.NewCallTx(blockCache, user[0].PubKey, nil, nil, 100, 100, 100) - tx.Sign(chainID, user[0]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // simple call create tx with send perm should fail - tx, _ = types.NewCallTx(blockCache, user[1].PubKey, nil, nil, 100, 100, 100) - tx.Sign(chainID, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // simple call create tx with call perm should fail - tx, _ = types.NewCallTx(blockCache, user[2].PubKey, nil, nil, 100, 100, 100) - tx.Sign(chainID, user[2]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } -} - -func TestSendPermission(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - - // A single input, having the permission, should succeed - tx := types.NewSendTx() - if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[1].Address, 5) - tx.SignInput(chainID, 0, user[0]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Transaction failed", err) - } - - // Two inputs, one with permission, one without, should fail - tx = types.NewSendTx() - if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { - t.Fatal(err) - } - if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[2].Address, 10) - tx.SignInput(chainID, 0, user[0]) - tx.SignInput(chainID, 1, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } -} - -func TestCallPermission(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - - //------------------------------ - // call to simple contract - fmt.Println("\n##### SIMPLE CONTRACT") - - // create simple contract - simpleContractAddr := NewContractAddress(user[0].Address, 100) - simpleAcc := &acm.Account{ - Address: simpleContractAddr, - Balance: 0, - Code: []byte{0x60}, - Sequence: 0, - StorageRoot: Zero256.Bytes(), - Permissions: ptypes.ZeroAccountPermissions, - } - st.UpdateAccount(simpleAcc) - - // A single input, having the permission, should succeed - tx, _ := types.NewCallTx(blockCache, user[0].PubKey, simpleContractAddr, nil, 100, 100, 100) - tx.Sign(chainID, user[0]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Transaction failed", err) - } - - //---------------------------------------------------------- - // call to contract that calls simple contract - without perm - fmt.Println("\n##### CALL TO SIMPLE CONTRACT (FAIL)") - - // create contract that calls the simple contract - contractCode := callContractCode(simpleContractAddr) - caller1ContractAddr := NewContractAddress(user[0].Address, 101) - caller1Acc := &acm.Account{ - Address: caller1ContractAddr, - Balance: 10000, - Code: contractCode, - Sequence: 0, - StorageRoot: Zero256.Bytes(), - Permissions: ptypes.ZeroAccountPermissions, - } - blockCache.UpdateAccount(caller1Acc) - - // A single input, having the permission, but the contract doesn't have permission - tx, _ = types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100) - tx.Sign(chainID, user[0]) - - // we need to subscribe to the Call event to detect the exception - _, exception := execTxWaitEvent(t, blockCache, tx, types.EventStringAccCall(caller1ContractAddr)) // - if exception == "" { - t.Fatal("Expected exception") - } - - //---------------------------------------------------------- - // call to contract that calls simple contract - with perm - fmt.Println("\n##### CALL TO SIMPLE CONTRACT (PASS)") - - // A single input, having the permission, and the contract has permission - caller1Acc.Permissions.Base.Set(ptypes.Call, true) - blockCache.UpdateAccount(caller1Acc) - tx, _ = types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100) - tx.Sign(chainID, user[0]) - - // we need to subscribe to the Call event to detect the exception - _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccCall(caller1ContractAddr)) // - if exception != "" { - t.Fatal("Unexpected exception:", exception) - } - - //---------------------------------------------------------- - // call to contract that calls contract that calls simple contract - without perm - // caller1Contract calls simpleContract. caller2Contract calls caller1Contract. - // caller1Contract does not have call perms, but caller2Contract does. - fmt.Println("\n##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (FAIL)") - - contractCode2 := callContractCode(caller1ContractAddr) - caller2ContractAddr := NewContractAddress(user[0].Address, 102) - caller2Acc := &acm.Account{ - Address: caller2ContractAddr, - Balance: 1000, - Code: contractCode2, - Sequence: 0, - StorageRoot: Zero256.Bytes(), - Permissions: ptypes.ZeroAccountPermissions, - } - caller1Acc.Permissions.Base.Set(ptypes.Call, false) - caller2Acc.Permissions.Base.Set(ptypes.Call, true) - blockCache.UpdateAccount(caller1Acc) - blockCache.UpdateAccount(caller2Acc) - - tx, _ = types.NewCallTx(blockCache, user[0].PubKey, caller2ContractAddr, nil, 100, 10000, 100) - tx.Sign(chainID, user[0]) - - // we need to subscribe to the Call event to detect the exception - _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccCall(caller1ContractAddr)) // - if exception == "" { - t.Fatal("Expected exception") - } - - //---------------------------------------------------------- - // call to contract that calls contract that calls simple contract - without perm - // caller1Contract calls simpleContract. caller2Contract calls caller1Contract. - // both caller1 and caller2 have permission - fmt.Println("\n##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (PASS)") - - caller1Acc.Permissions.Base.Set(ptypes.Call, true) - blockCache.UpdateAccount(caller1Acc) - - tx, _ = types.NewCallTx(blockCache, user[0].PubKey, caller2ContractAddr, nil, 100, 10000, 100) - tx.Sign(chainID, user[0]) - - // we need to subscribe to the Call event to detect the exception - _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccCall(caller1ContractAddr)) // - if exception != "" { - t.Fatal("Unexpected exception", exception) - } -} - -func TestCreatePermission(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateContract, true) // give the 0 account permission - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - - //------------------------------ - // create a simple contract - fmt.Println("\n##### CREATE SIMPLE CONTRACT") - - contractCode := []byte{0x60} - createCode := wrapContractForCreate(contractCode) - - // A single input, having the permission, should succeed - tx, _ := types.NewCallTx(blockCache, user[0].PubKey, nil, createCode, 100, 100, 100) - tx.Sign(chainID, user[0]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Transaction failed", err) - } - // ensure the contract is there - contractAddr := NewContractAddress(tx.Input.Address, tx.Input.Sequence) - contractAcc := blockCache.GetAccount(contractAddr) - if contractAcc == nil { - t.Fatalf("failed to create contract %X", contractAddr) - } - if bytes.Compare(contractAcc.Code, contractCode) != 0 { - t.Fatalf("contract does not have correct code. Got %X, expected %X", contractAcc.Code, contractCode) - } - - //------------------------------ - // create contract that uses the CREATE op - fmt.Println("\n##### CREATE FACTORY") - - contractCode = []byte{0x60} - createCode = wrapContractForCreate(contractCode) - factoryCode := createContractCode() - createFactoryCode := wrapContractForCreate(factoryCode) - - // A single input, having the permission, should succeed - tx, _ = types.NewCallTx(blockCache, user[0].PubKey, nil, createFactoryCode, 100, 100, 100) - tx.Sign(chainID, user[0]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Transaction failed", err) - } - // ensure the contract is there - contractAddr = NewContractAddress(tx.Input.Address, tx.Input.Sequence) - contractAcc = blockCache.GetAccount(contractAddr) - if contractAcc == nil { - t.Fatalf("failed to create contract %X", contractAddr) - } - if bytes.Compare(contractAcc.Code, factoryCode) != 0 { - t.Fatalf("contract does not have correct code. Got %X, expected %X", contractAcc.Code, factoryCode) - } - - //------------------------------ - // call the contract (should FAIL) - fmt.Println("\n###### CALL THE FACTORY (FAIL)") - - // A single input, having the permission, should succeed - tx, _ = types.NewCallTx(blockCache, user[0].PubKey, contractAddr, createCode, 100, 100, 100) - tx.Sign(chainID, user[0]) - // we need to subscribe to the Call event to detect the exception - _, exception := execTxWaitEvent(t, blockCache, tx, types.EventStringAccCall(contractAddr)) // - if exception == "" { - t.Fatal("expected exception") - } - - //------------------------------ - // call the contract (should PASS) - fmt.Println("\n###### CALL THE FACTORY (PASS)") - - contractAcc.Permissions.Base.Set(ptypes.CreateContract, true) - blockCache.UpdateAccount(contractAcc) - - // A single input, having the permission, should succeed - tx, _ = types.NewCallTx(blockCache, user[0].PubKey, contractAddr, createCode, 100, 100, 100) - tx.Sign(chainID, user[0]) - // we need to subscribe to the Call event to detect the exception - _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccCall(contractAddr)) // - if exception != "" { - t.Fatal("unexpected exception", exception) - } - - //-------------------------------- - fmt.Println("\n##### CALL to empty address") - zeroAddr := LeftPadBytes([]byte{}, 20) - code := callContractCode(zeroAddr) - - contractAddr = NewContractAddress(user[0].Address, 110) - contractAcc = &acm.Account{ - Address: contractAddr, - Balance: 1000, - Code: code, - Sequence: 0, - StorageRoot: Zero256.Bytes(), - Permissions: ptypes.ZeroAccountPermissions, - } - contractAcc.Permissions.Base.Set(ptypes.Call, true) - contractAcc.Permissions.Base.Set(ptypes.CreateContract, true) - blockCache.UpdateAccount(contractAcc) - - // this should call the 0 address but not create ... - tx, _ = types.NewCallTx(blockCache, user[0].PubKey, contractAddr, createCode, 100, 10000, 100) - tx.Sign(chainID, user[0]) - // we need to subscribe to the Call event to detect the exception - _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccCall(zeroAddr)) // - if exception != "" { - t.Fatal("unexpected exception", exception) - } - zeroAcc := blockCache.GetAccount(zeroAddr) - if len(zeroAcc.Code) != 0 { - t.Fatal("the zero account was given code from a CALL!") - } -} - -func TestBondPermission(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - var bondAcc *acm.Account - - //------------------------------ - // one bonder without permission should fail - tx, _ := types.NewBondTx(user[1].PubKey) - if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[1].Address, 5) - tx.SignInput(chainID, 0, user[1]) - tx.SignBond(chainID, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - //------------------------------ - // one bonder with permission should pass - bondAcc = blockCache.GetAccount(user[1].Address) - bondAcc.Permissions.Base.Set(ptypes.Bond, true) - blockCache.UpdateAccount(bondAcc) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Unexpected error", err) - } - - // reset state (we can only bond with an account once ..) - genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse) - st = MakeGenesisState(stateDB, &genDoc) - blockCache = NewBlockCache(st) - bondAcc = blockCache.GetAccount(user[1].Address) - bondAcc.Permissions.Base.Set(ptypes.Bond, true) - blockCache.UpdateAccount(bondAcc) - //------------------------------ - // one bonder with permission and an input without send should fail - tx, _ = types.NewBondTx(user[1].PubKey) - if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[1].Address, 5) - tx.SignInput(chainID, 0, user[2]) - tx.SignBond(chainID, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // reset state (we can only bond with an account once ..) - genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse) - st = MakeGenesisState(stateDB, &genDoc) - blockCache = NewBlockCache(st) - bondAcc = blockCache.GetAccount(user[1].Address) - bondAcc.Permissions.Base.Set(ptypes.Bond, true) - blockCache.UpdateAccount(bondAcc) - //------------------------------ - // one bonder with permission and an input with send should pass - sendAcc := blockCache.GetAccount(user[2].Address) - sendAcc.Permissions.Base.Set(ptypes.Send, true) - blockCache.UpdateAccount(sendAcc) - tx, _ = types.NewBondTx(user[1].PubKey) - if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[1].Address, 5) - tx.SignInput(chainID, 0, user[2]) - tx.SignBond(chainID, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Unexpected error", err) - } - - // reset state (we can only bond with an account once ..) - genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse) - st = MakeGenesisState(stateDB, &genDoc) - blockCache = NewBlockCache(st) - bondAcc = blockCache.GetAccount(user[1].Address) - bondAcc.Permissions.Base.Set(ptypes.Bond, true) - blockCache.UpdateAccount(bondAcc) - //------------------------------ - // one bonder with permission and an input with bond should pass - sendAcc.Permissions.Base.Set(ptypes.Bond, true) - blockCache.UpdateAccount(sendAcc) - tx, _ = types.NewBondTx(user[1].PubKey) - if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[1].Address, 5) - tx.SignInput(chainID, 0, user[2]) - tx.SignBond(chainID, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Unexpected error", err) - } - - // reset state (we can only bond with an account once ..) - genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse) - st = MakeGenesisState(stateDB, &genDoc) - blockCache = NewBlockCache(st) - bondAcc = blockCache.GetAccount(user[1].Address) - bondAcc.Permissions.Base.Set(ptypes.Bond, true) - blockCache.UpdateAccount(bondAcc) - //------------------------------ - // one bonder with permission and an input from that bonder and an input without send or bond should fail - tx, _ = types.NewBondTx(user[1].PubKey) - if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { - t.Fatal(err) - } - if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[1].Address, 5) - tx.SignInput(chainID, 0, user[1]) - tx.SignInput(chainID, 1, user[2]) - tx.SignBond(chainID, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } -} - -func TestCreateAccountPermission(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission - genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission - genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateAccount, true) // give the 0 account permission - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - - //---------------------------------------------------------- - // SendTx to unknown account - - // A single input, having the permission, should succeed - tx := types.NewSendTx() - if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[6].Address, 5) - tx.SignInput(chainID, 0, user[0]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Transaction failed", err) - } - - // Two inputs, both with send, one with create, one without, should fail - tx = types.NewSendTx() - if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { - t.Fatal(err) - } - if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[7].Address, 10) - tx.SignInput(chainID, 0, user[0]) - tx.SignInput(chainID, 1, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // Two inputs, both with send, one with create, one without, two ouputs (one known, one unknown) should fail - tx = types.NewSendTx() - if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { - t.Fatal(err) - } - if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[7].Address, 4) - tx.AddOutput(user[4].Address, 6) - tx.SignInput(chainID, 0, user[0]) - tx.SignInput(chainID, 1, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err == nil { - t.Fatal("Expected error") - } else { - fmt.Println(err) - } - - // Two inputs, both with send, both with create, should pass - acc := blockCache.GetAccount(user[1].Address) - acc.Permissions.Base.Set(ptypes.CreateAccount, true) - blockCache.UpdateAccount(acc) - tx = types.NewSendTx() - if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { - t.Fatal(err) - } - if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[7].Address, 10) - tx.SignInput(chainID, 0, user[0]) - tx.SignInput(chainID, 1, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Unexpected error", err) - } - - // Two inputs, both with send, both with create, two outputs (one known, one unknown) should pass - tx = types.NewSendTx() - if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { - t.Fatal(err) - } - if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { - t.Fatal(err) - } - tx.AddOutput(user[7].Address, 7) - tx.AddOutput(user[4].Address, 3) - tx.SignInput(chainID, 0, user[0]) - tx.SignInput(chainID, 1, user[1]) - if err := ExecTx(blockCache, tx, true, nil); err != nil { - t.Fatal("Unexpected error", err) - } - - //---------------------------------------------------------- - // CALL to unknown account - - acc = blockCache.GetAccount(user[0].Address) - acc.Permissions.Base.Set(ptypes.Call, true) - blockCache.UpdateAccount(acc) - - // call to contract that calls unknown account - without create_account perm - // create contract that calls the simple contract - contractCode := callContractCode(user[9].Address) - caller1ContractAddr := NewContractAddress(user[4].Address, 101) - caller1Acc := &acm.Account{ - Address: caller1ContractAddr, - Balance: 0, - Code: contractCode, - Sequence: 0, - StorageRoot: Zero256.Bytes(), - Permissions: ptypes.ZeroAccountPermissions, - } - blockCache.UpdateAccount(caller1Acc) - - // A single input, having the permission, but the contract doesn't have permission - txCall, _ := types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100) - txCall.Sign(chainID, user[0]) - - // we need to subscribe to the Call event to detect the exception - _, exception := execTxWaitEvent(t, blockCache, txCall, types.EventStringAccCall(caller1ContractAddr)) // - if exception == "" { - t.Fatal("Expected exception") - } - - // NOTE: for a contract to be able to CreateAccount, it must be able to call - // NOTE: for a user to be able to CreateAccount, it must be able to send! - caller1Acc.Permissions.Base.Set(ptypes.CreateAccount, true) - caller1Acc.Permissions.Base.Set(ptypes.Call, true) - blockCache.UpdateAccount(caller1Acc) - // A single input, having the permission, but the contract doesn't have permission - txCall, _ = types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100) - txCall.Sign(chainID, user[0]) - - // we need to subscribe to the Call event to detect the exception - _, exception = execTxWaitEvent(t, blockCache, txCall, types.EventStringAccCall(caller1ContractAddr)) // - if exception != "" { - t.Fatal("Unexpected exception", exception) - } - -} - -// holla at my boy -var DougAddress = append([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []byte("THISISDOUG")...) - -func TestSNativeCALL(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission - genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with - genDoc.Accounts[3].Permissions.AddRole("bumble") - genDoc.Accounts[3].Permissions.AddRole("bee") - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - - //---------------------------------------------------------- - // Test CALL to SNative contracts - - // make the main contract once - doug := &acm.Account{ - Address: DougAddress, - Balance: 0, - Code: nil, - Sequence: 0, - StorageRoot: Zero256.Bytes(), - Permissions: ptypes.ZeroAccountPermissions, - } - doug.Permissions.Base.Set(ptypes.Call, true) - //doug.Permissions.Base.Set(ptypes.HasBase, true) - blockCache.UpdateAccount(doug) - - fmt.Println("\n#### HasBase") - // HasBase - snativeAddress, data := snativePermTestInputCALL("has_base", user[3], ptypes.Bond, false) - testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { - // return value should be true or false as a 32 byte array... - if !IsZeros(ret[:31]) || ret[31] != byte(1) { - return fmt.Errorf("Expected 1. Got %X", ret) - } - return nil - }) - - fmt.Println("\n#### SetBase") - // SetBase - snativeAddress, data = snativePermTestInputCALL("set_base", user[3], ptypes.Bond, false) - testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, data = snativePermTestInputCALL("has_base", user[3], ptypes.Bond, false) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { - // return value should be true or false as a 32 byte array... - if !IsZeros(ret) { - return fmt.Errorf("Expected 0. Got %X", ret) - } - return nil - }) - snativeAddress, data = snativePermTestInputCALL("set_base", user[3], ptypes.CreateContract, true) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, data = snativePermTestInputCALL("has_base", user[3], ptypes.CreateContract, false) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { - // return value should be true or false as a 32 byte array... - if !IsZeros(ret[:31]) || ret[31] != byte(1) { - return fmt.Errorf("Expected 1. Got %X", ret) - } - return nil - }) - - fmt.Println("\n#### UnsetBase") - // UnsetBase - snativeAddress, data = snativePermTestInputCALL("unset_base", user[3], ptypes.CreateContract, false) - testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, data = snativePermTestInputCALL("has_base", user[3], ptypes.CreateContract, false) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { - if !IsZeros(ret) { - return fmt.Errorf("Expected 0. Got %X", ret) - } - return nil - }) - - fmt.Println("\n#### SetGlobal") - // SetGlobalPerm - snativeAddress, data = snativePermTestInputCALL("set_global", user[3], ptypes.CreateContract, true) - testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, data = snativePermTestInputCALL("has_base", user[3], ptypes.CreateContract, false) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { - // return value should be true or false as a 32 byte array... - if !IsZeros(ret[:31]) || ret[31] != byte(1) { - return fmt.Errorf("Expected 1. Got %X", ret) - } - return nil - }) - - fmt.Println("\n#### HasRole") - // HasRole - snativeAddress, data = snativeRoleTestInputCALL("has_role", user[3], "bumble") - testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { - if !IsZeros(ret[:31]) || ret[31] != byte(1) { - return fmt.Errorf("Expected 1. Got %X", ret) - } - return nil - }) - - fmt.Println("\n#### AddRole") - // AddRole - snativeAddress, data = snativeRoleTestInputCALL("has_role", user[3], "chuck") - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { - if !IsZeros(ret) { - return fmt.Errorf("Expected 0. Got %X", ret) - } - return nil - }) - snativeAddress, data = snativeRoleTestInputCALL("add_role", user[3], "chuck") - testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, data = snativeRoleTestInputCALL("has_role", user[3], "chuck") - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { - if !IsZeros(ret[:31]) || ret[31] != byte(1) { - return fmt.Errorf("Expected 1. Got %X", ret) - } - return nil - }) - - fmt.Println("\n#### RmRole") - // RmRole - snativeAddress, data = snativeRoleTestInputCALL("rm_role", user[3], "chuck") - testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data) - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, data = snativeRoleTestInputCALL("has_role", user[3], "chuck") - testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { - if !IsZeros(ret) { - return fmt.Errorf("Expected 0. Got %X", ret) - } - return nil - }) -} - -func TestSNativeTx(t *testing.T) { - stateDB := dbm.GetDB("state") - genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission - genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with - genDoc.Accounts[3].Permissions.AddRole("bumble") - genDoc.Accounts[3].Permissions.AddRole("bee") - st := MakeGenesisState(stateDB, &genDoc) - blockCache := NewBlockCache(st) - - //---------------------------------------------------------- - // Test SNativeTx - - fmt.Println("\n#### SetBase") - // SetBase - snativeArgs := snativePermTestInputTx("set_base", user[3], ptypes.Bond, false) - testSNativeTxExpectFail(t, blockCache, snativeArgs) - testSNativeTxExpectPass(t, blockCache, ptypes.SetBase, snativeArgs) - acc := blockCache.GetAccount(user[3].Address) - if v, _ := acc.Permissions.Base.Get(ptypes.Bond); v { - t.Fatal("expected permission to be set false") - } - snativeArgs = snativePermTestInputTx("set_base", user[3], ptypes.CreateContract, true) - testSNativeTxExpectPass(t, blockCache, ptypes.SetBase, snativeArgs) - acc = blockCache.GetAccount(user[3].Address) - if v, _ := acc.Permissions.Base.Get(ptypes.CreateContract); !v { - t.Fatal("expected permission to be set true") - } - - fmt.Println("\n#### UnsetBase") - // UnsetBase - snativeArgs = snativePermTestInputTx("unset_base", user[3], ptypes.CreateContract, false) - testSNativeTxExpectFail(t, blockCache, snativeArgs) - testSNativeTxExpectPass(t, blockCache, ptypes.UnsetBase, snativeArgs) - acc = blockCache.GetAccount(user[3].Address) - if v, _ := acc.Permissions.Base.Get(ptypes.CreateContract); v { - t.Fatal("expected permission to be set false") - } - - fmt.Println("\n#### SetGlobal") - // SetGlobalPerm - snativeArgs = snativePermTestInputTx("set_global", user[3], ptypes.CreateContract, true) - testSNativeTxExpectFail(t, blockCache, snativeArgs) - testSNativeTxExpectPass(t, blockCache, ptypes.SetGlobal, snativeArgs) - acc = blockCache.GetAccount(ptypes.GlobalPermissionsAddress) - if v, _ := acc.Permissions.Base.Get(ptypes.CreateContract); !v { - t.Fatal("expected permission to be set true") - } - - fmt.Println("\n#### AddRole") - // AddRole - snativeArgs = snativeRoleTestInputTx("add_role", user[3], "chuck") - testSNativeTxExpectFail(t, blockCache, snativeArgs) - testSNativeTxExpectPass(t, blockCache, ptypes.AddRole, snativeArgs) - acc = blockCache.GetAccount(user[3].Address) - if v := acc.Permissions.HasRole("chuck"); !v { - t.Fatal("expected role to be added") - } - - fmt.Println("\n#### RmRole") - // RmRole - snativeArgs = snativeRoleTestInputTx("rm_role", user[3], "chuck") - testSNativeTxExpectFail(t, blockCache, snativeArgs) - testSNativeTxExpectPass(t, blockCache, ptypes.RmRole, snativeArgs) - acc = blockCache.GetAccount(user[3].Address) - if v := acc.Permissions.HasRole("chuck"); v { - t.Fatal("expected role to be removed") - } -} - -//------------------------------------------------------------------------------------- -// helpers - -var ExceptionTimeOut = "timed out waiting for event" - -// run ExecTx and wait for the Call event on given addr -// returns the msg data and an error/exception -func execTxWaitEvent(t *testing.T, blockCache *BlockCache, tx types.Tx, eventid string) (interface{}, string) { - evsw := events.NewEventSwitch() - evsw.Start() - ch := make(chan interface{}) - evsw.AddListenerForEvent("test", eventid, func(msg types.EventData) { - ch <- msg - }) - evc := events.NewEventCache(evsw) - go func() { - if err := ExecTx(blockCache, tx, true, evc); err != nil { - ch <- err.Error() - } - evc.Flush() - }() - ticker := time.NewTicker(5 * time.Second) - var msg interface{} - select { - case msg = <-ch: - case <-ticker.C: - return nil, ExceptionTimeOut - } - - switch ev := msg.(type) { - case types.EventDataTx: - return ev, ev.Exception - case types.EventDataCall: - return ev, ev.Exception - case string: - return nil, ev - default: - return ev, "" - } -} - -// give a contract perms for an snative, call it, it calls the snative, but shouldn't have permission -func testSNativeCALLExpectFail(t *testing.T, blockCache *BlockCache, doug *acm.Account, snativeAddress, data []byte) { - testSNativeCALL(t, false, blockCache, doug, snativeAddress, data, nil) -} - -// give a contract perms for an snative, call it, it calls the snative, ensure the check funciton (f) succeeds -func testSNativeCALLExpectPass(t *testing.T, blockCache *BlockCache, doug *acm.Account, snativeAddress, data []byte, f func([]byte) error) { - testSNativeCALL(t, true, blockCache, doug, snativeAddress, data, f) -} - -func testSNativeCALL(t *testing.T, expectPass bool, blockCache *BlockCache, doug *acm.Account, snativeAddress, data []byte, f func([]byte) error) { - if expectPass { - perm, err := ptypes.PermStringToFlag(TrimmedString(snativeAddress)) - if err != nil { - t.Fatal(err) - } - doug.Permissions.Base.Set(perm, true) - } - var addr []byte - contractCode := callContractCode(snativeAddress) - doug.Code = contractCode - blockCache.UpdateAccount(doug) - addr = doug.Address - tx, _ := types.NewCallTx(blockCache, user[0].PubKey, addr, data, 100, 10000, 100) - tx.Sign(chainID, user[0]) - fmt.Println("subscribing to", types.EventStringAccCall(snativeAddress)) - ev, exception := execTxWaitEvent(t, blockCache, tx, types.EventStringAccCall(snativeAddress)) - if exception == ExceptionTimeOut { - t.Fatal("Timed out waiting for event") - } - if expectPass { - if exception != "" { - t.Fatal("Unexpected exception", exception) - } - evv := ev.(types.EventDataCall) - ret := evv.Return - if err := f(ret); err != nil { - t.Fatal(err) - } - } else { - if exception == "" { - t.Fatal("Expected exception") - } - } -} - -func testSNativeTxExpectFail(t *testing.T, blockCache *BlockCache, snativeArgs ptypes.PermArgs) { - testSNativeTx(t, false, blockCache, 0, snativeArgs) -} - -func testSNativeTxExpectPass(t *testing.T, blockCache *BlockCache, perm ptypes.PermFlag, snativeArgs ptypes.PermArgs) { - testSNativeTx(t, true, blockCache, perm, snativeArgs) -} - -func testSNativeTx(t *testing.T, expectPass bool, blockCache *BlockCache, perm ptypes.PermFlag, snativeArgs ptypes.PermArgs) { - if expectPass { - acc := blockCache.GetAccount(user[0].Address) - acc.Permissions.Base.Set(perm, true) - blockCache.UpdateAccount(acc) - } - tx, _ := types.NewPermissionsTx(blockCache, user[0].PubKey, snativeArgs) - tx.Sign(chainID, user[0]) - err := ExecTx(blockCache, tx, true, nil) - if expectPass { - if err != nil { - t.Fatal("Unexpected exception", err) - } - } else { - if err == nil { - t.Fatal("Expected exception") - } - } -} - -func boolToWord256(v bool) Word256 { - var vint byte - if v { - vint = 0x1 - } else { - vint = 0x0 - } - return LeftPadWord256([]byte{vint}) -} - -func snativePermTestInputCALL(name string, user *acm.PrivAccount, perm ptypes.PermFlag, val bool) (addr []byte, data []byte) { - addr = LeftPadWord256([]byte(name)).Postfix(20) - switch name { - case "has_base", "unset_base": - data = LeftPadBytes(user.Address, 32) - data = append(data, Uint64ToWord256(uint64(perm)).Bytes()...) - case "set_base": - data = LeftPadBytes(user.Address, 32) - data = append(data, Uint64ToWord256(uint64(perm)).Bytes()...) - data = append(data, boolToWord256(val).Bytes()...) - case "set_global": - data = Uint64ToWord256(uint64(perm)).Bytes() - data = append(data, boolToWord256(val).Bytes()...) - } - return -} - -func snativePermTestInputTx(name string, user *acm.PrivAccount, perm ptypes.PermFlag, val bool) (snativeArgs ptypes.PermArgs) { - switch name { - case "has_base": - snativeArgs = &ptypes.HasBaseArgs{user.Address, perm} - case "unset_base": - snativeArgs = &ptypes.UnsetBaseArgs{user.Address, perm} - case "set_base": - snativeArgs = &ptypes.SetBaseArgs{user.Address, perm, val} - case "set_global": - snativeArgs = &ptypes.SetGlobalArgs{perm, val} - } - return -} - -func snativeRoleTestInputCALL(name string, user *acm.PrivAccount, role string) (addr []byte, data []byte) { - addr = LeftPadWord256([]byte(name)).Postfix(20) - data = LeftPadBytes(user.Address, 32) - data = append(data, LeftPadBytes([]byte(role), 32)...) - return -} - -func snativeRoleTestInputTx(name string, user *acm.PrivAccount, role string) (snativeArgs ptypes.PermArgs) { - switch name { - case "has_role": - snativeArgs = &ptypes.HasRoleArgs{user.Address, role} - case "add_role": - snativeArgs = &ptypes.AddRoleArgs{user.Address, role} - case "rm_role": - snativeArgs = &ptypes.RmRoleArgs{user.Address, role} - } - return -} - -// convenience function for contract that calls a given address -func callContractCode(contractAddr []byte) []byte { - // calldatacopy into mem and use as input to call - memOff, inputOff := byte(0x0), byte(0x0) - contractCode := []byte{0x36, 0x60, inputOff, 0x60, memOff, 0x37} - - gas1, gas2 := byte(0x1), byte(0x1) - value := byte(0x1) - inOff := byte(0x0) - retOff, retSize := byte(0x0), byte(0x20) - // this is the code we want to run (call a contract and return) - contractCode = append(contractCode, []byte{0x60, retSize, 0x60, retOff, 0x36, 0x60, inOff, 0x60, value, 0x73}...) - contractCode = append(contractCode, contractAddr...) - contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...) - return contractCode -} - -// convenience function for contract that is a factory for the code that comes as call data -func createContractCode() []byte { - // TODO: gas ... - - // calldatacopy the calldatasize - memOff, inputOff := byte(0x0), byte(0x0) - contractCode := []byte{0x60, memOff, 0x60, inputOff, 0x36, 0x37} - - // create - value := byte(0x1) - contractCode = append(contractCode, []byte{0x60, value, 0x36, 0x60, memOff, 0xf0}...) - return contractCode -} - -// wrap a contract in create code -func wrapContractForCreate(contractCode []byte) []byte { - // the is the code we need to return the contractCode when the contract is initialized - lenCode := len(contractCode) - // push code to the stack - code := append([]byte{0x7f}, RightPadWord256(contractCode).Bytes()...) - // store it in memory - code = append(code, []byte{0x60, 0x0, 0x52}...) - // return whats in memory - code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...) - // return init code, contract code, expected return - return code -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go index 20f6d134..e890ea8c 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go @@ -2,73 +2,48 @@ package state import ( "bytes" - "io" "io/ioutil" + "sync" "time" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - dbm "github.com/tendermint/tendermint/db" - "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/merkle" - ptypes "github.com/tendermint/tendermint/permission/types" - . "github.com/tendermint/tendermint/state/types" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" + . "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") - minBondAmount = int64(1) // TODO adjust - defaultAccountsCacheCapacity = 1000 // TODO adjust - unbondingPeriodBlocks = int(60 * 24 * 365) // TODO probably better to make it time based. - validatorTimeoutBlocks = int(10) // TODO adjust + stateKey = []byte("stateKey") ) //----------------------------------------------------------------------------- // NOTE: not goroutine-safe. type State struct { - DB dbm.DB - ChainID string - LastBlockHeight int - LastBlockHash []byte - LastBlockParts types.PartSetHeader - LastBlockTime time.Time - BondedValidators *types.ValidatorSet - LastBondedValidators *types.ValidatorSet - UnbondingValidators *types.ValidatorSet - accounts merkle.Tree // Shouldn't be accessed directly. - validatorInfos merkle.Tree // Shouldn't be accessed directly. - nameReg merkle.Tree // Shouldn't be accessed directly. + 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} + s := &State{db: db} buf := db.Get(stateKey) if len(buf) == 0 { return nil } else { - r, n, err := bytes.NewReader(buf), new(int64), new(error) - s.ChainID = wire.ReadString(r, n, err) - s.LastBlockHeight = wire.ReadVarint(r, n, err) - s.LastBlockHash = wire.ReadByteSlice(r, n, err) - s.LastBlockParts = wire.ReadBinary(types.PartSetHeader{}, r, n, err).(types.PartSetHeader) - s.LastBlockTime = wire.ReadTime(r, n, err) - s.BondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) - s.LastBondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) - s.UnbondingValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) - accountsHash := wire.ReadByteSlice(r, n, err) - s.accounts = merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) - s.accounts.Load(accountsHash) - validatorInfosHash := wire.ReadByteSlice(r, n, err) - s.validatorInfos = merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, db) - s.validatorInfos.Load(validatorInfosHash) - nameRegHash := wire.ReadByteSlice(r, n, err) - s.nameReg = merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) - s.nameReg.Load(nameRegHash) + 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)) @@ -78,302 +53,55 @@ func LoadState(db dbm.DB) *State { return s } -func (s *State) Save() { - s.accounts.Save() - s.validatorInfos.Save() - s.nameReg.Save() - buf, n, err := new(bytes.Buffer), new(int64), new(error) - wire.WriteString(s.ChainID, buf, n, err) - wire.WriteVarint(s.LastBlockHeight, buf, n, err) - wire.WriteByteSlice(s.LastBlockHash, buf, n, err) - wire.WriteBinary(s.LastBlockParts, buf, n, err) - wire.WriteTime(s.LastBlockTime, buf, n, err) - wire.WriteBinary(s.BondedValidators, buf, n, err) - wire.WriteBinary(s.LastBondedValidators, buf, n, err) - wire.WriteBinary(s.UnbondingValidators, buf, n, err) - wire.WriteByteSlice(s.accounts.Hash(), buf, n, err) - wire.WriteByteSlice(s.validatorInfos.Hash(), buf, n, err) - wire.WriteByteSlice(s.nameReg.Hash(), buf, n, err) - if *err != nil { - PanicCrisis(*err) - } - s.DB.Set(stateKey, buf.Bytes()) -} - -// CONTRACT: -// Copy() is a cheap way to take a snapshot, -// as if State were copied by value. func (s *State) Copy() *State { return &State{ - DB: s.DB, - ChainID: s.ChainID, - LastBlockHeight: s.LastBlockHeight, - LastBlockHash: s.LastBlockHash, - LastBlockParts: s.LastBlockParts, - LastBlockTime: s.LastBlockTime, - BondedValidators: s.BondedValidators.Copy(), // TODO remove need for Copy() here. - LastBondedValidators: s.LastBondedValidators.Copy(), // That is, make updates to the validator set - UnbondingValidators: s.UnbondingValidators.Copy(), // copy the valSet lazily. - accounts: s.accounts.Copy(), - validatorInfos: s.validatorInfos.Copy(), - nameReg: s.nameReg.Copy(), - evc: nil, - } -} - -// Returns a hash that represents the state data, excluding Last* -func (s *State) Hash() []byte { - return merkle.SimpleHashFromMap(map[string]interface{}{ - "BondedValidators": s.BondedValidators, - "UnbondingValidators": s.UnbondingValidators, - "Accounts": s.accounts, - "ValidatorInfos": s.validatorInfos, - "NameRegistry": s.nameReg, - }) -} - -// Mutates the block in place and updates it with new state hash. -func (s *State) ComputeBlockStateHash(block *types.Block) error { - sCopy := s.Copy() - // sCopy has no event cache in it, so this won't fire events - err := execBlock(sCopy, block, types.PartSetHeader{}) - if err != nil { - return err - } - // Set block.StateHash - block.StateHash = sCopy.Hash() - return nil -} - -func (s *State) SetDB(db dbm.DB) { - s.DB = db -} - -//------------------------------------- -// State.params - -func (s *State) GetGasLimit() int64 { - return 1000000 // TODO -} - -// State.params -//------------------------------------- -// 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 { - return nil + 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, } - return acc.(*acm.Account).Copy() -} - -// 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.Copy()) -} - -// Implements Statelike -func (s *State) RemoveAccount(address []byte) bool { - _, removed := s.accounts.Remove(address) - return removed } -// The returned Account is a copy, so mutating it -// has no side effects. -func (s *State) GetAccounts() merkle.Tree { - return s.accounts.Copy() -} - -// Set the accounts tree -func (s *State) SetAccounts(accounts merkle.Tree) { - s.accounts = accounts -} - -// State.accounts -//------------------------------------- -// State.validators - -// The returned ValidatorInfo is a copy, so mutating it -// has no side effects. -func (s *State) GetValidatorInfo(address []byte) *types.ValidatorInfo { - _, valInfo := s.validatorInfos.Get(address) - if valInfo == nil { - return nil - } - return valInfo.(*types.ValidatorInfo).Copy() -} - -// Returns false if new, true if updated. -// The valInfo is copied before setting, so mutating it -// afterwards has no side effects. -func (s *State) SetValidatorInfo(valInfo *types.ValidatorInfo) (updated bool) { - return s.validatorInfos.Set(valInfo.Address, valInfo.Copy()) -} - -func (s *State) GetValidatorInfos() merkle.Tree { - return s.validatorInfos.Copy() -} - -func (s *State) unbondValidator(val *types.Validator) { - // Move validator to UnbondingValidators - val, removed := s.BondedValidators.Remove(val.Address) - if !removed { - PanicCrisis("Couldn't remove validator for unbonding") - } - val.UnbondHeight = s.LastBlockHeight + 1 - added := s.UnbondingValidators.Add(val) - if !added { - PanicCrisis("Couldn't add validator for unbonding") - } -} - -func (s *State) rebondValidator(val *types.Validator) { - // Move validator to BondingValidators - val, removed := s.UnbondingValidators.Remove(val.Address) - if !removed { - PanicCrisis("Couldn't remove validator for rebonding") - } - val.BondHeight = s.LastBlockHeight + 1 - added := s.BondedValidators.Add(val) - if !added { - PanicCrisis("Couldn't add validator for rebonding") - } -} - -func (s *State) releaseValidator(val *types.Validator) { - // Update validatorInfo - valInfo := s.GetValidatorInfo(val.Address) - if valInfo == nil { - PanicSanity("Couldn't find validatorInfo for release") - } - valInfo.ReleasedHeight = s.LastBlockHeight + 1 - s.SetValidatorInfo(valInfo) - - // Send coins back to UnbondTo outputs - accounts, err := getOrMakeOutputs(s, nil, valInfo.UnbondTo) - if err != nil { - PanicSanity("Couldn't get or make unbondTo accounts") - } - adjustByOutputs(accounts, valInfo.UnbondTo) - for _, acc := range accounts { - s.UpdateAccount(acc) - } - - // Remove validator from UnbondingValidators - _, removed := s.UnbondingValidators.Remove(val.Address) - if !removed { - PanicCrisis("Couldn't remove validator for release") - } -} - -func (s *State) destroyValidator(val *types.Validator) { - // Update validatorInfo - valInfo := s.GetValidatorInfo(val.Address) - if valInfo == nil { - PanicSanity("Couldn't find validatorInfo for release") - } - valInfo.DestroyedHeight = s.LastBlockHeight + 1 - valInfo.DestroyedAmount = val.VotingPower - s.SetValidatorInfo(valInfo) - - // Remove validator - _, removed := s.BondedValidators.Remove(val.Address) - if !removed { - _, removed := s.UnbondingValidators.Remove(val.Address) - if !removed { - PanicCrisis("Couldn't remove validator for destruction") - } - } - -} - -// Set the validator infos tree -func (s *State) SetValidatorInfos(validatorInfos merkle.Tree) { - s.validatorInfos = validatorInfos -} - -// State.validators -//------------------------------------- -// State.storage - -func (s *State) LoadStorage(hash []byte) (storage merkle.Tree) { - storage = merkle.NewIAVLTree(wire.BasicCodec, wire.BasicCodec, 1024, s.DB) - storage.Load(hash) - return storage -} - -// State.storage -//------------------------------------- -// State.nameReg +func (s *State) Save() { + s.mtx.Lock() + defer s.mtx.Unlock() -func (s *State) GetNameRegEntry(name string) *types.NameRegEntry { - _, value := s.nameReg.Get(name) - if value == nil { - return nil + buf, n, err := new(bytes.Buffer), new(int), new(error) + wire.WriteBinary(s, buf, n, err) + if *err != nil { + PanicCrisis(*err) } - entry := value.(*types.NameRegEntry) - return entry.Copy() -} - -func (s *State) UpdateNameRegEntry(entry *types.NameRegEntry) bool { - return s.nameReg.Set(entry.Name, entry) -} - -func (s *State) RemoveNameRegEntry(name string) bool { - _, removed := s.nameReg.Remove(name) - return removed + s.db.Set(stateKey, buf.Bytes()) } -func (s *State) GetNames() merkle.Tree { - return s.nameReg.Copy() -} - -// Set the name reg tree -func (s *State) SetNameReg(nameReg merkle.Tree) { - s.nameReg = nameReg -} - -func NameRegEncoder(o interface{}, w io.Writer, n *int64, err *error) { - wire.WriteBinary(o.(*types.NameRegEntry), w, n, err) -} - -func NameRegDecoder(r io.Reader, n *int64, err *error) interface{} { - return wire.ReadBinary(&types.NameRegEntry{}, r, n, err) -} - -var NameRegCodec = wire.Codec{ - Encode: NameRegEncoder, - Decode: NameRegDecoder, -} - -// State.nameReg -//------------------------------------- - // 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) (*GenesisDoc, *State) { - jsonBlob, err := ioutil.ReadFile(genDocFile) +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 := GenesisDocFromJSON(jsonBlob) - return genDoc, MakeGenesisState(db, genDoc) + genDoc := types.GenesisDocFromJSON(genDocJSON) + return MakeGenesisState(db, genDoc) } -func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { +func MakeGenesisState(db dbm.DB, genDoc *types.GenesisDoc) *State { if len(genDoc.Validators) == 0 { Exit(Fmt("The genesis file has no validators")) } @@ -382,65 +110,12 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { genDoc.GenesisTime = time.Now() } - // Make accounts state tree - accounts := merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) - for _, genAcc := range genDoc.Accounts { - perm := ptypes.ZeroAccountPermissions - if genAcc.Permissions != nil { - perm = *genAcc.Permissions - } - acc := &acm.Account{ - Address: genAcc.Address, - PubKey: nil, - Sequence: 0, - Balance: genAcc.Amount, - Permissions: perm, - } - accounts.Set(acc.Address, acc) - } - - // global permissions are saved as the 0 address - // so they are included in the accounts tree - globalPerms := ptypes.DefaultAccountPermissions - if genDoc.Params != nil && genDoc.Params.GlobalPermissions != nil { - globalPerms = *genDoc.Params.GlobalPermissions - // XXX: make sure the set bits are all true - // Without it the HasPermission() functions will fail - globalPerms.Base.SetBit = ptypes.AllPermFlags - } - - permsAcc := &acm.Account{ - Address: ptypes.GlobalPermissionsAddress, - PubKey: nil, - Sequence: 0, - Balance: 1337, - Permissions: globalPerms, - } - accounts.Set(permsAcc.Address, permsAcc) - - // Make validatorInfos state tree && validators slice - validatorInfos := merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, db) + // Make validators slice validators := make([]*types.Validator, len(genDoc.Validators)) for i, val := range genDoc.Validators { pubKey := val.PubKey address := pubKey.Address() - // Make ValidatorInfo - valInfo := &types.ValidatorInfo{ - Address: address, - PubKey: pubKey, - UnbondTo: make([]*types.TxOutput, len(val.UnbondTo)), - FirstBondHeight: 0, - FirstBondAmount: val.Amount, - } - for i, unbondTo := range val.UnbondTo { - valInfo.UnbondTo[i] = &types.TxOutput{ - Address: unbondTo.Address, - Amount: unbondTo.Amount, - } - } - validatorInfos.Set(address, valInfo) - // Make validator validators[i] = &types.Validator{ Address: address, @@ -449,27 +124,16 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { } } - // Make namereg tree - nameReg := merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) - // TODO: add names, contracts to genesis.json - - // IAVLTrees must be persisted before copy operations. - accounts.Save() - validatorInfos.Save() - nameReg.Save() - return &State{ - DB: db, - ChainID: genDoc.ChainID, - LastBlockHeight: 0, - LastBlockHash: nil, - LastBlockParts: types.PartSetHeader{}, - LastBlockTime: genDoc.GenesisTime, - BondedValidators: types.NewValidatorSet(validators), - LastBondedValidators: types.NewValidatorSet(nil), - UnbondingValidators: types.NewValidatorSet(nil), - accounts: accounts, - validatorInfos: validatorInfos, - nameReg: nameReg, + 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/state_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state_test.go deleted file mode 100644 index c98aac82..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state_test.go +++ /dev/null @@ -1,699 +0,0 @@ -package state - -import ( - "bytes" - "testing" - "time" - - "github.com/tendermint/tendermint/account" - _ "github.com/tendermint/tendermint/config/tendermint_test" - "github.com/tendermint/tendermint/types" -) - -func execTxWithState(state *State, tx types.Tx, runCall bool) error { - cache := NewBlockCache(state) - if err := ExecTx(cache, tx, runCall, nil); err != nil { - return err - } else { - cache.Sync() - return nil - } -} - -func execTxWithStateNewBlock(state *State, tx types.Tx, runCall bool) error { - if err := execTxWithState(state, tx, runCall); err != nil { - return err - } - - state.LastBlockHeight += 1 - return nil -} - -func TestCopyState(t *testing.T) { - // Generate a random state - s0, privAccounts, _ := RandGenesisState(10, true, 1000, 5, true, 1000) - s0Hash := s0.Hash() - if len(s0Hash) == 0 { - t.Error("Expected state hash") - } - - // Check hash of copy - s0Copy := s0.Copy() - if !bytes.Equal(s0Hash, s0Copy.Hash()) { - t.Error("Expected state copy hash to be the same") - } - - // Mutate the original; hash should change. - acc0Address := privAccounts[0].PubKey.Address() - acc := s0.GetAccount(acc0Address) - acc.Balance += 1 - - // The account balance shouldn't have changed yet. - if s0.GetAccount(acc0Address).Balance == acc.Balance { - t.Error("Account balance changed unexpectedly") - } - - // Setting, however, should change the balance. - s0.UpdateAccount(acc) - if s0.GetAccount(acc0Address).Balance != acc.Balance { - t.Error("Account balance wasn't set") - } - - // Now that the state changed, the hash should change too. - if bytes.Equal(s0Hash, s0.Hash()) { - t.Error("Expected state hash to have changed") - } - - // The s0Copy shouldn't have changed though. - if !bytes.Equal(s0Hash, s0Copy.Hash()) { - t.Error("Expected state copy hash to have not changed") - } -} - -func makeBlock(t *testing.T, state *State, validation *types.Validation, txs []types.Tx) *types.Block { - if validation == nil { - validation = &types.Validation{} - } - block := &types.Block{ - Header: &types.Header{ - ChainID: state.ChainID, - Height: state.LastBlockHeight + 1, - Time: state.LastBlockTime.Add(time.Minute), - Fees: 0, - NumTxs: len(txs), - LastBlockHash: state.LastBlockHash, - LastBlockParts: state.LastBlockParts, - StateHash: nil, - }, - LastValidation: validation, - Data: &types.Data{ - Txs: txs, - }, - } - block.FillHeader() - - // Fill in block StateHash - err := state.ComputeBlockStateHash(block) - if err != nil { - t.Error("Error appending initial block:", err) - } - if len(block.Header.StateHash) == 0 { - t.Error("Expected StateHash but got nothing.") - } - - return block -} - -func TestGenesisSaveLoad(t *testing.T) { - - // Generate a state, save & load it. - s0, _, _ := RandGenesisState(10, true, 1000, 5, true, 1000) - - // Make complete block and blockParts - block := makeBlock(t, s0, nil, nil) - blockParts := block.MakePartSet() - - // Now append the block to s0. - err := ExecBlock(s0, block, blockParts.Header()) - if err != nil { - t.Error("Error appending initial block:", err) - } - - // Save s0 - s0.Save() - - // Sanity check s0 - //s0.DB.(*dbm.MemDB).Print() - if s0.BondedValidators.TotalVotingPower() == 0 { - t.Error("s0 BondedValidators TotalVotingPower should not be 0") - } - if s0.LastBlockHeight != 1 { - t.Error("s0 LastBlockHeight should be 1, got", s0.LastBlockHeight) - } - - // Load s1 - s1 := LoadState(s0.DB) - - // Compare height & blockHash - if s0.LastBlockHeight != s1.LastBlockHeight { - t.Error("LastBlockHeight mismatch") - } - if !bytes.Equal(s0.LastBlockHash, s1.LastBlockHash) { - t.Error("LastBlockHash mismatch") - } - - // Compare state merkle trees - if s0.BondedValidators.Size() != s1.BondedValidators.Size() { - t.Error("BondedValidators Size mismatch") - } - if s0.BondedValidators.TotalVotingPower() != s1.BondedValidators.TotalVotingPower() { - t.Error("BondedValidators TotalVotingPower mismatch") - } - if !bytes.Equal(s0.BondedValidators.Hash(), s1.BondedValidators.Hash()) { - t.Error("BondedValidators hash mismatch") - } - if s0.UnbondingValidators.Size() != s1.UnbondingValidators.Size() { - t.Error("UnbondingValidators Size mismatch") - } - if s0.UnbondingValidators.TotalVotingPower() != s1.UnbondingValidators.TotalVotingPower() { - t.Error("UnbondingValidators TotalVotingPower mismatch") - } - if !bytes.Equal(s0.UnbondingValidators.Hash(), s1.UnbondingValidators.Hash()) { - t.Error("UnbondingValidators hash mismatch") - } - if !bytes.Equal(s0.accounts.Hash(), s1.accounts.Hash()) { - t.Error("Accounts mismatch") - } - if !bytes.Equal(s0.validatorInfos.Hash(), s1.validatorInfos.Hash()) { - t.Error("Accounts mismatch") - } -} - -func TestTxSequence(t *testing.T) { - - state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000) - acc0 := state.GetAccount(privAccounts[0].PubKey.Address()) - acc0PubKey := privAccounts[0].PubKey - acc1 := state.GetAccount(privAccounts[1].PubKey.Address()) - - // Test a variety of sequence numbers for the tx. - // The tx should only pass when i == 1. - for i := -1; i < 3; i++ { - sequence := acc0.Sequence + i - tx := types.NewSendTx() - tx.AddInputWithNonce(acc0PubKey, 1, sequence) - tx.AddOutput(acc1.Address, 1) - tx.Inputs[0].Signature = privAccounts[0].Sign(state.ChainID, tx) - stateCopy := state.Copy() - err := execTxWithState(stateCopy, tx, true) - if i == 1 { - // Sequence is good. - if err != nil { - t.Errorf("Expected good sequence to pass: %v", err) - } - // Check acc.Sequence. - newAcc0 := stateCopy.GetAccount(acc0.Address) - if newAcc0.Sequence != sequence { - t.Errorf("Expected account sequence to change to %v, got %v", - sequence, newAcc0.Sequence) - } - } else { - // Sequence is bad. - if err == nil { - t.Errorf("Expected bad sequence to fail") - } - // Check acc.Sequence. (shouldn't have changed) - newAcc0 := stateCopy.GetAccount(acc0.Address) - if newAcc0.Sequence != acc0.Sequence { - t.Errorf("Expected account sequence to not change from %v, got %v", - acc0.Sequence, newAcc0.Sequence) - } - } - } -} - -func TestNameTxs(t *testing.T) { - state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000) - - types.MinNameRegistrationPeriod = 5 - startingBlock := state.LastBlockHeight - - // try some bad names. these should all fail - names := []string{"", "\n", "123#$%", "\x00", string([]byte{20, 40, 60, 80}), "baffledbythespectacleinallofthisyouseeehesaidwithouteyessurprised", "no spaces please"} - data := "something about all this just doesn't feel right." - fee := int64(1000) - numDesiredBlocks := 5 - for _, name := range names { - amt := fee + int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data) - tx, _ := types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[0]) - - if err := execTxWithState(state, tx, true); err == nil { - t.Fatalf("Expected invalid name error from %s", name) - } - } - - // try some bad data. these should all fail - name := "hold_it_chum" - datas := []string{"cold&warm", "!@#$%^&*()", "<<<>>>>", "because why would you ever need a ~ or a & or even a % in a json file? make your case and we'll talk"} - for _, data := range datas { - amt := fee + int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data) - tx, _ := types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[0]) - - if err := execTxWithState(state, tx, true); err == nil { - t.Fatalf("Expected invalid data error from %s", data) - } - } - - validateEntry := func(t *testing.T, entry *types.NameRegEntry, name, data string, addr []byte, expires int) { - - if entry == nil { - t.Fatalf("Could not find name %s", name) - } - if bytes.Compare(entry.Owner, addr) != 0 { - t.Fatalf("Wrong owner. Got %X expected %X", entry.Owner, addr) - } - if data != entry.Data { - t.Fatalf("Wrong data. Got %s expected %s", entry.Data, data) - } - if name != entry.Name { - t.Fatalf("Wrong name. Got %s expected %s", entry.Name, name) - } - if expires != entry.Expires { - t.Fatalf("Wrong expiry. Got %d, expected %d", entry.Expires, expires) - } - } - - // try a good one, check data, owner, expiry - name = "@looking_good/karaoke_bar.broadband" - data = "on this side of neptune there are 1234567890 people: first is OMNIVORE+-3. Or is it. Ok this is pretty restrictive. No exclamations :(. Faces tho :')" - amt := fee + int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data) - tx, _ := types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[0]) - if err := execTxWithState(state, tx, true); err != nil { - t.Fatal(err) - } - entry := state.GetNameRegEntry(name) - validateEntry(t, entry, name, data, privAccounts[0].Address, startingBlock+numDesiredBlocks) - - // fail to update it as non-owner, in same block - tx, _ = types.NewNameTx(state, privAccounts[1].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[1]) - if err := execTxWithState(state, tx, true); err == nil { - t.Fatal("Expected error") - } - - // update it as owner, just to increase expiry, in same block - // NOTE: we have to resend the data or it will clear it (is this what we want?) - tx, _ = types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[0]) - if err := execTxWithStateNewBlock(state, tx, true); err != nil { - t.Fatal(err) - } - entry = state.GetNameRegEntry(name) - validateEntry(t, entry, name, data, privAccounts[0].Address, startingBlock+numDesiredBlocks*2) - - // update it as owner, just to increase expiry, in next block - tx, _ = types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[0]) - if err := execTxWithStateNewBlock(state, tx, true); err != nil { - t.Fatal(err) - } - entry = state.GetNameRegEntry(name) - validateEntry(t, entry, name, data, privAccounts[0].Address, startingBlock+numDesiredBlocks*3) - - // fail to update it as non-owner - state.LastBlockHeight = entry.Expires - 1 - tx, _ = types.NewNameTx(state, privAccounts[1].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[1]) - if err := execTxWithState(state, tx, true); err == nil { - t.Fatal("Expected error") - } - - // once expires, non-owner succeeds - state.LastBlockHeight = entry.Expires - tx, _ = types.NewNameTx(state, privAccounts[1].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[1]) - if err := execTxWithState(state, tx, true); err != nil { - t.Fatal(err) - } - entry = state.GetNameRegEntry(name) - validateEntry(t, entry, name, data, privAccounts[1].Address, state.LastBlockHeight+numDesiredBlocks) - - // update it as new owner, with new data (longer), but keep the expiry! - data = "In the beginning there was no thing, not even the beginning. It hadn't been here, no there, nor for that matter anywhere, not especially because it had not to even exist, let alone to not. Nothing especially odd about that." - oldCredit := amt - fee - numDesiredBlocks = 10 - amt = fee + (int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data) - oldCredit) - tx, _ = types.NewNameTx(state, privAccounts[1].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[1]) - if err := execTxWithState(state, tx, true); err != nil { - t.Fatal(err) - } - entry = state.GetNameRegEntry(name) - validateEntry(t, entry, name, data, privAccounts[1].Address, state.LastBlockHeight+numDesiredBlocks) - - // test removal - amt = fee - data = "" - tx, _ = types.NewNameTx(state, privAccounts[1].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[1]) - if err := execTxWithStateNewBlock(state, tx, true); err != nil { - t.Fatal(err) - } - entry = state.GetNameRegEntry(name) - if entry != nil { - t.Fatal("Expected removed entry to be nil") - } - - // create entry by key0, - // test removal by key1 after expiry - name = "looking_good/karaoke_bar" - data = "some data" - amt = fee + int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data) - tx, _ = types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[0]) - if err := execTxWithState(state, tx, true); err != nil { - t.Fatal(err) - } - entry = state.GetNameRegEntry(name) - validateEntry(t, entry, name, data, privAccounts[0].Address, state.LastBlockHeight+numDesiredBlocks) - state.LastBlockHeight = entry.Expires - - amt = fee - data = "" - tx, _ = types.NewNameTx(state, privAccounts[1].PubKey, name, data, amt, fee) - tx.Sign(state.ChainID, privAccounts[1]) - if err := execTxWithStateNewBlock(state, tx, true); err != nil { - t.Fatal(err) - } - entry = state.GetNameRegEntry(name) - if entry != nil { - t.Fatal("Expected removed entry to be nil") - } -} - -// TODO: test overflows. -// TODO: test for unbonding validators. -func TestTxs(t *testing.T) { - - state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000) - - //val0 := state.GetValidatorInfo(privValidators[0].Address) - acc0 := state.GetAccount(privAccounts[0].PubKey.Address()) - acc0PubKey := privAccounts[0].PubKey - acc1 := state.GetAccount(privAccounts[1].PubKey.Address()) - - // SendTx. - { - state := state.Copy() - tx := &types.SendTx{ - Inputs: []*types.TxInput{ - &types.TxInput{ - Address: acc0.Address, - Amount: 1, - Sequence: acc0.Sequence + 1, - PubKey: acc0PubKey, - }, - }, - Outputs: []*types.TxOutput{ - &types.TxOutput{ - Address: acc1.Address, - Amount: 1, - }, - }, - } - - tx.Inputs[0].Signature = privAccounts[0].Sign(state.ChainID, tx) - err := execTxWithState(state, tx, true) - if err != nil { - t.Errorf("Got error in executing send transaction, %v", err) - } - newAcc0 := state.GetAccount(acc0.Address) - if acc0.Balance-1 != newAcc0.Balance { - t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v", - acc0.Balance-1, newAcc0.Balance) - } - newAcc1 := state.GetAccount(acc1.Address) - if acc1.Balance+1 != newAcc1.Balance { - t.Errorf("Unexpected newAcc1 balance. Expected %v, got %v", - acc1.Balance+1, newAcc1.Balance) - } - } - - // CallTx. Just runs through it and checks the transfer. See vm, rpc tests for more - { - state := state.Copy() - newAcc1 := state.GetAccount(acc1.Address) - newAcc1.Code = []byte{0x60} - state.UpdateAccount(newAcc1) - tx := &types.CallTx{ - Input: &types.TxInput{ - Address: acc0.Address, - Amount: 1, - Sequence: acc0.Sequence + 1, - PubKey: acc0PubKey, - }, - Address: acc1.Address, - GasLimit: 10, - } - - tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx) - err := execTxWithState(state, tx, true) - if err != nil { - t.Errorf("Got error in executing call transaction, %v", err) - } - newAcc0 := state.GetAccount(acc0.Address) - if acc0.Balance-1 != newAcc0.Balance { - t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v", - acc0.Balance-1, newAcc0.Balance) - } - newAcc1 = state.GetAccount(acc1.Address) - if acc1.Balance+1 != newAcc1.Balance { - t.Errorf("Unexpected newAcc1 balance. Expected %v, got %v", - acc1.Balance+1, newAcc1.Balance) - } - } - - // NameTx. - { - entryName := "satoshi" - entryData := ` -A purely peer-to-peer version of electronic cash would allow online -payments to be sent directly from one party to another without going through a -financial institution. Digital signatures provide part of the solution, but the main -benefits are lost if a trusted third party is still required to prevent double-spending. -We propose a solution to the double-spending problem using a peer-to-peer network. -The network timestamps transactions by hashing them into an ongoing chain of -hash-based proof-of-work, forming a record that cannot be changed without redoing -the proof-of-work. The longest chain not only serves as proof of the sequence of -events witnessed, but proof that it came from the largest pool of CPU power. As -long as a majority of CPU power is controlled by nodes that are not cooperating to -attack the network, they'll generate the longest chain and outpace attackers. The -network itself requires minimal structure. Messages are broadcast on a best effort -basis, and nodes can leave and rejoin the network at will, accepting the longest -proof-of-work chain as proof of what happened while they were gone ` - entryAmount := int64(10000) - - state := state.Copy() - tx := &types.NameTx{ - Input: &types.TxInput{ - Address: acc0.Address, - Amount: entryAmount, - Sequence: acc0.Sequence + 1, - PubKey: acc0PubKey, - }, - Name: entryName, - Data: entryData, - } - - tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx) - err := execTxWithState(state, tx, true) - if err != nil { - t.Errorf("Got error in executing call transaction, %v", err) - } - newAcc0 := state.GetAccount(acc0.Address) - if acc0.Balance-entryAmount != newAcc0.Balance { - t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v", - acc0.Balance-entryAmount, newAcc0.Balance) - } - entry := state.GetNameRegEntry(entryName) - if entry == nil { - t.Errorf("Expected an entry but got nil") - } - if entry.Data != entryData { - t.Errorf("Wrong data stored") - } - - // test a bad string - tx.Data = string([]byte{0, 1, 2, 3, 127, 128, 129, 200, 251}) - tx.Input.Sequence += 1 - tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx) - err = execTxWithState(state, tx, true) - if _, ok := err.(types.ErrTxInvalidString); !ok { - t.Errorf("Expected invalid string error. Got: %s", err.Error()) - } - } - - // BondTx. - { - state := state.Copy() - tx := &types.BondTx{ - PubKey: acc0PubKey.(account.PubKeyEd25519), - Inputs: []*types.TxInput{ - &types.TxInput{ - Address: acc0.Address, - Amount: 1, - Sequence: acc0.Sequence + 1, - PubKey: acc0PubKey, - }, - }, - UnbondTo: []*types.TxOutput{ - &types.TxOutput{ - Address: acc0.Address, - Amount: 1, - }, - }, - } - tx.Signature = privAccounts[0].Sign(state.ChainID, tx).(account.SignatureEd25519) - tx.Inputs[0].Signature = privAccounts[0].Sign(state.ChainID, tx) - err := execTxWithState(state, tx, true) - if err != nil { - t.Errorf("Got error in executing bond transaction, %v", err) - } - newAcc0 := state.GetAccount(acc0.Address) - if newAcc0.Balance != acc0.Balance-1 { - t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v", - acc0.Balance-1, newAcc0.Balance) - } - _, acc0Val := state.BondedValidators.GetByAddress(acc0.Address) - if acc0Val == nil { - t.Errorf("acc0Val not present") - } - if acc0Val.BondHeight != state.LastBlockHeight+1 { - t.Errorf("Unexpected bond height. Expected %v, got %v", - state.LastBlockHeight, acc0Val.BondHeight) - } - if acc0Val.VotingPower != 1 { - t.Errorf("Unexpected voting power. Expected %v, got %v", - acc0Val.VotingPower, acc0.Balance) - } - if acc0Val.Accum != 0 { - t.Errorf("Unexpected accum. Expected 0, got %v", - acc0Val.Accum) - } - } - - // TODO UnbondTx. - -} - -func TestSuicide(t *testing.T) { - - state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000) - - acc0 := state.GetAccount(privAccounts[0].PubKey.Address()) - acc0PubKey := privAccounts[0].PubKey - acc1 := state.GetAccount(privAccounts[1].PubKey.Address()) - acc2 := state.GetAccount(privAccounts[2].Address) - sendingAmount, refundedBalance, oldBalance := int64(1), acc1.Balance, acc2.Balance - - newAcc1 := state.GetAccount(acc1.Address) - - // store 0x1 at 0x1, push an address, then suicide :) - contractCode := []byte{0x60, 0x01, 0x60, 0x01, 0x55, 0x73} - contractCode = append(contractCode, acc2.Address...) - contractCode = append(contractCode, 0xff) - newAcc1.Code = contractCode - state.UpdateAccount(newAcc1) - - // send call tx with no data, cause suicide - tx := types.NewCallTxWithNonce(acc0PubKey, acc1.Address, nil, sendingAmount, 1000, 0, acc0.Sequence+1) - tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx) - - // we use cache instead of execTxWithState so we can run the tx twice - cache := NewBlockCache(state) - if err := ExecTx(cache, tx, true, nil); err != nil { - t.Errorf("Got error in executing call transaction, %v", err) - } - - // if we do it again, we won't get an error, but the suicide - // shouldn't happen twice and the caller should lose fee - tx.Input.Sequence += 1 - tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx) - if err := ExecTx(cache, tx, true, nil); err != nil { - t.Errorf("Got error in executing call transaction, %v", err) - } - - // commit the block - cache.Sync() - - // acc2 should receive the sent funds and the contracts balance - newAcc2 := state.GetAccount(acc2.Address) - newBalance := sendingAmount + refundedBalance + oldBalance - if newAcc2.Balance != newBalance { - t.Errorf("Unexpected newAcc2 balance. Expected %v, got %v", - newAcc2.Balance, newBalance) - } - newAcc1 = state.GetAccount(acc1.Address) - if newAcc1 != nil { - t.Errorf("Expected account to be removed") - } - -} - -func TestAddValidator(t *testing.T) { - - // Generate a state, save & load it. - s0, privAccounts, privValidators := RandGenesisState(10, false, 1000, 1, false, 1000) - - // The first privAccount will become a validator - acc0 := privAccounts[0] - bondTx := &types.BondTx{ - PubKey: acc0.PubKey.(account.PubKeyEd25519), - Inputs: []*types.TxInput{ - &types.TxInput{ - Address: acc0.Address, - Amount: 1000, - Sequence: 1, - PubKey: acc0.PubKey, - }, - }, - UnbondTo: []*types.TxOutput{ - &types.TxOutput{ - Address: acc0.Address, - Amount: 1000, - }, - }, - } - bondTx.Signature = acc0.Sign(s0.ChainID, bondTx).(account.SignatureEd25519) - bondTx.Inputs[0].Signature = acc0.Sign(s0.ChainID, bondTx) - - // Make complete block and blockParts - block0 := makeBlock(t, s0, nil, []types.Tx{bondTx}) - block0Parts := block0.MakePartSet() - - // Sanity check - if s0.BondedValidators.Size() != 1 { - t.Error("Expected there to be 1 validators before bondTx") - } - - // Now append the block to s0. - err := ExecBlock(s0, block0, block0Parts.Header()) - if err != nil { - t.Error("Error appending initial block:", err) - } - - // Must save before further modification - s0.Save() - - // Test new validator set - if s0.BondedValidators.Size() != 2 { - t.Error("Expected there to be 2 validators after bondTx") - } - - // The validation for the next block should only require 1 signature - // (the new validator wasn't active for block0) - precommit0 := &types.Vote{ - Height: 1, - Round: 0, - Type: types.VoteTypePrecommit, - BlockHash: block0.Hash(), - BlockPartsHeader: block0Parts.Header(), - } - privValidators[0].SignVote(s0.ChainID, precommit0) - - block1 := makeBlock(t, s0, - &types.Validation{ - Precommits: []*types.Vote{ - precommit0, - }, - }, nil, - ) - block1Parts := block1.MakePartSet() - err = ExecBlock(s0, block1, block1Parts.Header()) - if err != nil { - t.Error("Error appending secondary block:", err) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/test.go deleted file mode 100644 index 90d5003d..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/test.go +++ /dev/null @@ -1,76 +0,0 @@ -package state - -import ( - "sort" - "time" - - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - dbm "github.com/tendermint/tendermint/db" - ptypes "github.com/tendermint/tendermint/permission/types" - . "github.com/tendermint/tendermint/state/types" - "github.com/tendermint/tendermint/types" -) - -func RandAccount(randBalance bool, minBalance int64) (*acm.Account, *acm.PrivAccount) { - privAccount := acm.GenPrivAccount() - perms := ptypes.DefaultAccountPermissions - acc := &acm.Account{ - Address: privAccount.PubKey.Address(), - PubKey: privAccount.PubKey, - Sequence: RandInt(), - Balance: minBalance, - Permissions: perms, - } - if randBalance { - acc.Balance += int64(RandUint32()) - } - return acc, privAccount -} - -func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numValidators int, randBonded bool, minBonded int64) (*GenesisDoc, []*acm.PrivAccount, []*types.PrivValidator) { - accounts := make([]GenesisAccount, numAccounts) - privAccounts := make([]*acm.PrivAccount, numAccounts) - defaultPerms := ptypes.DefaultAccountPermissions - for i := 0; i < numAccounts; i++ { - account, privAccount := RandAccount(randBalance, minBalance) - accounts[i] = GenesisAccount{ - Address: account.Address, - Amount: account.Balance, - Permissions: &defaultPerms, // This will get copied into each state.Account. - } - privAccounts[i] = privAccount - } - validators := make([]GenesisValidator, numValidators) - privValidators := make([]*types.PrivValidator, numValidators) - for i := 0; i < numValidators; i++ { - valInfo, _, privVal := types.RandValidator(randBonded, minBonded) - validators[i] = GenesisValidator{ - PubKey: valInfo.PubKey, - Amount: valInfo.FirstBondAmount, - UnbondTo: []BasicAccount{ - { - Address: valInfo.PubKey.Address(), - Amount: valInfo.FirstBondAmount, - }, - }, - } - privValidators[i] = privVal - } - sort.Sort(types.PrivValidatorsByAddress(privValidators)) - return &GenesisDoc{ - GenesisTime: time.Now(), - ChainID: "tendermint_test", - Accounts: accounts, - Validators: validators, - }, privAccounts, privValidators - -} - -func RandGenesisState(numAccounts int, randBalance bool, minBalance int64, numValidators int, randBonded bool, minBonded int64) (*State, []*acm.PrivAccount, []*types.PrivValidator) { - db := dbm.NewMemDB() - genDoc, privAccounts, privValidators := RandGenesisDoc(numAccounts, randBalance, minBalance, numValidators, randBonded, minBonded) - s0 := MakeGenesisState(db, genDoc) - s0.Save() - return s0, privAccounts, privValidators -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/tx_cache.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/tx_cache.go deleted file mode 100644 index 8afd1cd0..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/tx_cache.go +++ /dev/null @@ -1,198 +0,0 @@ -package state - -import ( - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - ptypes "github.com/tendermint/tendermint/permission/types" // for GlobalPermissionAddress ... - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/vm" -) - -type TxCache struct { - backend *BlockCache - accounts map[Word256]vmAccountInfo - storages map[Tuple256]Word256 -} - -func NewTxCache(backend *BlockCache) *TxCache { - return &TxCache{ - backend: backend, - accounts: make(map[Word256]vmAccountInfo), - storages: make(map[Tuple256]Word256), - } -} - -//------------------------------------- -// TxCache.account - -func (cache *TxCache) GetAccount(addr Word256) *vm.Account { - acc, removed := cache.accounts[addr].unpack() - if removed { - return nil - } else if acc == nil { - acc2 := cache.backend.GetAccount(addr.Postfix(20)) - if acc2 != nil { - return toVMAccount(acc2) - } - } - return acc -} - -func (cache *TxCache) UpdateAccount(acc *vm.Account) { - addr := acc.Address - _, removed := cache.accounts[addr].unpack() - if removed { - PanicSanity("UpdateAccount on a removed account") - } - cache.accounts[addr] = vmAccountInfo{acc, false} -} - -func (cache *TxCache) RemoveAccount(acc *vm.Account) { - addr := acc.Address - _, removed := cache.accounts[addr].unpack() - if removed { - PanicSanity("RemoveAccount on a removed account") - } - cache.accounts[addr] = vmAccountInfo{acc, true} -} - -// Creates a 20 byte address and bumps the creator's nonce. -func (cache *TxCache) CreateAccount(creator *vm.Account) *vm.Account { - - // Generate an address - nonce := creator.Nonce - creator.Nonce += 1 - - addr := LeftPadWord256(NewContractAddress(creator.Address.Postfix(20), int(nonce))) - - // Create account from address. - account, removed := cache.accounts[addr].unpack() - if removed || account == nil { - account = &vm.Account{ - Address: addr, - Balance: 0, - Code: nil, - Nonce: 0, - Permissions: cache.GetAccount(ptypes.GlobalPermissionsAddress256).Permissions, - Other: vmAccountOther{ - PubKey: nil, - StorageRoot: nil, - }, - } - cache.accounts[addr] = vmAccountInfo{account, false} - return account - } else { - // either we've messed up nonce handling, or sha3 is broken - PanicSanity(Fmt("Could not create account, address already exists: %X", addr)) - return nil - } -} - -// TxCache.account -//------------------------------------- -// TxCache.storage - -func (cache *TxCache) GetStorage(addr Word256, key Word256) Word256 { - // Check cache - value, ok := cache.storages[Tuple256{addr, key}] - if ok { - return value - } - - // Load from backend - return cache.backend.GetStorage(addr, key) -} - -// NOTE: Set value to zero to removed from the trie. -func (cache *TxCache) SetStorage(addr Word256, key Word256, value Word256) { - _, removed := cache.accounts[addr].unpack() - if removed { - PanicSanity("SetStorage() on a removed account") - } - cache.storages[Tuple256{addr, key}] = value -} - -// TxCache.storage -//------------------------------------- - -// These updates do not have to be in deterministic order, -// the backend is responsible for ordering updates. -func (cache *TxCache) Sync() { - - // Remove or update storage - for addrKey, value := range cache.storages { - addr, key := Tuple256Split(addrKey) - cache.backend.SetStorage(addr, key, value) - } - - // Remove or update accounts - for addr, accInfo := range cache.accounts { - acc, removed := accInfo.unpack() - if removed { - cache.backend.RemoveAccount(addr.Postfix(20)) - } else { - cache.backend.UpdateAccount(toStateAccount(acc)) - } - } -} - -//----------------------------------------------------------------------------- - -// Convenience function to return address of new contract -func NewContractAddress(caller []byte, nonce int) []byte { - return types.NewContractAddress(caller, nonce) -} - -// Converts backend.Account to vm.Account struct. -func toVMAccount(acc *acm.Account) *vm.Account { - return &vm.Account{ - Address: LeftPadWord256(acc.Address), - Balance: acc.Balance, - Code: acc.Code, // This is crazy. - Nonce: int64(acc.Sequence), - Permissions: acc.Permissions, // Copy - Other: vmAccountOther{ - PubKey: acc.PubKey, - StorageRoot: acc.StorageRoot, - }, - } -} - -// Converts vm.Account to backend.Account struct. -func toStateAccount(acc *vm.Account) *acm.Account { - var pubKey acm.PubKey - var storageRoot []byte - if acc.Other != nil { - pubKey, storageRoot = acc.Other.(vmAccountOther).unpack() - } - - return &acm.Account{ - Address: acc.Address.Postfix(20), - PubKey: pubKey, - Balance: acc.Balance, - Code: acc.Code, - Sequence: int(acc.Nonce), - StorageRoot: storageRoot, - Permissions: acc.Permissions, // Copy - } -} - -// Everything in acmAccount that doesn't belong in -// exported vmAccount fields. -type vmAccountOther struct { - PubKey acm.PubKey - StorageRoot []byte -} - -func (accOther vmAccountOther) unpack() (acm.PubKey, []byte) { - return accOther.PubKey, accOther.StorageRoot -} - -type vmAccountInfo struct { - account *vm.Account - removed bool -} - -func (accInfo vmAccountInfo) unpack() (*vm.Account, bool) { - return accInfo.account, accInfo.removed -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/tx_cache_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/tx_cache_test.go deleted file mode 100644 index c1a2d057..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/tx_cache_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package state - -import ( - "bytes" - "testing" - - "github.com/tendermint/tendermint/wire" -) - -func TestStateToFromVMAccount(t *testing.T) { - acmAcc1, _ := RandAccount(true, 456) - vmAcc := toVMAccount(acmAcc1) - acmAcc2 := toStateAccount(vmAcc) - - acmAcc1Bytes := wire.BinaryBytes(acmAcc1) - acmAcc2Bytes := wire.BinaryBytes(acmAcc2) - if !bytes.Equal(acmAcc1Bytes, acmAcc2Bytes) { - t.Errorf("Unexpected account wire bytes\n%X vs\n%X", - acmAcc1Bytes, acmAcc2Bytes) - } - -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/types/genesis.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/types/genesis.go deleted file mode 100644 index c956286f..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/types/genesis.go +++ /dev/null @@ -1,61 +0,0 @@ -package types - -import ( - "time" - - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - ptypes "github.com/tendermint/tendermint/permission/types" - "github.com/tendermint/tendermint/wire" -) - -//------------------------------------------------------------ -// we store the gendoc in the db - -var GenDocKey = []byte("GenDocKey") - -//------------------------------------------------------------ -// core types for a genesis definition - -type BasicAccount struct { - Address []byte `json:"address"` - Amount int64 `json:"amount"` -} - -type GenesisAccount struct { - Address []byte `json:"address"` - Amount int64 `json:"amount"` - Name string `json:"name"` - Permissions *ptypes.AccountPermissions `json:"permissions"` -} - -type GenesisValidator struct { - PubKey acm.PubKeyEd25519 `json:"pub_key"` - Amount int64 `json:"amount"` - Name string `json:"name"` - UnbondTo []BasicAccount `json:"unbond_to"` -} - -type GenesisParams struct { - GlobalPermissions *ptypes.AccountPermissions `json:"global_permissions"` -} - -type GenesisDoc struct { - GenesisTime time.Time `json:"genesis_time"` - ChainID string `json:"chain_id"` - Params *GenesisParams `json:"params"` - Accounts []GenesisAccount `json:"accounts"` - Validators []GenesisValidator `json:"validators"` -} - -//------------------------------------------------------------ -// 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/state/wtf b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf new file mode 100644 index 00000000..0e10d8a5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf @@ -0,0 +1,68 @@ +[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/block.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go index 718b6a5a..8b68b96f 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go @@ -7,12 +7,13 @@ import ( "strings" "time" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/merkle" - "github.com/tendermint/tendermint/wire" + . "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"` @@ -56,7 +57,7 @@ func (b *Block) ValidateBasic(chainID string, lastBlockHeight int, lastBlockHash 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 StateHash is validated later. + // NOTE: the AppHash and ValidatorsHash are validated later. return nil } @@ -66,8 +67,7 @@ func (b *Block) FillHeader() { } // Computes and returns the block hash. -// If the block is incomplete (e.g. missing Header.StateHash) -// then the hash is nil, to prevent the usage of that 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 @@ -132,12 +132,13 @@ type Header struct { LastBlockParts PartSetHeader `json:"last_block_parts"` LastValidationHash []byte `json:"last_validation_hash"` DataHash []byte `json:"data_hash"` - StateHash []byte `json:"state_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.StateHash) == 0 { + if len(h.ValidatorsHash) == 0 { return nil } return merkle.SimpleHashFromMap(map[string]interface{}{ @@ -150,7 +151,8 @@ func (h *Header) Hash() []byte { "LastBlockParts": h.LastBlockParts, "LastValidation": h.LastValidationHash, "Data": h.DataHash, - "State": h.StateHash, + "Validators": h.ValidatorsHash, + "App": h.AppHash, }) } @@ -164,9 +166,12 @@ func (h *Header) StringIndented(indent string) string { %s Time: %v %s Fees: %v %s NumTxs: %v -%s LastBlockHash: %X +%s LastBlock: %X %s LastBlockParts: %v -%s StateHash: %X +%s LastValidation: %X +%s Data: %X +%s Validators: %X +%s App: %X %s}#%X`, indent, h.ChainID, indent, h.Height, @@ -175,7 +180,10 @@ func (h *Header) StringIndented(indent string) string { indent, h.NumTxs, indent, h.LastBlockHash, indent, h.LastBlockParts, - indent, h.StateHash, + indent, h.LastValidationHash, + indent, h.DataHash, + indent, h.ValidatorsHash, + indent, h.AppHash, indent, h.Hash()) } @@ -322,11 +330,11 @@ type Data struct { func (data *Data) Hash() []byte { if data.hash == nil { - bs := make([]interface{}, len(data.Txs)) + txs := make([]interface{}, len(data.Txs)) for i, tx := range data.Txs { - bs[i] = acm.SignBytes(config.GetString("chain_id"), tx) + txs[i] = tx } - data.hash = merkle.SimpleHashFromBinaries(bs) // NOTE: leaves are TxIDs. + data.hash = merkle.SimpleHashFromBinaries(txs) // NOTE: leaves are TxIDs. } return data.hash } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go index 915778dd..e8f96401 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go @@ -1,7 +1,7 @@ package types import ( - cfg "github.com/tendermint/tendermint/config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go index 5d717734..67510baa 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go @@ -1,37 +1,31 @@ package types import ( - "fmt" "time" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" ) // Functions to generate eventId strings -func EventStringAccInput(addr []byte) string { return fmt.Sprintf("Acc/%X/Input", addr) } -func EventStringAccOutput(addr []byte) string { return fmt.Sprintf("Acc/%X/Output", addr) } -func EventStringAccCall(addr []byte) string { return fmt.Sprintf("Acc/%X/Call", addr) } -func EventStringLogEvent(addr []byte) string { return fmt.Sprintf("Log/%X", addr) } -func EventStringPermissions(name string) string { return fmt.Sprintf("Permissions/%s", name) } -func EventStringNameReg(name string) string { return fmt.Sprintf("NameReg/%s", name) } -func EventStringBond() string { return "Bond" } -func EventStringUnbond() string { return "Unbond" } -func EventStringRebond() string { return "Rebond" } -func EventStringDupeout() string { return "Dupeout" } -func EventStringNewBlock() string { return "NewBlock" } -func EventStringFork() string { return "Fork" } - -func EventStringNewRound() string { return fmt.Sprintf("NewRound") } -func EventStringTimeoutPropose() string { return fmt.Sprintf("TimeoutPropose") } -func EventStringCompleteProposal() string { return fmt.Sprintf("CompleteProposal") } -func EventStringPolka() string { return fmt.Sprintf("Polka") } -func EventStringUnlock() string { return fmt.Sprintf("Unlock") } -func EventStringLock() string { return fmt.Sprintf("Lock") } -func EventStringRelock() string { return fmt.Sprintf("Relock") } -func EventStringTimeoutWait() string { return fmt.Sprintf("TimeoutWait") } -func EventStringVote() string { return fmt.Sprintf("Vote") } +// 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" } //---------------------------------------- @@ -39,8 +33,7 @@ const ( EventDataTypeNewBlock = byte(0x01) EventDataTypeFork = byte(0x02) EventDataTypeTx = byte(0x03) - EventDataTypeCall = byte(0x04) - EventDataTypeLog = byte(0x05) + EventDataTypeApp = byte(0x04) // Custom app event EventDataTypeRoundState = byte(0x11) EventDataTypeVote = byte(0x12) @@ -55,8 +48,7 @@ var _ = wire.RegisterInterface( wire.ConcreteType{EventDataNewBlock{}, EventDataTypeNewBlock}, // wire.ConcreteType{EventDataFork{}, EventDataTypeFork }, wire.ConcreteType{EventDataTx{}, EventDataTypeTx}, - wire.ConcreteType{EventDataCall{}, EventDataTypeCall}, - wire.ConcreteType{EventDataLog{}, EventDataTypeLog}, + wire.ConcreteType{EventDataApp{}, EventDataTypeApp}, wire.ConcreteType{EventDataRoundState{}, EventDataTypeRoundState}, wire.ConcreteType{EventDataVote{}, EventDataTypeVote}, ) @@ -68,36 +60,16 @@ type EventDataNewBlock struct { Block *Block `json:"block"` } -// All txs fire EventDataTx, but only CallTx might have Return or Exception +// All txs fire EventDataTx type EventDataTx struct { Tx Tx `json:"tx"` Return []byte `json:"return"` Exception string `json:"exception"` } -// EventDataCall fires when we call a contract, and when a contract calls another contract -type EventDataCall struct { - CallData *CallData `json:"call_data"` - Origin []byte `json:"origin"` - TxID []byte `json:"tx_id"` - Return []byte `json:"return"` - Exception string `json:"exception"` -} - -type CallData struct { - Caller []byte `json:"caller"` - Callee []byte `json:"callee"` - Data []byte `json:"data"` - Value int64 `json:"value"` - Gas int64 `json:"gas"` -} - -// EventDataLog fires when a contract executes the LOG opcode -type EventDataLog struct { - Address Word256 `json:"address"` - Topics []Word256 `json:"topics"` - Data []byte `json:"data"` - Height int64 `json:"height"` +type EventDataApp struct { + Key string `json:"key"` + Data []byte `json:"bytes"` } // We fire the most recent round state that led to the event @@ -125,7 +97,6 @@ type EventDataVote struct { func (_ EventDataNewBlock) AssertIsEventData() {} func (_ EventDataTx) AssertIsEventData() {} -func (_ EventDataCall) AssertIsEventData() {} -func (_ EventDataLog) 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 new file mode 100644 index 00000000..0966cf23 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/genesis.go @@ -0,0 +1,48 @@ +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 new file mode 100644 index 00000000..90591b95 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/keys.go @@ -0,0 +1,6 @@ +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 index fed0c559..1f22008f 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/log.go @@ -1,7 +1,7 @@ package types import ( - "github.com/tendermint/tendermint/logger" + "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 new file mode 100644 index 0000000000000000000000000000000000000000..d4401eddd73a489b7f045232f80c08e4c7f2dc41 GIT binary patch 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-* literal 0 HcmV?d00001 diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/names.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/names.go deleted file mode 100644 index 2f4c8ff8..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/names.go +++ /dev/null @@ -1,55 +0,0 @@ -package types - -import ( - "regexp" -) - -var ( - MinNameRegistrationPeriod int = 5 - - // NOTE: base costs and validity checks are here so clients - // can use them without importing state - - // cost for storing a name for a block is - // CostPerBlock*CostPerByte*(len(data) + 32) - NameByteCostMultiplier int64 = 1 - NameBlockCostMultiplier int64 = 1 - - MaxNameLength = 64 - MaxDataLength = 1 << 16 - - // Name should be file system lik - // Data should be anything permitted in JSON - regexpAlphaNum = regexp.MustCompile("^[a-zA-Z0-9._/-@]*$") - regexpJSON = regexp.MustCompile(`^[a-zA-Z0-9_/ \-+"':,\n\t.{}()\[\]]*$`) -) - -// filter strings -func validateNameRegEntryName(name string) bool { - return regexpAlphaNum.Match([]byte(name)) -} - -func validateNameRegEntryData(data string) bool { - return regexpJSON.Match([]byte(data)) -} - -// base cost is "effective" number of bytes -func NameBaseCost(name, data string) int64 { - return int64(len(data) + 32) -} - -func NameCostPerBlock(baseCost int64) int64 { - return NameBlockCostMultiplier * NameByteCostMultiplier * baseCost -} - -type NameRegEntry struct { - Name string `json:"name"` // registered name for the entry - Owner []byte `json:"owner"` // address that created the entry - Data string `json:"data"` // data to store under this name - Expires int `json:"expires"` // block at which this entry expires -} - -func (entry *NameRegEntry) Copy() *NameRegEntry { - entryCopy := *entry - return &entryCopy -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/node.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/node.go deleted file mode 100644 index bf635074..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/node.go +++ /dev/null @@ -1,67 +0,0 @@ -package types - -import ( - "fmt" - acm "github.com/tendermint/tendermint/account" - "strings" -) - -type NodeInfo struct { - PubKey acm.PubKeyEd25519 `json:"pub_key"` - Moniker string `json:"moniker"` - ChainID string `json:"chain_id"` - Host string `json:"host"` - P2PPort uint16 `json:"p2p_port"` - RPCPort uint16 `json:"rpc_port"` - - Version Versions `json:"versions"` -} - -type Versions struct { - Revision string `json:"revision"` - Tendermint string `json"tendermint"` - P2P string `json:"p2p"` - RPC string `json:"rpc"` - Wire string `json:"wire"` -} - -// CONTRACT: two nodes with the same Tendermint major and minor version and with the same ChainID are compatible -func (ni *NodeInfo) CompatibleWith(no *NodeInfo) error { - iM, im, _, ie := splitVersion(ni.Version.Tendermint) - oM, om, _, oe := splitVersion(no.Version.Tendermint) - - // if our own version number is not formatted right, we messed up - if ie != nil { - return ie - } - - // version number must be formatted correctly ("x.x.x") - if oe != nil { - return oe - } - - // major version must match - if iM != oM { - return fmt.Errorf("Peer is on a different major version. Got %v, expected %v", oM, iM) - } - - // minor version must match - if im != om { - return fmt.Errorf("Peer is on a different minor version. Got %v, expected %v", om, im) - } - - // nodes must be on the same chain_id - if ni.ChainID != no.ChainID { - return fmt.Errorf("Peer is on a different chain_id. Got %v, expected %v", no.ChainID, ni.ChainID) - } - - return nil -} - -func splitVersion(version string) (string, string, string, error) { - spl := strings.Split(version, ".") - if len(spl) != 3 { - return "", "", "", fmt.Errorf("Invalid version format %v", version) - } - return spl[0], spl[1], spl[2], nil -} 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 index 646c79ad..8bf2b3cf 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set.go @@ -7,11 +7,11 @@ import ( "io" "sync" - "code.google.com/p/go.crypto/ripemd160" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/merkle" - "github.com/tendermint/tendermint/wire" + . "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 ( @@ -75,7 +75,7 @@ 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 *int64, err *error) { +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) } 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 index 5d2d9142..565a3b51 100644 --- 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 @@ -5,7 +5,7 @@ import ( "io/ioutil" "testing" - . "github.com/tendermint/tendermint/common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) func TestBasicPartSet(t *testing.T) { 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 index b70afe94..c4d62407 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/priv_validator.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/priv_validator.go @@ -5,14 +5,14 @@ import ( "errors" "fmt" "io/ioutil" - "math" + "os" "sync" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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/ed25519" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" ) const ( @@ -35,12 +35,12 @@ func voteToStep(vote *Vote) int8 { } type PrivValidator struct { - Address []byte `json:"address"` - PubKey acm.PubKeyEd25519 `json:"pub_key"` - PrivKey acm.PrivKeyEd25519 `json:"priv_key"` - LastHeight int `json:"last_height"` - LastRound int `json:"last_round"` - LastStep int8 `json:"last_step"` + 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. @@ -53,8 +53,8 @@ func GenPrivValidator() *PrivValidator { privKeyBytes := new([64]byte) copy(privKeyBytes[:32], CRandBytes(32)) pubKeyBytes := ed25519.MakePublicKey(privKeyBytes) - pubKey := acm.PubKeyEd25519(*pubKeyBytes) - privKey := acm.PrivKeyEd25519(*privKeyBytes) + pubKey := crypto.PubKeyEd25519(*pubKeyBytes) + privKey := crypto.PrivKeyEd25519(*privKeyBytes) return &PrivValidator{ Address: pubKey.Address(), PubKey: pubKey, @@ -79,6 +79,21 @@ func LoadPrivValidator(filePath string) *PrivValidator { 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() @@ -96,7 +111,7 @@ func (privVal *PrivValidator) save() { PanicSanity("Cannot save PrivValidator: filePath not set") } jsonBytes := wire.JSONBytes(privVal) - err := WriteFileAtomic(privVal.filePath, jsonBytes) + err := WriteFileAtomic(privVal.filePath, jsonBytes, 0600) if err != nil { // `@; BOOM!!! PanicCrisis(err) @@ -135,7 +150,7 @@ func (privVal *PrivValidator) SignVote(chainID string, vote *Vote) error { } func (privVal *PrivValidator) SignVoteUnsafe(chainID string, vote *Vote) { - vote.Signature = privVal.PrivKey.Sign(acm.SignBytes(chainID, vote)).(acm.SignatureEd25519) + vote.Signature = privVal.PrivKey.Sign(SignBytes(chainID, vote)).(crypto.SignatureEd25519) } func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) error { @@ -152,33 +167,13 @@ func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) e privVal.save() // Sign - proposal.Signature = privVal.PrivKey.Sign(acm.SignBytes(chainID, proposal)).(acm.SignatureEd25519) + 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) SignRebondTx(chainID string, rebondTx *RebondTx) error { - privVal.mtx.Lock() - defer privVal.mtx.Unlock() - if privVal.LastHeight < rebondTx.Height { - - // Persist height/round/step - // Prevent doing anything else for this rebondTx.Height. - privVal.LastHeight = rebondTx.Height - privVal.LastRound = math.MaxInt32 // MaxInt64 overflows on 32bit architectures. - privVal.LastStep = math.MaxInt8 - privVal.save() - - // Sign - rebondTx.Signature = privVal.PrivKey.Sign(acm.SignBytes(chainID, rebondTx)).(acm.SignatureEd25519) - return nil - } else { - return errors.New(fmt.Sprintf("Attempt of duplicate signing of rebondTx: Height %v", rebondTx.Height)) - } -} - func (privVal *PrivValidator) String() string { return fmt.Sprintf("PrivValidator{%X LH:%v, LR:%v, LS:%v}", privVal.Address, privVal.LastHeight, privVal.LastRound, privVal.LastStep) } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go index 78c393f9..e67db26a 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go @@ -5,9 +5,9 @@ import ( "fmt" "io" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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 ( @@ -16,13 +16,14 @@ var ( ) 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 acm.SignatureEd25519 `json:"signature"` + 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, @@ -37,7 +38,7 @@ func (p *Proposal) String() string { p.BlockPartsHeader, p.POLRound, p.Signature) } -func (p *Proposal) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { +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) 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 index f37c11ee..a0024828 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal_test.go @@ -3,9 +3,8 @@ package types import ( "testing" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - _ "github.com/tendermint/tendermint/config/tendermint_test" + . "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) { @@ -15,7 +14,7 @@ func TestProposalSignable(t *testing.T) { BlockPartsHeader: PartSetHeader{111, []byte("blockparts")}, POLRound: -1, } - signBytes := acm.SignBytes(config.GetString("chain_id"), proposal) + 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}}`, diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go new file mode 100644 index 00000000..041f3bc4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go @@ -0,0 +1,30 @@ +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 new file mode 100644 index 00000000..29e00535 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/stats.go @@ -0,0 +1,46 @@ +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 index 245e32f0..a3cb9fc0 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx.go @@ -1,375 +1,3 @@ package types -import ( - "encoding/json" - "errors" - "io" - - "golang.org/x/crypto/ripemd160" - - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - ptypes "github.com/tendermint/tendermint/permission/types" - "github.com/tendermint/tendermint/wire" -) - -var ( - ErrTxInvalidAddress = errors.New("Error invalid address") - ErrTxDuplicateAddress = errors.New("Error duplicate address") - ErrTxInvalidAmount = errors.New("Error invalid amount") - ErrTxInsufficientFunds = errors.New("Error insufficient funds") - ErrTxInsufficientGasPrice = errors.New("Error insufficient gas price") - ErrTxUnknownPubKey = errors.New("Error unknown pubkey") - ErrTxInvalidPubKey = errors.New("Error invalid pubkey") - ErrTxInvalidSignature = errors.New("Error invalid signature") - ErrTxPermissionDenied = errors.New("Error permission denied") -) - -type ErrTxInvalidString struct { - Msg string -} - -func (e ErrTxInvalidString) Error() string { - return e.Msg -} - -type ErrTxInvalidSequence struct { - Got int - Expected int -} - -func (e ErrTxInvalidSequence) Error() string { - return Fmt("Error invalid sequence. Got %d, expected %d", e.Got, e.Expected) -} - -/* -Tx (Transaction) is an atomic operation on the ledger state. - -Account Txs: - - SendTx Send coins to address - - CallTx Send a msg to a contract that runs in the vm - - NameTx Store some value under a name in the global namereg - -Validation Txs: - - BondTx New validator posts a bond - - UnbondTx Validator leaves - - DupeoutTx Validator dupes out (equivocates) - -Admin Txs: - - PermissionsTx -*/ - -type Tx interface { - WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) -} - -// Types of Tx implementations -const ( - // Account transactions - TxTypeSend = byte(0x01) - TxTypeCall = byte(0x02) - TxTypeName = byte(0x03) - - // Validation transactions - TxTypeBond = byte(0x11) - TxTypeUnbond = byte(0x12) - TxTypeRebond = byte(0x13) - TxTypeDupeout = byte(0x14) - - // Admin transactions - TxTypePermissions = byte(0x20) -) - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ Tx }{}, - wire.ConcreteType{&SendTx{}, TxTypeSend}, - wire.ConcreteType{&CallTx{}, TxTypeCall}, - wire.ConcreteType{&NameTx{}, TxTypeName}, - wire.ConcreteType{&BondTx{}, TxTypeBond}, - wire.ConcreteType{&UnbondTx{}, TxTypeUnbond}, - wire.ConcreteType{&RebondTx{}, TxTypeRebond}, - wire.ConcreteType{&DupeoutTx{}, TxTypeDupeout}, - wire.ConcreteType{&PermissionsTx{}, TxTypePermissions}, -) - -//----------------------------------------------------------------------------- - -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 -} - -func (txIn *TxInput) ValidateBasic() error { - if len(txIn.Address) != 20 { - return ErrTxInvalidAddress - } - if txIn.Amount == 0 { - return ErrTxInvalidAmount - } - return nil -} - -func (txIn *TxInput) WriteSignBytes(w io.Writer, n *int64, err *error) { - wire.WriteTo([]byte(Fmt(`{"address":"%X","amount":%v,"sequence":%v}`, txIn.Address, txIn.Amount, txIn.Sequence)), w, n, err) -} - -func (txIn *TxInput) String() string { - return Fmt("TxInput{%X,%v,%v,%v,%v}", txIn.Address, txIn.Amount, txIn.Sequence, txIn.Signature, txIn.PubKey) -} - -//----------------------------------------------------------------------------- - -type TxOutput struct { - Address []byte `json:"address"` // Hash of the PubKey - Amount int64 `json:"amount"` // The sum of all outputs must not exceed the inputs. -} - -func (txOut *TxOutput) ValidateBasic() error { - if len(txOut.Address) != 20 { - return ErrTxInvalidAddress - } - if txOut.Amount == 0 { - return ErrTxInvalidAmount - } - return nil -} - -func (txOut *TxOutput) WriteSignBytes(w io.Writer, n *int64, err *error) { - wire.WriteTo([]byte(Fmt(`{"address":"%X","amount":%v}`, txOut.Address, txOut.Amount)), w, n, err) -} - -func (txOut *TxOutput) String() string { - return Fmt("TxOutput{%X,%v}", txOut.Address, txOut.Amount) -} - -//----------------------------------------------------------------------------- - -type SendTx struct { - Inputs []*TxInput `json:"inputs"` - Outputs []*TxOutput `json:"outputs"` -} - -func (tx *SendTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":%s`, jsonEscape(chainID))), w, n, err) - wire.WriteTo([]byte(Fmt(`,"tx":[%v,{"inputs":[`, TxTypeSend)), w, n, err) - for i, in := range tx.Inputs { - in.WriteSignBytes(w, n, err) - if i != len(tx.Inputs)-1 { - wire.WriteTo([]byte(","), w, n, err) - } - } - wire.WriteTo([]byte(`],"outputs":[`), w, n, err) - for i, out := range tx.Outputs { - out.WriteSignBytes(w, n, err) - if i != len(tx.Outputs)-1 { - wire.WriteTo([]byte(","), w, n, err) - } - } - wire.WriteTo([]byte(`]}]}`), w, n, err) -} - -func (tx *SendTx) String() string { - return Fmt("SendTx{%v -> %v}", tx.Inputs, tx.Outputs) -} - -//----------------------------------------------------------------------------- - -type CallTx struct { - Input *TxInput `json:"input"` - Address []byte `json:"address"` - GasLimit int64 `json:"gas_limit"` - Fee int64 `json:"fee"` - Data []byte `json:"data"` -} - -func (tx *CallTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":%s`, jsonEscape(chainID))), w, n, err) - wire.WriteTo([]byte(Fmt(`,"tx":[%v,{"address":"%X","data":"%X"`, TxTypeCall, tx.Address, tx.Data)), w, n, err) - wire.WriteTo([]byte(Fmt(`,"fee":%v,"gas_limit":%v,"input":`, tx.Fee, tx.GasLimit)), w, n, err) - tx.Input.WriteSignBytes(w, n, err) - wire.WriteTo([]byte(`}]}`), w, n, err) -} - -func (tx *CallTx) String() string { - return Fmt("CallTx{%v -> %x: %x}", tx.Input, tx.Address, tx.Data) -} - -func NewContractAddress(caller []byte, nonce int) []byte { - temp := make([]byte, 32+8) - copy(temp, caller) - PutInt64BE(temp[32:], int64(nonce)) - hasher := ripemd160.New() - hasher.Write(temp) // does not error - return hasher.Sum(nil) -} - -//----------------------------------------------------------------------------- - -type NameTx struct { - Input *TxInput `json:"input"` - Name string `json:"name"` - Data string `json:"data"` - Fee int64 `json:"fee"` -} - -func (tx *NameTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":%s`, jsonEscape(chainID))), w, n, err) - wire.WriteTo([]byte(Fmt(`,"tx":[%v,{"data":%s,"fee":%v`, TxTypeName, jsonEscape(tx.Data), tx.Fee)), w, n, err) - wire.WriteTo([]byte(`,"input":`), w, n, err) - tx.Input.WriteSignBytes(w, n, err) - wire.WriteTo([]byte(Fmt(`,"name":%s`, jsonEscape(tx.Name))), w, n, err) - wire.WriteTo([]byte(`}]}`), w, n, err) -} - -func (tx *NameTx) ValidateStrings() error { - if len(tx.Name) == 0 { - return ErrTxInvalidString{"Name must not be empty"} - } - if len(tx.Name) > MaxNameLength { - return ErrTxInvalidString{Fmt("Name is too long. Max %d bytes", MaxNameLength)} - } - if len(tx.Data) > MaxDataLength { - return ErrTxInvalidString{Fmt("Data is too long. Max %d bytes", MaxDataLength)} - } - - if !validateNameRegEntryName(tx.Name) { - return ErrTxInvalidString{Fmt("Invalid characters found in NameTx.Name (%s). Only alphanumeric, underscores, dashes, forward slashes, and @ are allowed", tx.Name)} - } - - if !validateNameRegEntryData(tx.Data) { - return ErrTxInvalidString{Fmt("Invalid characters found in NameTx.Data (%s). Only the kind of things found in a JSON file are allowed", tx.Data)} - } - - return nil -} - -func (tx *NameTx) String() string { - return Fmt("NameTx{%v -> %s: %s}", tx.Input, tx.Name, tx.Data) -} - -//----------------------------------------------------------------------------- - -type BondTx struct { - PubKey acm.PubKeyEd25519 `json:"pub_key"` - Signature acm.SignatureEd25519 `json:"signature"` - Inputs []*TxInput `json:"inputs"` - UnbondTo []*TxOutput `json:"unbond_to"` -} - -func (tx *BondTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":%s`, jsonEscape(chainID))), w, n, err) - wire.WriteTo([]byte(Fmt(`,"tx":[%v,{"inputs":[`, TxTypeBond)), w, n, err) - for i, in := range tx.Inputs { - in.WriteSignBytes(w, n, err) - if i != len(tx.Inputs)-1 { - wire.WriteTo([]byte(","), w, n, err) - } - } - wire.WriteTo([]byte(Fmt(`],"pub_key":`)), w, n, err) - wire.WriteTo(wire.JSONBytes(tx.PubKey), w, n, err) - wire.WriteTo([]byte(`,"unbond_to":[`), w, n, err) - for i, out := range tx.UnbondTo { - out.WriteSignBytes(w, n, err) - if i != len(tx.UnbondTo)-1 { - wire.WriteTo([]byte(","), w, n, err) - } - } - wire.WriteTo([]byte(`]}]}`), w, n, err) -} - -func (tx *BondTx) String() string { - return Fmt("BondTx{%v: %v -> %v}", tx.PubKey, tx.Inputs, tx.UnbondTo) -} - -//----------------------------------------------------------------------------- - -type UnbondTx struct { - Address []byte `json:"address"` - Height int `json:"height"` - Signature acm.SignatureEd25519 `json:"signature"` -} - -func (tx *UnbondTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":%s`, jsonEscape(chainID))), w, n, err) - wire.WriteTo([]byte(Fmt(`,"tx":[%v,{"address":"%X","height":%v}]}`, TxTypeUnbond, tx.Address, tx.Height)), w, n, err) -} - -func (tx *UnbondTx) String() string { - return Fmt("UnbondTx{%X,%v,%v}", tx.Address, tx.Height, tx.Signature) -} - -//----------------------------------------------------------------------------- - -type RebondTx struct { - Address []byte `json:"address"` - Height int `json:"height"` - Signature acm.SignatureEd25519 `json:"signature"` -} - -func (tx *RebondTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":%s`, jsonEscape(chainID))), w, n, err) - wire.WriteTo([]byte(Fmt(`,"tx":[%v,{"address":"%X","height":%v}]}`, TxTypeRebond, tx.Address, tx.Height)), w, n, err) -} - -func (tx *RebondTx) String() string { - return Fmt("RebondTx{%X,%v,%v}", tx.Address, tx.Height, tx.Signature) -} - -//----------------------------------------------------------------------------- - -type DupeoutTx struct { - Address []byte `json:"address"` - VoteA Vote `json:"vote_a"` - VoteB Vote `json:"vote_b"` -} - -func (tx *DupeoutTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { - PanicSanity("DupeoutTx has no sign bytes") -} - -func (tx *DupeoutTx) String() string { - return Fmt("DupeoutTx{%X,%v,%v}", tx.Address, tx.VoteA, tx.VoteB) -} - -//----------------------------------------------------------------------------- - -type PermissionsTx struct { - Input *TxInput `json:"input"` - PermArgs ptypes.PermArgs `json:"args"` -} - -func (tx *PermissionsTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":%s`, jsonEscape(chainID))), w, n, err) - wire.WriteTo([]byte(Fmt(`,"tx":[%v,{"args":"`, TxTypePermissions)), w, n, err) - wire.WriteJSON(tx.PermArgs, w, n, err) - wire.WriteTo([]byte(`","input":`), w, n, err) - tx.Input.WriteSignBytes(w, n, err) - wire.WriteTo([]byte(`}]}`), w, n, err) -} - -func (tx *PermissionsTx) String() string { - return Fmt("PermissionsTx{%v -> %v}", tx.Input, tx.PermArgs) -} - -//----------------------------------------------------------------------------- - -// This should match the leaf hashes of Block.Data.Hash()'s SimpleMerkleTree. -func TxID(chainID string, tx Tx) []byte { - signBytes := acm.SignBytes(chainID, tx) - return wire.BinaryRipemd160(signBytes) -} - -//-------------------------------------------------------------------------------- - -// Contract: This function is deterministic and completely reversible. -func jsonEscape(str string) string { - escapedBytes, err := json.Marshal(str) - if err != nil { - PanicSanity(Fmt("Error json-escaping a string", str)) - } - return string(escapedBytes) -} +type Tx []byte diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx_test.go deleted file mode 100644 index 61acab15..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx_test.go +++ /dev/null @@ -1,178 +0,0 @@ -package types - -import ( - "testing" - - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - _ "github.com/tendermint/tendermint/config/tendermint_test" - ptypes "github.com/tendermint/tendermint/permission/types" -) - -var chainID string - -func init() { - chainID = config.GetString("chain_id") -} - -func TestSendTxSignable(t *testing.T) { - sendTx := &SendTx{ - Inputs: []*TxInput{ - &TxInput{ - Address: []byte("input1"), - Amount: 12345, - Sequence: 67890, - }, - &TxInput{ - Address: []byte("input2"), - Amount: 111, - Sequence: 222, - }, - }, - Outputs: []*TxOutput{ - &TxOutput{ - Address: []byte("output1"), - Amount: 333, - }, - &TxOutput{ - Address: []byte("output2"), - Amount: 444, - }, - }, - } - signBytes := acm.SignBytes(chainID, sendTx) - signStr := string(signBytes) - expected := Fmt(`{"chain_id":"%s","tx":[1,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"outputs":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`, - config.GetString("chain_id")) - if signStr != expected { - t.Errorf("Got unexpected sign string for SendTx. Expected:\n%v\nGot:\n%v", expected, signStr) - } -} - -func TestCallTxSignable(t *testing.T) { - callTx := &CallTx{ - Input: &TxInput{ - Address: []byte("input1"), - Amount: 12345, - Sequence: 67890, - }, - Address: []byte("contract1"), - GasLimit: 111, - Fee: 222, - Data: []byte("data1"), - } - signBytes := acm.SignBytes(chainID, callTx) - signStr := string(signBytes) - expected := Fmt(`{"chain_id":"%s","tx":[2,{"address":"636F6E747261637431","data":"6461746131","fee":222,"gas_limit":111,"input":{"address":"696E70757431","amount":12345,"sequence":67890}}]}`, - config.GetString("chain_id")) - if signStr != expected { - t.Errorf("Got unexpected sign string for CallTx. Expected:\n%v\nGot:\n%v", expected, signStr) - } -} - -func TestNameTxSignable(t *testing.T) { - nameTx := &NameTx{ - Input: &TxInput{ - Address: []byte("input1"), - Amount: 12345, - Sequence: 250, - }, - Name: "google.com", - Data: "secretly.not.google.com", - Fee: 1000, - } - signBytes := acm.SignBytes(chainID, nameTx) - signStr := string(signBytes) - expected := Fmt(`{"chain_id":"%s","tx":[3,{"data":"secretly.not.google.com","fee":1000,"input":{"address":"696E70757431","amount":12345,"sequence":250},"name":"google.com"}]}`, - config.GetString("chain_id")) - if signStr != expected { - t.Errorf("Got unexpected sign string for CallTx. Expected:\n%v\nGot:\n%v", expected, signStr) - } -} - -func TestBondTxSignable(t *testing.T) { - privKeyBytes := make([]byte, 64) - privAccount := acm.GenPrivAccountFromPrivKeyBytes(privKeyBytes) - bondTx := &BondTx{ - PubKey: privAccount.PubKey.(acm.PubKeyEd25519), - Inputs: []*TxInput{ - &TxInput{ - Address: []byte("input1"), - Amount: 12345, - Sequence: 67890, - }, - &TxInput{ - Address: []byte("input2"), - Amount: 111, - Sequence: 222, - }, - }, - UnbondTo: []*TxOutput{ - &TxOutput{ - Address: []byte("output1"), - Amount: 333, - }, - &TxOutput{ - Address: []byte("output2"), - Amount: 444, - }, - }, - } - signBytes := acm.SignBytes(chainID, bondTx) - signStr := string(signBytes) - expected := Fmt(`{"chain_id":"%s","tx":[17,{"inputs":[{"address":"696E70757431","amount":12345,"sequence":67890},{"address":"696E70757432","amount":111,"sequence":222}],"pub_key":[1,"3B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29"],"unbond_to":[{"address":"6F757470757431","amount":333},{"address":"6F757470757432","amount":444}]}]}`, - config.GetString("chain_id")) - if signStr != expected { - t.Errorf("Unexpected sign string for BondTx. \nGot %s\nExpected %s", signStr, expected) - } -} - -func TestUnbondTxSignable(t *testing.T) { - unbondTx := &UnbondTx{ - Address: []byte("address1"), - Height: 111, - } - signBytes := acm.SignBytes(chainID, unbondTx) - signStr := string(signBytes) - expected := Fmt(`{"chain_id":"%s","tx":[18,{"address":"6164647265737331","height":111}]}`, - config.GetString("chain_id")) - if signStr != expected { - t.Errorf("Got unexpected sign string for UnbondTx") - } -} - -func TestRebondTxSignable(t *testing.T) { - rebondTx := &RebondTx{ - Address: []byte("address1"), - Height: 111, - } - signBytes := acm.SignBytes(chainID, rebondTx) - signStr := string(signBytes) - expected := Fmt(`{"chain_id":"%s","tx":[19,{"address":"6164647265737331","height":111}]}`, - config.GetString("chain_id")) - if signStr != expected { - t.Errorf("Got unexpected sign string for RebondTx") - } -} - -func TestPermissionsTxSignable(t *testing.T) { - permsTx := &PermissionsTx{ - Input: &TxInput{ - Address: []byte("input1"), - Amount: 12345, - Sequence: 250, - }, - PermArgs: &ptypes.SetBaseArgs{ - Address: []byte("address1"), - Permission: 1, - Value: true, - }, - } - signBytes := acm.SignBytes(chainID, permsTx) - signStr := string(signBytes) - expected := Fmt(`{"chain_id":"%s","tx":[32,{"args":"[2,{"address":"6164647265737331","permission":1,"value":true}]","input":{"address":"696E70757431","amount":12345,"sequence":250}}]}`, - config.GetString("chain_id")) - if signStr != expected { - t.Errorf("Got unexpected sign string for CallTx. Expected:\n%v\nGot:\n%v", expected, signStr) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx_utils.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx_utils.go deleted file mode 100644 index 3750483d..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx_utils.go +++ /dev/null @@ -1,260 +0,0 @@ -package types - -import ( - "fmt" - acm "github.com/tendermint/tendermint/account" - ptypes "github.com/tendermint/tendermint/permission/types" -) - -type AccountGetter interface { - GetAccount(addr []byte) *acm.Account -} - -//---------------------------------------------------------------------------- -// SendTx interface for adding inputs/outputs and adding signatures - -func NewSendTx() *SendTx { - return &SendTx{ - Inputs: []*TxInput{}, - Outputs: []*TxOutput{}, - } -} - -func (tx *SendTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error { - addr := pubkey.Address() - acc := st.GetAccount(addr) - if acc == nil { - return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey) - } - return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1) -} - -func (tx *SendTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error { - addr := pubkey.Address() - tx.Inputs = append(tx.Inputs, &TxInput{ - Address: addr, - Amount: amt, - Sequence: nonce, - Signature: acm.SignatureEd25519{}, - PubKey: pubkey, - }) - return nil -} - -func (tx *SendTx) AddOutput(addr []byte, amt int64) error { - tx.Outputs = append(tx.Outputs, &TxOutput{ - Address: addr, - Amount: amt, - }) - return nil -} - -func (tx *SendTx) SignInput(chainID string, i int, privAccount *acm.PrivAccount) error { - if i >= len(tx.Inputs) { - return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs)) - } - tx.Inputs[i].PubKey = privAccount.PubKey - tx.Inputs[i].Signature = privAccount.Sign(chainID, tx) - return nil -} - -//---------------------------------------------------------------------------- -// CallTx interface for creating tx - -func NewCallTx(st AccountGetter, from acm.PubKey, to, data []byte, amt, gasLimit, fee int64) (*CallTx, error) { - addr := from.Address() - acc := st.GetAccount(addr) - if acc == nil { - return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from) - } - - nonce := acc.Sequence + 1 - 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 { - addr := from.Address() - input := &TxInput{ - Address: addr, - Amount: amt, - Sequence: nonce, - Signature: acm.SignatureEd25519{}, - PubKey: from, - } - - return &CallTx{ - Input: input, - Address: to, - GasLimit: gasLimit, - Fee: fee, - Data: data, - } -} - -func (tx *CallTx) Sign(chainID string, privAccount *acm.PrivAccount) { - tx.Input.PubKey = privAccount.PubKey - tx.Input.Signature = privAccount.Sign(chainID, tx) -} - -//---------------------------------------------------------------------------- -// NameTx interface for creating tx - -func NewNameTx(st AccountGetter, from acm.PubKey, name, data string, amt, fee int64) (*NameTx, error) { - addr := from.Address() - acc := st.GetAccount(addr) - if acc == nil { - return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from) - } - - nonce := acc.Sequence + 1 - return NewNameTxWithNonce(from, name, data, amt, fee, nonce), nil -} - -func NewNameTxWithNonce(from acm.PubKey, name, data string, amt, fee int64, nonce int) *NameTx { - addr := from.Address() - input := &TxInput{ - Address: addr, - Amount: amt, - Sequence: nonce, - Signature: acm.SignatureEd25519{}, - PubKey: from, - } - - return &NameTx{ - Input: input, - Name: name, - Data: data, - Fee: fee, - } -} - -func (tx *NameTx) Sign(chainID string, privAccount *acm.PrivAccount) { - tx.Input.PubKey = privAccount.PubKey - tx.Input.Signature = privAccount.Sign(chainID, tx) -} - -//---------------------------------------------------------------------------- -// BondTx interface for adding inputs/outputs and adding signatures - -func NewBondTx(pubkey acm.PubKey) (*BondTx, error) { - pubkeyEd, ok := pubkey.(acm.PubKeyEd25519) - if !ok { - return nil, fmt.Errorf("Pubkey must be ed25519") - } - return &BondTx{ - PubKey: pubkeyEd, - Inputs: []*TxInput{}, - UnbondTo: []*TxOutput{}, - }, nil -} - -func (tx *BondTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error { - addr := pubkey.Address() - acc := st.GetAccount(addr) - if acc == nil { - return fmt.Errorf("Invalid address %X from pubkey %X", addr, pubkey) - } - return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1) -} - -func (tx *BondTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error { - addr := pubkey.Address() - tx.Inputs = append(tx.Inputs, &TxInput{ - Address: addr, - Amount: amt, - Sequence: nonce, - Signature: acm.SignatureEd25519{}, - PubKey: pubkey, - }) - return nil -} - -func (tx *BondTx) AddOutput(addr []byte, amt int64) error { - tx.UnbondTo = append(tx.UnbondTo, &TxOutput{ - Address: addr, - Amount: amt, - }) - return nil -} - -func (tx *BondTx) SignBond(chainID string, privAccount *acm.PrivAccount) error { - sig := privAccount.Sign(chainID, tx) - sigEd, ok := sig.(acm.SignatureEd25519) - if !ok { - return fmt.Errorf("Bond signer must be ED25519") - } - tx.Signature = sigEd - return nil -} - -func (tx *BondTx) SignInput(chainID string, i int, privAccount *acm.PrivAccount) error { - if i >= len(tx.Inputs) { - return fmt.Errorf("Index %v is greater than number of inputs (%v)", i, len(tx.Inputs)) - } - tx.Inputs[i].PubKey = privAccount.PubKey - tx.Inputs[i].Signature = privAccount.Sign(chainID, tx) - return nil -} - -//---------------------------------------------------------------------- -// UnbondTx interface for creating tx - -func NewUnbondTx(addr []byte, height int) *UnbondTx { - return &UnbondTx{ - Address: addr, - Height: height, - } -} - -func (tx *UnbondTx) Sign(chainID string, privAccount *acm.PrivAccount) { - tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519) -} - -//---------------------------------------------------------------------- -// RebondTx interface for creating tx - -func NewRebondTx(addr []byte, height int) *RebondTx { - return &RebondTx{ - Address: addr, - Height: height, - } -} - -func (tx *RebondTx) Sign(chainID string, privAccount *acm.PrivAccount) { - tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519) -} - -//---------------------------------------------------------------------------- -// PermissionsTx interface for creating tx - -func NewPermissionsTx(st AccountGetter, from acm.PubKey, args ptypes.PermArgs) (*PermissionsTx, error) { - addr := from.Address() - acc := st.GetAccount(addr) - if acc == nil { - return nil, fmt.Errorf("Invalid address %X from pubkey %X", addr, from) - } - - nonce := acc.Sequence + 1 - return NewPermissionsTxWithNonce(from, args, nonce), nil -} - -func NewPermissionsTxWithNonce(from acm.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{}, - PubKey: from, - } - - return &PermissionsTx{ - Input: input, - PermArgs: args, - } -} - -func (tx *PermissionsTx) Sign(chainID string, privAccount *acm.PrivAccount) { - tx.Input.PubKey = privAccount.PubKey - tx.Input.Signature = privAccount.Sign(chainID, tx) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go index dbf4cbde..e7807008 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go @@ -5,54 +5,20 @@ import ( "fmt" "io" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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" ) -// Persistent (mostly) static data for each Validator -type ValidatorInfo struct { - Address []byte `json:"address"` - PubKey acm.PubKeyEd25519 `json:"pub_key"` - UnbondTo []*TxOutput `json:"unbond_to"` - FirstBondHeight int `json:"first_bond_height"` - FirstBondAmount int64 `json:"first_bond_amount"` - DestroyedHeight int `json:"destroyed_height"` // If destroyed - DestroyedAmount int64 `json:"destroyed_amount"` // If destroyed - ReleasedHeight int `json:"released_height"` // If released -} - -func (valInfo *ValidatorInfo) Copy() *ValidatorInfo { - valInfoCopy := *valInfo - return &valInfoCopy -} - -func ValidatorInfoEncoder(o interface{}, w io.Writer, n *int64, err *error) { - wire.WriteBinary(o.(*ValidatorInfo), w, n, err) -} - -func ValidatorInfoDecoder(r io.Reader, n *int64, err *error) interface{} { - return wire.ReadBinary(&ValidatorInfo{}, r, n, err) -} - -var ValidatorInfoCodec = wire.Codec{ - Encode: ValidatorInfoEncoder, - Decode: ValidatorInfoDecoder, -} - -//----------------------------------------------------------------------------- - // 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 acm.PubKeyEd25519 `json:"pub_key"` - BondHeight int `json:"bond_height"` - UnbondHeight int `json:"unbond_height"` - LastCommitHeight int `json:"last_commit_height"` - VotingPower int64 `json:"voting_power"` - Accum int64 `json:"accum"` + 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. @@ -90,9 +56,7 @@ func (v *Validator) String() string { return fmt.Sprintf("Validator{%X %v %v-%v-%v VP:%v A:%v}", v.Address, v.PubKey, - v.BondHeight, v.LastCommitHeight, - v.UnbondHeight, v.VotingPower, v.Accum) } @@ -107,12 +71,12 @@ var ValidatorCodec = validatorCodec{} type validatorCodec struct{} -func (vc validatorCodec) Encode(o interface{}, w io.Writer, n *int64, err *error) { +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 *int64, err *error) interface{} { - return wire.ReadBinary(&Validator{}, r, 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 { 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 index 7dc4ee62..d156adc8 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set.go @@ -6,9 +6,8 @@ import ( "sort" "strings" - "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/merkle" + . "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. @@ -36,9 +35,14 @@ func NewValidatorSet(vals []*Validator) *ValidatorSet { validators[i] = val.Copy() } sort.Sort(ValidatorsByAddress(validators)) - return &ValidatorSet{ + vs := &ValidatorSet{ Validators: validators, } + + if vals != nil { + vs.IncrementAccum(1) + } + return vs } // TODO: mind the overflow when times and votingPower shares too large. @@ -230,7 +234,7 @@ func (valSet *ValidatorSet) VerifyValidation(chainID string, } _, val := valSet.GetByIndex(idx) // Validate signature - precommitSignBytes := account.SignBytes(chainID, precommit) + precommitSignBytes := SignBytes(chainID, precommit) if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) { return fmt.Errorf("Invalid validation -- invalid signature: %v", precommit) } 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 index c8b5d307..5064e796 100644 --- 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 @@ -1,25 +1,24 @@ package types import ( - "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" + . "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() account.PubKeyEd25519 { +func randPubKey() crypto.PubKeyEd25519 { var pubKey [32]byte copy(pubKey[:], RandBytes(32)) - return account.PubKeyEd25519(pubKey) + return crypto.PubKeyEd25519(pubKey) } func randValidator_() *Validator { return &Validator{ Address: RandBytes(20), PubKey: randPubKey(), - BondHeight: RandInt(), VotingPower: RandInt64(), Accum: RandInt64(), } @@ -50,48 +49,107 @@ func TestCopy(t *testing.T) { func TestProposerSelection(t *testing.T) { vset := NewValidatorSet([]*Validator{ - &Validator{ - Address: []byte("foo"), - PubKey: randPubKey(), - BondHeight: RandInt(), - VotingPower: 1000, - Accum: 0, - }, - &Validator{ - Address: []byte("bar"), - PubKey: randPubKey(), - BondHeight: RandInt(), - VotingPower: 300, - Accum: 0, - }, - &Validator{ - Address: []byte("baz"), - PubKey: randPubKey(), - BondHeight: RandInt(), - VotingPower: 330, - Accum: 0, - }, + newValidator([]byte("foo"), 1000), + newValidator([]byte("bar"), 300), + newValidator([]byte("baz"), 330), }) proposers := []string{} - for i := 0; i < 100; i++ { + for i := 0; i < 99; i++ { val := vset.Proposer() proposers = append(proposers, string(val.Address)) vset.IncrementAccum(1) } - expected := `bar 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` + 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++ { - privAccount := account.GenPrivAccount() + privKey := crypto.GenPrivKeyEd25519() + pubKey := privKey.PubKey().(crypto.PubKeyEd25519) val := &Validator{ - Address: privAccount.Address, - PubKey: privAccount.PubKey.(account.PubKeyEd25519), + Address: pubKey.Address(), + PubKey: pubKey, } if !vset.Add(val) { panic("Failed to add validator") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go index c23ca9cb..d1ecfe65 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go @@ -5,9 +5,9 @@ import ( "fmt" "io" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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 ( @@ -28,12 +28,12 @@ func (err *ErrVoteConflictingSignature) Error() string { // 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 acm.SignatureEd25519 `json:"signature"` + 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 @@ -42,7 +42,7 @@ const ( VoteTypePrecommit = byte(0x02) ) -func (vote *Vote) WriteSignBytes(chainID string, w io.Writer, n *int64, err *error) { +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) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/.ethtest b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set similarity index 100% rename from Godeps/_workspace/src/github.com/tendermint/tendermint/vm/.ethtest rename to Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set 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 index 621e3076..55c24b14 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set.go +++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set.go @@ -6,9 +6,8 @@ import ( "strings" "sync" - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/wire" + . "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 @@ -130,7 +129,7 @@ func (voteSet *VoteSet) addVote(val *Validator, valIndex int, vote *Vote) (bool, } // Check signature. - if !val.PubKey.VerifyBytes(acm.SignBytes(config.GetString("chain_id"), vote), vote.Signature) { + if !val.PubKey.VerifyBytes(SignBytes(config.GetString("chain_id"), vote), vote.Signature) { // Bad signature. return false, 0, ErrVoteInvalidSignature } @@ -204,6 +203,9 @@ 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 @@ -302,32 +304,20 @@ func (voteSet *VoteSet) MakeValidation() *Validation { //-------------------------------------------------------------------------------- // For testing... -func RandValidator(randBonded bool, minBonded int64) (*ValidatorInfo, *Validator, *PrivValidator) { +func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidator) { privVal := GenPrivValidator() _, tempFilePath := Tempfile("priv_validator_") privVal.SetFile(tempFilePath) - bonded := minBonded - if randBonded { - bonded += int64(RandUint32()) - } - valInfo := &ValidatorInfo{ - Address: privVal.Address, - PubKey: privVal.PubKey, - UnbondTo: []*TxOutput{&TxOutput{ - Amount: bonded, - Address: privVal.Address, - }}, - FirstBondHeight: 0, - FirstBondAmount: bonded, + votePower := minPower + if randPower { + votePower += int64(RandUint32()) } val := &Validator{ - Address: valInfo.Address, - PubKey: valInfo.PubKey, - BondHeight: 0, - UnbondHeight: 0, + Address: privVal.Address, + PubKey: privVal.PubKey, LastCommitHeight: 0, - VotingPower: valInfo.FirstBondAmount, + VotingPower: votePower, Accum: 0, } - return valInfo, val, privVal + 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 index d521478e..d066b9f1 100644 --- 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 @@ -4,9 +4,9 @@ import ( "bytes" "sort" - . "github.com/tendermint/tendermint/common" - . "github.com/tendermint/tendermint/common/test" - _ "github.com/tendermint/tendermint/config/tendermint_test" + . "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" ) @@ -15,7 +15,7 @@ func randVoteSet(height int, round int, type_ byte, numValidators int, votingPow vals := make([]*Validator, numValidators) privValidators := make([]*PrivValidator, numValidators) for i := 0; i < numValidators; i++ { - _, val, privValidator := RandValidator(false, votingPower) + val, privValidator := RandValidator(false, votingPower) vals[i] = val privValidators[i] = privValidator } diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/common.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/common.go deleted file mode 100644 index 00ab93c7..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/common.go +++ /dev/null @@ -1,26 +0,0 @@ -package vm - -import ( - "math/big" -) - -// To256 -// -// "cast" the big int to a 256 big int (i.e., limit to) -var tt256 = new(big.Int).Lsh(big.NewInt(1), 256) -var tt256m1 = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1)) -var tt255 = new(big.Int).Lsh(big.NewInt(1), 255) - -func U256(x *big.Int) *big.Int { - x.And(x, tt256m1) - return x -} - -func S256(x *big.Int) *big.Int { - if x.Cmp(tt255) < 0 { - return x - } else { - // We don't want to modify x, ever - return new(big.Int).Sub(x, tt256) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/gas.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/gas.go deleted file mode 100644 index fe4a43d8..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/gas.go +++ /dev/null @@ -1,18 +0,0 @@ -package vm - -const ( - GasSha3 int64 = 1 - GasGetAccount int64 = 1 - GasStorageUpdate int64 = 1 - - GasBaseOp int64 = 0 // TODO: make this 1 - GasStackOp int64 = 1 - - GasEcRecover int64 = 1 - GasSha256Word int64 = 1 - GasSha256Base int64 = 1 - GasRipemd160Word int64 = 1 - GasRipemd160Base int64 = 1 - GasIdentityWord int64 = 1 - GasIdentityBase int64 = 1 -) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/log.go deleted file mode 100644 index 9862495b..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package vm - -import ( - "github.com/tendermint/tendermint/logger" -) - -var log = logger.New("module", "vm") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/native.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/native.go deleted file mode 100644 index a85bd17c..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/native.go +++ /dev/null @@ -1,104 +0,0 @@ -package vm - -import ( - "crypto/sha256" - "code.google.com/p/go.crypto/ripemd160" - . "github.com/tendermint/tendermint/common" -) - -var registeredNativeContracts = make(map[Word256]NativeContract) - -func RegisteredNativeContract(addr Word256) bool { - _, ok := registeredNativeContracts[addr] - return ok -} - -func RegisterNativeContract(addr Word256, fn NativeContract) bool { - _, exists := registeredNativeContracts[addr] - if exists { - return false - } - registeredNativeContracts[addr] = fn - return true -} - -func init() { - registerNativeContracts() - registerSNativeContracts() -} - -func registerNativeContracts() { - // registeredNativeContracts[Int64ToWord256(1)] = ecrecoverFunc - registeredNativeContracts[Int64ToWord256(2)] = sha256Func - registeredNativeContracts[Int64ToWord256(3)] = ripemd160Func - registeredNativeContracts[Int64ToWord256(4)] = identityFunc -} - -//----------------------------------------------------------------------------- - -type NativeContract func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) - -/* Removed due to C dependency -func ecrecoverFunc(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) { - // Deduct gas - gasRequired := GasEcRecover - if *gas < gasRequired { - return nil, ErrInsufficientGas - } else { - *gas -= gasRequired - } - // Recover - hash := input[:32] - v := byte(input[32] - 27) // ignore input[33:64], v is small. - sig := append(input[64:], v) - - recovered, err := secp256k1.RecoverPubkey(hash, sig) - if err != nil { - return nil, err - } - hashed := sha3.Sha3(recovered[1:]) - return LeftPadBytes(hashed, 32), nil -} -*/ - -func sha256Func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) { - // Deduct gas - gasRequired := int64((len(input)+31)/32)*GasSha256Word + GasSha256Base - if *gas < gasRequired { - return nil, ErrInsufficientGas - } else { - *gas -= gasRequired - } - // Hash - hasher := sha256.New() - // CONTRACT: this does not err - hasher.Write(input) - return hasher.Sum(nil), nil -} - -func ripemd160Func(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) { - // Deduct gas - gasRequired := int64((len(input)+31)/32)*GasRipemd160Word + GasRipemd160Base - if *gas < gasRequired { - return nil, ErrInsufficientGas - } else { - *gas -= gasRequired - } - // Hash - hasher := ripemd160.New() - // CONTRACT: this does not err - hasher.Write(input) - return LeftPadBytes(hasher.Sum(nil), 32), nil -} - -func identityFunc(appState AppState, caller *Account, input []byte, gas *int64) (output []byte, err error) { - // Deduct gas - gasRequired := int64((len(input)+31)/32)*GasIdentityWord + GasIdentityBase - if *gas < gasRequired { - return nil, ErrInsufficientGas - } else { - *gas -= gasRequired - } - // Return identity - return input, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go deleted file mode 100644 index 87e09bfd..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/opcodes.go +++ /dev/null @@ -1,354 +0,0 @@ -package vm - -import ( - "fmt" - "gopkg.in/fatih/set.v0" -) - -type OpCode byte - -const ( - // Op codes - // 0x0 range - arithmetic ops - STOP OpCode = iota - ADD - MUL - SUB - DIV - SDIV - MOD - SMOD - ADDMOD - MULMOD - EXP - SIGNEXTEND -) - -const ( - LT OpCode = iota + 0x10 - GT - SLT - SGT - EQ - ISZERO - AND - OR - XOR - NOT - BYTE - - SHA3 = 0x20 -) - -const ( - // 0x30 range - closure state - ADDRESS OpCode = 0x30 + iota - BALANCE - ORIGIN - CALLER - CALLVALUE - CALLDATALOAD - CALLDATASIZE - CALLDATACOPY - CODESIZE - CODECOPY - GASPRICE_DEPRECATED - EXTCODESIZE - EXTCODECOPY -) - -const ( - - // 0x40 range - block operations - BLOCKHASH OpCode = 0x40 + iota - COINBASE - TIMESTAMP - BLOCKHEIGHT - DIFFICULTY_DEPRECATED - GASLIMIT -) - -const ( - // 0x50 range - 'storage' and execution - POP OpCode = 0x50 + iota - MLOAD - MSTORE - MSTORE8 - SLOAD - SSTORE - JUMP - JUMPI - PC - MSIZE - GAS - JUMPDEST -) - -const ( - // 0x60 range - PUSH1 OpCode = 0x60 + iota - PUSH2 - PUSH3 - PUSH4 - PUSH5 - PUSH6 - PUSH7 - PUSH8 - PUSH9 - PUSH10 - PUSH11 - PUSH12 - PUSH13 - PUSH14 - PUSH15 - PUSH16 - PUSH17 - PUSH18 - PUSH19 - PUSH20 - PUSH21 - PUSH22 - PUSH23 - PUSH24 - PUSH25 - PUSH26 - PUSH27 - PUSH28 - PUSH29 - PUSH30 - PUSH31 - PUSH32 - DUP1 - DUP2 - DUP3 - DUP4 - DUP5 - DUP6 - DUP7 - DUP8 - DUP9 - DUP10 - DUP11 - DUP12 - DUP13 - DUP14 - DUP15 - DUP16 - SWAP1 - SWAP2 - SWAP3 - SWAP4 - SWAP5 - SWAP6 - SWAP7 - SWAP8 - SWAP9 - SWAP10 - SWAP11 - SWAP12 - SWAP13 - SWAP14 - SWAP15 - SWAP16 -) - -const ( - LOG0 OpCode = 0xa0 + iota - LOG1 - LOG2 - LOG3 - LOG4 -) - -const ( - // 0xf0 range - closures - CREATE OpCode = 0xf0 + iota - CALL - CALLCODE - RETURN - - // 0x70 range - other - SUICIDE = 0xff -) - -// Since the opcodes aren't all in order we can't use a regular slice -var opCodeToString = map[OpCode]string{ - // 0x0 range - arithmetic ops - STOP: "STOP", - ADD: "ADD", - MUL: "MUL", - SUB: "SUB", - DIV: "DIV", - SDIV: "SDIV", - MOD: "MOD", - SMOD: "SMOD", - EXP: "EXP", - NOT: "NOT", - LT: "LT", - GT: "GT", - SLT: "SLT", - SGT: "SGT", - EQ: "EQ", - ISZERO: "ISZERO", - SIGNEXTEND: "SIGNEXTEND", - - // 0x10 range - bit ops - AND: "AND", - OR: "OR", - XOR: "XOR", - BYTE: "BYTE", - ADDMOD: "ADDMOD", - MULMOD: "MULMOD", - - // 0x20 range - crypto - SHA3: "SHA3", - - // 0x30 range - closure state - ADDRESS: "ADDRESS", - BALANCE: "BALANCE", - ORIGIN: "ORIGIN", - CALLER: "CALLER", - CALLVALUE: "CALLVALUE", - CALLDATALOAD: "CALLDATALOAD", - CALLDATASIZE: "CALLDATASIZE", - CALLDATACOPY: "CALLDATACOPY", - CODESIZE: "CODESIZE", - CODECOPY: "CODECOPY", - GASPRICE_DEPRECATED: "TXGASPRICE_DEPRECATED", - - // 0x40 range - block operations - BLOCKHASH: "BLOCKHASH", - COINBASE: "COINBASE", - TIMESTAMP: "TIMESTAMP", - BLOCKHEIGHT: "BLOCKHEIGHT", - DIFFICULTY_DEPRECATED: "DIFFICULTY_DEPRECATED", - GASLIMIT: "GASLIMIT", - EXTCODESIZE: "EXTCODESIZE", - EXTCODECOPY: "EXTCODECOPY", - - // 0x50 range - 'storage' and execution - POP: "POP", - //DUP: "DUP", - //SWAP: "SWAP", - MLOAD: "MLOAD", - MSTORE: "MSTORE", - MSTORE8: "MSTORE8", - SLOAD: "SLOAD", - SSTORE: "SSTORE", - JUMP: "JUMP", - JUMPI: "JUMPI", - PC: "PC", - MSIZE: "MSIZE", - GAS: "GAS", - JUMPDEST: "JUMPDEST", - - // 0x60 range - push - PUSH1: "PUSH1", - PUSH2: "PUSH2", - PUSH3: "PUSH3", - PUSH4: "PUSH4", - PUSH5: "PUSH5", - PUSH6: "PUSH6", - PUSH7: "PUSH7", - PUSH8: "PUSH8", - PUSH9: "PUSH9", - PUSH10: "PUSH10", - PUSH11: "PUSH11", - PUSH12: "PUSH12", - PUSH13: "PUSH13", - PUSH14: "PUSH14", - PUSH15: "PUSH15", - PUSH16: "PUSH16", - PUSH17: "PUSH17", - PUSH18: "PUSH18", - PUSH19: "PUSH19", - PUSH20: "PUSH20", - PUSH21: "PUSH21", - PUSH22: "PUSH22", - PUSH23: "PUSH23", - PUSH24: "PUSH24", - PUSH25: "PUSH25", - PUSH26: "PUSH26", - PUSH27: "PUSH27", - PUSH28: "PUSH28", - PUSH29: "PUSH29", - PUSH30: "PUSH30", - PUSH31: "PUSH31", - PUSH32: "PUSH32", - - DUP1: "DUP1", - DUP2: "DUP2", - DUP3: "DUP3", - DUP4: "DUP4", - DUP5: "DUP5", - DUP6: "DUP6", - DUP7: "DUP7", - DUP8: "DUP8", - DUP9: "DUP9", - DUP10: "DUP10", - DUP11: "DUP11", - DUP12: "DUP12", - DUP13: "DUP13", - DUP14: "DUP14", - DUP15: "DUP15", - DUP16: "DUP16", - - SWAP1: "SWAP1", - SWAP2: "SWAP2", - SWAP3: "SWAP3", - SWAP4: "SWAP4", - SWAP5: "SWAP5", - SWAP6: "SWAP6", - SWAP7: "SWAP7", - SWAP8: "SWAP8", - SWAP9: "SWAP9", - SWAP10: "SWAP10", - SWAP11: "SWAP11", - SWAP12: "SWAP12", - SWAP13: "SWAP13", - SWAP14: "SWAP14", - SWAP15: "SWAP15", - SWAP16: "SWAP16", - LOG0: "LOG0", - LOG1: "LOG1", - LOG2: "LOG2", - LOG3: "LOG3", - LOG4: "LOG4", - - // 0xf0 range - CREATE: "CREATE", - CALL: "CALL", - RETURN: "RETURN", - CALLCODE: "CALLCODE", - - // 0x70 range - other - SUICIDE: "SUICIDE", -} - -func (o OpCode) String() string { - str := opCodeToString[o] - if len(str) == 0 { - return fmt.Sprintf("Missing opcode 0x%x", int(o)) - } - - return str -} - -//----------------------------------------------------------------------------- - -func AnalyzeJumpDests(code []byte) (dests *set.Set) { - dests = set.New() - - for pc := uint64(0); pc < uint64(len(code)); pc++ { - var op OpCode = OpCode(code[pc]) - switch op { - case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: - a := uint64(op) - uint64(PUSH1) + 1 - - pc += a - case JUMPDEST: - dests.Add(pc) - } - } - return -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/randentropy/rand_entropy.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/randentropy/rand_entropy.go deleted file mode 100644 index 615fee35..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/randentropy/rand_entropy.go +++ /dev/null @@ -1,35 +0,0 @@ -package randentropy - -import ( - crand "crypto/rand" - "github.com/tendermint/tendermint/vm/sha3" - "io" -) - -var Reader io.Reader = &randEntropy{} - -type randEntropy struct { -} - -func (*randEntropy) Read(bytes []byte) (n int, err error) { - readBytes := GetEntropyCSPRNG(len(bytes)) - copy(bytes, readBytes) - return len(bytes), nil -} - -// TODO: copied from crypto.go , move to sha3 package? -func Sha3(data []byte) []byte { - d := sha3.NewKeccak256() - d.Write(data) - - return d.Sum(nil) -} - -func GetEntropyCSPRNG(n int) []byte { - mainBuff := make([]byte, n) - _, err := io.ReadFull(crand.Reader, mainBuff) - if err != nil { - panic("reading from crypto/rand failed: " + err.Error()) - } - return mainBuff -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/sha3/keccakf.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/sha3/keccakf.go deleted file mode 100644 index 3baf13ba..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/sha3/keccakf.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sha3 - -// This file implements the core Keccak permutation function necessary for computing SHA3. -// This is implemented in a separate file to allow for replacement by an optimized implementation. -// Nothing in this package is exported. -// For the detailed specification, refer to the Keccak web site (http://keccak.noekeon.org/). - -// rc stores the round constants for use in the ι step. -var rc = [...]uint64{ - 0x0000000000000001, - 0x0000000000008082, - 0x800000000000808A, - 0x8000000080008000, - 0x000000000000808B, - 0x0000000080000001, - 0x8000000080008081, - 0x8000000000008009, - 0x000000000000008A, - 0x0000000000000088, - 0x0000000080008009, - 0x000000008000000A, - 0x000000008000808B, - 0x800000000000008B, - 0x8000000000008089, - 0x8000000000008003, - 0x8000000000008002, - 0x8000000000000080, - 0x000000000000800A, - 0x800000008000000A, - 0x8000000080008081, - 0x8000000000008080, - 0x0000000080000001, - 0x8000000080008008, -} - -// ro_xx represent the rotation offsets for use in the χ step. -// Defining them as const instead of in an array allows the compiler to insert constant shifts. -const ( - ro_00 = 0 - ro_01 = 36 - ro_02 = 3 - ro_03 = 41 - ro_04 = 18 - ro_05 = 1 - ro_06 = 44 - ro_07 = 10 - ro_08 = 45 - ro_09 = 2 - ro_10 = 62 - ro_11 = 6 - ro_12 = 43 - ro_13 = 15 - ro_14 = 61 - ro_15 = 28 - ro_16 = 55 - ro_17 = 25 - ro_18 = 21 - ro_19 = 56 - ro_20 = 27 - ro_21 = 20 - ro_22 = 39 - ro_23 = 8 - ro_24 = 14 -) - -// keccakF computes the complete Keccak-f function consisting of 24 rounds with a different -// constant (rc) in each round. This implementation fully unrolls the round function to avoid -// inner loops, as well as pre-calculating shift offsets. -func (d *digest) keccakF() { - for _, roundConstant := range rc { - // θ step - d.c[0] = d.a[0] ^ d.a[5] ^ d.a[10] ^ d.a[15] ^ d.a[20] - d.c[1] = d.a[1] ^ d.a[6] ^ d.a[11] ^ d.a[16] ^ d.a[21] - d.c[2] = d.a[2] ^ d.a[7] ^ d.a[12] ^ d.a[17] ^ d.a[22] - d.c[3] = d.a[3] ^ d.a[8] ^ d.a[13] ^ d.a[18] ^ d.a[23] - d.c[4] = d.a[4] ^ d.a[9] ^ d.a[14] ^ d.a[19] ^ d.a[24] - - d.d[0] = d.c[4] ^ (d.c[1]<<1 ^ d.c[1]>>63) - d.d[1] = d.c[0] ^ (d.c[2]<<1 ^ d.c[2]>>63) - d.d[2] = d.c[1] ^ (d.c[3]<<1 ^ d.c[3]>>63) - d.d[3] = d.c[2] ^ (d.c[4]<<1 ^ d.c[4]>>63) - d.d[4] = d.c[3] ^ (d.c[0]<<1 ^ d.c[0]>>63) - - d.a[0] ^= d.d[0] - d.a[1] ^= d.d[1] - d.a[2] ^= d.d[2] - d.a[3] ^= d.d[3] - d.a[4] ^= d.d[4] - d.a[5] ^= d.d[0] - d.a[6] ^= d.d[1] - d.a[7] ^= d.d[2] - d.a[8] ^= d.d[3] - d.a[9] ^= d.d[4] - d.a[10] ^= d.d[0] - d.a[11] ^= d.d[1] - d.a[12] ^= d.d[2] - d.a[13] ^= d.d[3] - d.a[14] ^= d.d[4] - d.a[15] ^= d.d[0] - d.a[16] ^= d.d[1] - d.a[17] ^= d.d[2] - d.a[18] ^= d.d[3] - d.a[19] ^= d.d[4] - d.a[20] ^= d.d[0] - d.a[21] ^= d.d[1] - d.a[22] ^= d.d[2] - d.a[23] ^= d.d[3] - d.a[24] ^= d.d[4] - - // Ï and Ï€ steps - d.b[0] = d.a[0] - d.b[1] = d.a[6]<<ro_06 ^ d.a[6]>>(64-ro_06) - d.b[2] = d.a[12]<<ro_12 ^ d.a[12]>>(64-ro_12) - d.b[3] = d.a[18]<<ro_18 ^ d.a[18]>>(64-ro_18) - d.b[4] = d.a[24]<<ro_24 ^ d.a[24]>>(64-ro_24) - d.b[5] = d.a[3]<<ro_15 ^ d.a[3]>>(64-ro_15) - d.b[6] = d.a[9]<<ro_21 ^ d.a[9]>>(64-ro_21) - d.b[7] = d.a[10]<<ro_02 ^ d.a[10]>>(64-ro_02) - d.b[8] = d.a[16]<<ro_08 ^ d.a[16]>>(64-ro_08) - d.b[9] = d.a[22]<<ro_14 ^ d.a[22]>>(64-ro_14) - d.b[10] = d.a[1]<<ro_05 ^ d.a[1]>>(64-ro_05) - d.b[11] = d.a[7]<<ro_11 ^ d.a[7]>>(64-ro_11) - d.b[12] = d.a[13]<<ro_17 ^ d.a[13]>>(64-ro_17) - d.b[13] = d.a[19]<<ro_23 ^ d.a[19]>>(64-ro_23) - d.b[14] = d.a[20]<<ro_04 ^ d.a[20]>>(64-ro_04) - d.b[15] = d.a[4]<<ro_20 ^ d.a[4]>>(64-ro_20) - d.b[16] = d.a[5]<<ro_01 ^ d.a[5]>>(64-ro_01) - d.b[17] = d.a[11]<<ro_07 ^ d.a[11]>>(64-ro_07) - d.b[18] = d.a[17]<<ro_13 ^ d.a[17]>>(64-ro_13) - d.b[19] = d.a[23]<<ro_19 ^ d.a[23]>>(64-ro_19) - d.b[20] = d.a[2]<<ro_10 ^ d.a[2]>>(64-ro_10) - d.b[21] = d.a[8]<<ro_16 ^ d.a[8]>>(64-ro_16) - d.b[22] = d.a[14]<<ro_22 ^ d.a[14]>>(64-ro_22) - d.b[23] = d.a[15]<<ro_03 ^ d.a[15]>>(64-ro_03) - d.b[24] = d.a[21]<<ro_09 ^ d.a[21]>>(64-ro_09) - - // χ step - d.a[0] = d.b[0] ^ (^d.b[1] & d.b[2]) - d.a[1] = d.b[1] ^ (^d.b[2] & d.b[3]) - d.a[2] = d.b[2] ^ (^d.b[3] & d.b[4]) - d.a[3] = d.b[3] ^ (^d.b[4] & d.b[0]) - d.a[4] = d.b[4] ^ (^d.b[0] & d.b[1]) - d.a[5] = d.b[5] ^ (^d.b[6] & d.b[7]) - d.a[6] = d.b[6] ^ (^d.b[7] & d.b[8]) - d.a[7] = d.b[7] ^ (^d.b[8] & d.b[9]) - d.a[8] = d.b[8] ^ (^d.b[9] & d.b[5]) - d.a[9] = d.b[9] ^ (^d.b[5] & d.b[6]) - d.a[10] = d.b[10] ^ (^d.b[11] & d.b[12]) - d.a[11] = d.b[11] ^ (^d.b[12] & d.b[13]) - d.a[12] = d.b[12] ^ (^d.b[13] & d.b[14]) - d.a[13] = d.b[13] ^ (^d.b[14] & d.b[10]) - d.a[14] = d.b[14] ^ (^d.b[10] & d.b[11]) - d.a[15] = d.b[15] ^ (^d.b[16] & d.b[17]) - d.a[16] = d.b[16] ^ (^d.b[17] & d.b[18]) - d.a[17] = d.b[17] ^ (^d.b[18] & d.b[19]) - d.a[18] = d.b[18] ^ (^d.b[19] & d.b[15]) - d.a[19] = d.b[19] ^ (^d.b[15] & d.b[16]) - d.a[20] = d.b[20] ^ (^d.b[21] & d.b[22]) - d.a[21] = d.b[21] ^ (^d.b[22] & d.b[23]) - d.a[22] = d.b[22] ^ (^d.b[23] & d.b[24]) - d.a[23] = d.b[23] ^ (^d.b[24] & d.b[20]) - d.a[24] = d.b[24] ^ (^d.b[20] & d.b[21]) - - // ι step - d.a[0] ^= roundConstant - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/sha3/sha3.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/sha3/sha3.go deleted file mode 100644 index da6b381f..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/sha3/sha3.go +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package sha3 implements the SHA3 hash algorithm (formerly called Keccak) chosen by NIST in 2012. -// This file provides a SHA3 implementation which implements the standard hash.Hash interface. -// Writing input data, including padding, and reading output data are computed in this file. -// Note that the current implementation can compute the hash of an integral number of bytes only. -// This is a consequence of the hash interface in which a buffer of bytes is passed in. -// The internals of the Keccak-f function are computed in keccakf.go. -// For the detailed specification, refer to the Keccak web site (http://keccak.noekeon.org/). -package sha3 - -import ( - "encoding/binary" - "hash" -) - -// laneSize is the size in bytes of each "lane" of the internal state of SHA3 (5 * 5 * 8). -// Note that changing this size would requires using a type other than uint64 to store each lane. -const laneSize = 8 - -// sliceSize represents the dimensions of the internal state, a square matrix of -// sliceSize ** 2 lanes. This is the size of both the "rows" and "columns" dimensions in the -// terminology of the SHA3 specification. -const sliceSize = 5 - -// numLanes represents the total number of lanes in the state. -const numLanes = sliceSize * sliceSize - -// stateSize is the size in bytes of the internal state of SHA3 (5 * 5 * WSize). -const stateSize = laneSize * numLanes - -// digest represents the partial evaluation of a checksum. -// Note that capacity, and not outputSize, is the critical security parameter, as SHA3 can output -// an arbitrary number of bytes for any given capacity. The Keccak proposal recommends that -// capacity = 2*outputSize to ensure that finding a collision of size outputSize requires -// O(2^{outputSize/2}) computations (the birthday lower bound). Future standards may modify the -// capacity/outputSize ratio to allow for more output with lower cryptographic security. -type digest struct { - a [numLanes]uint64 // main state of the hash - b [numLanes]uint64 // intermediate states - c [sliceSize]uint64 // intermediate states - d [sliceSize]uint64 // intermediate states - outputSize int // desired output size in bytes - capacity int // number of bytes to leave untouched during squeeze/absorb - absorbed int // number of bytes absorbed thus far -} - -// minInt returns the lesser of two integer arguments, to simplify the absorption routine. -func minInt(v1, v2 int) int { - if v1 <= v2 { - return v1 - } - return v2 -} - -// rate returns the number of bytes of the internal state which can be absorbed or squeezed -// in between calls to the permutation function. -func (d *digest) rate() int { - return stateSize - d.capacity -} - -// Reset clears the internal state by zeroing bytes in the state buffer. -// This can be skipped for a newly-created hash state; the default zero-allocated state is correct. -func (d *digest) Reset() { - d.absorbed = 0 - for i := range d.a { - d.a[i] = 0 - } -} - -// BlockSize, required by the hash.Hash interface, does not have a standard intepretation -// for a sponge-based construction like SHA3. We return the data rate: the number of bytes which -// can be absorbed per invocation of the permutation function. For Merkle-DamgÃ¥rd based hashes -// (ie SHA1, SHA2, MD5) the output size of the internal compression function is returned. -// We consider this to be roughly equivalent because it represents the number of bytes of output -// produced per cryptographic operation. -func (d *digest) BlockSize() int { return d.rate() } - -// Size returns the output size of the hash function in bytes. -func (d *digest) Size() int { - return d.outputSize -} - -// unalignedAbsorb is a helper function for Write, which absorbs data that isn't aligned with an -// 8-byte lane. This requires shifting the individual bytes into position in a uint64. -func (d *digest) unalignedAbsorb(p []byte) { - var t uint64 - for i := len(p) - 1; i >= 0; i-- { - t <<= 8 - t |= uint64(p[i]) - } - offset := (d.absorbed) % d.rate() - t <<= 8 * uint(offset%laneSize) - d.a[offset/laneSize] ^= t - d.absorbed += len(p) -} - -// Write "absorbs" bytes into the state of the SHA3 hash, updating as needed when the sponge -// "fills up" with rate() bytes. Since lanes are stored internally as type uint64, this requires -// converting the incoming bytes into uint64s using a little endian interpretation. This -// implementation is optimized for large, aligned writes of multiples of 8 bytes (laneSize). -// Non-aligned or uneven numbers of bytes require shifting and are slower. -func (d *digest) Write(p []byte) (int, error) { - // An initial offset is needed if the we aren't absorbing to the first lane initially. - offset := d.absorbed % d.rate() - toWrite := len(p) - - // The first lane may need to absorb unaligned and/or incomplete data. - if (offset%laneSize != 0 || len(p) < 8) && len(p) > 0 { - toAbsorb := minInt(laneSize-(offset%laneSize), len(p)) - d.unalignedAbsorb(p[:toAbsorb]) - p = p[toAbsorb:] - offset = (d.absorbed) % d.rate() - - // For every rate() bytes absorbed, the state must be permuted via the F Function. - if (d.absorbed)%d.rate() == 0 { - d.keccakF() - } - } - - // This loop should absorb the bulk of the data into full, aligned lanes. - // It will call the update function as necessary. - for len(p) > 7 { - firstLane := offset / laneSize - lastLane := minInt(d.rate()/laneSize, firstLane+len(p)/laneSize) - - // This inner loop absorbs input bytes into the state in groups of 8, converted to uint64s. - for lane := firstLane; lane < lastLane; lane++ { - d.a[lane] ^= binary.LittleEndian.Uint64(p[:laneSize]) - p = p[laneSize:] - } - d.absorbed += (lastLane - firstLane) * laneSize - // For every rate() bytes absorbed, the state must be permuted via the F Function. - if (d.absorbed)%d.rate() == 0 { - d.keccakF() - } - - offset = 0 - } - - // If there are insufficient bytes to fill the final lane, an unaligned absorption. - // This should always start at a correct lane boundary though, or else it would be caught - // by the uneven opening lane case above. - if len(p) > 0 { - d.unalignedAbsorb(p) - } - - return toWrite, nil -} - -// pad computes the SHA3 padding scheme based on the number of bytes absorbed. -// The padding is a 1 bit, followed by an arbitrary number of 0s and then a final 1 bit, such that -// the input bits plus padding bits are a multiple of rate(). Adding the padding simply requires -// xoring an opening and closing bit into the appropriate lanes. -func (d *digest) pad() { - offset := d.absorbed % d.rate() - // The opening pad bit must be shifted into position based on the number of bytes absorbed - padOpenLane := offset / laneSize - d.a[padOpenLane] ^= 0x0000000000000001 << uint(8*(offset%laneSize)) - // The closing padding bit is always in the last position - padCloseLane := (d.rate() / laneSize) - 1 - d.a[padCloseLane] ^= 0x8000000000000000 -} - -// finalize prepares the hash to output data by padding and one final permutation of the state. -func (d *digest) finalize() { - d.pad() - d.keccakF() -} - -// squeeze outputs an arbitrary number of bytes from the hash state. -// Squeezing can require multiple calls to the F function (one per rate() bytes squeezed), -// although this is not the case for standard SHA3 parameters. This implementation only supports -// squeezing a single time, subsequent squeezes may lose alignment. Future implementations -// may wish to support multiple squeeze calls, for example to support use as a PRNG. -func (d *digest) squeeze(in []byte, toSqueeze int) []byte { - // Because we read in blocks of laneSize, we need enough room to read - // an integral number of lanes - needed := toSqueeze + (laneSize-toSqueeze%laneSize)%laneSize - if cap(in)-len(in) < needed { - newIn := make([]byte, len(in), len(in)+needed) - copy(newIn, in) - in = newIn - } - out := in[len(in) : len(in)+needed] - - for len(out) > 0 { - for i := 0; i < d.rate() && len(out) > 0; i += laneSize { - binary.LittleEndian.PutUint64(out[:], d.a[i/laneSize]) - out = out[laneSize:] - } - if len(out) > 0 { - d.keccakF() - } - } - return in[:len(in)+toSqueeze] // Re-slice in case we wrote extra data. -} - -// Sum applies padding to the hash state and then squeezes out the desired nubmer of output bytes. -func (d *digest) Sum(in []byte) []byte { - // Make a copy of the original hash so that caller can keep writing and summing. - dup := *d - dup.finalize() - return dup.squeeze(in, dup.outputSize) -} - -// The NewKeccakX constructors enable initializing a hash in any of the four recommend sizes -// from the Keccak specification, all of which set capacity=2*outputSize. Note that the final -// NIST standard for SHA3 may specify different input/output lengths. -// The output size is indicated in bits but converted into bytes internally. -func NewKeccak224() hash.Hash { return &digest{outputSize: 224 / 8, capacity: 2 * 224 / 8} } -func NewKeccak256() hash.Hash { return &digest{outputSize: 256 / 8, capacity: 2 * 256 / 8} } -func NewKeccak384() hash.Hash { return &digest{outputSize: 384 / 8, capacity: 2 * 384 / 8} } -func NewKeccak512() hash.Hash { return &digest{outputSize: 512 / 8, capacity: 2 * 512 / 8} } - -func Sha3(data ...[]byte) []byte { - d := NewKeccak256() - for _, b := range data { - d.Write(b) - } - return d.Sum(nil) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/snative.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/snative.go deleted file mode 100644 index 2fd3b0f9..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/snative.go +++ /dev/null @@ -1,233 +0,0 @@ -package vm - -import ( - "fmt" - - . "github.com/tendermint/tendermint/common" - ptypes "github.com/tendermint/tendermint/permission/types" -) - -// TODO: ABI -//------------------------------------------------------------------------------------------------ -// Registered SNative contracts - -func registerSNativeContracts() { - registeredNativeContracts[LeftPadWord256([]byte("has_base"))] = hasBasePerm - registeredNativeContracts[LeftPadWord256([]byte("set_base"))] = setBasePerm - registeredNativeContracts[LeftPadWord256([]byte("unset_base"))] = unsetBasePerm - registeredNativeContracts[LeftPadWord256([]byte("set_global"))] = setGlobalPerm - registeredNativeContracts[LeftPadWord256([]byte("has_role"))] = hasRole - registeredNativeContracts[LeftPadWord256([]byte("add_role"))] = addRole - registeredNativeContracts[LeftPadWord256([]byte("rm_role"))] = rmRole -} - -//----------------------------------------------------------------------------- -// snative are native contracts that can access and modify an account's permissions - -// TODO: catch errors, log em, return 0s to the vm (should some errors cause exceptions though?) - -func hasBasePerm(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) { - if !HasPermission(appState, caller, ptypes.HasBase) { - return nil, ErrInvalidPermission{caller.Address, "has_base"} - } - if len(args) != 2*32 { - return nil, fmt.Errorf("hasBasePerm() takes two arguments (address, permFlag)") - } - addr, permNum := returnTwoArgs(args) - vmAcc := appState.GetAccount(addr) - if vmAcc == nil { - return nil, fmt.Errorf("Unknown account %X", addr) - } - permN := ptypes.PermFlag(Uint64FromWord256(permNum)) // already shifted - if !ValidPermN(permN) { - return nil, ptypes.ErrInvalidPermission(permN) - } - var permInt byte - if HasPermission(appState, vmAcc, permN) { - permInt = 0x1 - } else { - permInt = 0x0 - } - dbg.Printf("snative.hasBasePerm(0x%X, %b) = %v\n", addr.Postfix(20), permN, permInt) - return LeftPadWord256([]byte{permInt}).Bytes(), nil -} - -func setBasePerm(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) { - if !HasPermission(appState, caller, ptypes.SetBase) { - return nil, ErrInvalidPermission{caller.Address, "set_base"} - } - if len(args) != 3*32 { - return nil, fmt.Errorf("setBase() takes three arguments (address, permFlag, permission value)") - } - addr, permNum, perm := returnThreeArgs(args) - vmAcc := appState.GetAccount(addr) - if vmAcc == nil { - return nil, fmt.Errorf("Unknown account %X", addr) - } - permN := ptypes.PermFlag(Uint64FromWord256(permNum)) - if !ValidPermN(permN) { - return nil, ptypes.ErrInvalidPermission(permN) - } - permV := !perm.IsZero() - if err = vmAcc.Permissions.Base.Set(permN, permV); err != nil { - return nil, err - } - appState.UpdateAccount(vmAcc) - dbg.Printf("snative.setBasePerm(0x%X, %b, %v)\n", addr.Postfix(20), permN, permV) - return perm.Bytes(), nil -} - -func unsetBasePerm(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) { - if !HasPermission(appState, caller, ptypes.UnsetBase) { - return nil, ErrInvalidPermission{caller.Address, "unset_base"} - } - if len(args) != 2*32 { - return nil, fmt.Errorf("unsetBase() takes two arguments (address, permFlag)") - } - addr, permNum := returnTwoArgs(args) - vmAcc := appState.GetAccount(addr) - if vmAcc == nil { - return nil, fmt.Errorf("Unknown account %X", addr) - } - permN := ptypes.PermFlag(Uint64FromWord256(permNum)) - if !ValidPermN(permN) { - return nil, ptypes.ErrInvalidPermission(permN) - } - if err = vmAcc.Permissions.Base.Unset(permN); err != nil { - return nil, err - } - appState.UpdateAccount(vmAcc) - dbg.Printf("snative.unsetBasePerm(0x%X, %b)\n", addr.Postfix(20), permN) - return permNum.Bytes(), nil -} - -func setGlobalPerm(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) { - if !HasPermission(appState, caller, ptypes.SetGlobal) { - return nil, ErrInvalidPermission{caller.Address, "set_global"} - } - if len(args) != 2*32 { - return nil, fmt.Errorf("setGlobal() takes two arguments (permFlag, permission value)") - } - permNum, perm := returnTwoArgs(args) - vmAcc := appState.GetAccount(ptypes.GlobalPermissionsAddress256) - if vmAcc == nil { - PanicSanity("cant find the global permissions account") - } - permN := ptypes.PermFlag(Uint64FromWord256(permNum)) - if !ValidPermN(permN) { - return nil, ptypes.ErrInvalidPermission(permN) - } - permV := !perm.IsZero() - if err = vmAcc.Permissions.Base.Set(permN, permV); err != nil { - return nil, err - } - appState.UpdateAccount(vmAcc) - dbg.Printf("snative.setGlobalPerm(%b, %v)\n", permN, permV) - return perm.Bytes(), nil -} - -func hasRole(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) { - if !HasPermission(appState, caller, ptypes.HasRole) { - return nil, ErrInvalidPermission{caller.Address, "has_role"} - } - if len(args) != 2*32 { - return nil, fmt.Errorf("hasRole() takes two arguments (address, role)") - } - addr, role := returnTwoArgs(args) - vmAcc := appState.GetAccount(addr) - if vmAcc == nil { - return nil, fmt.Errorf("Unknown account %X", addr) - } - roleS := string(role.Bytes()) - var permInt byte - if vmAcc.Permissions.HasRole(roleS) { - permInt = 0x1 - } else { - permInt = 0x0 - } - dbg.Printf("snative.hasRole(0x%X, %s) = %v\n", addr.Postfix(20), roleS, permInt > 0) - return LeftPadWord256([]byte{permInt}).Bytes(), nil -} - -func addRole(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) { - if !HasPermission(appState, caller, ptypes.AddRole) { - return nil, ErrInvalidPermission{caller.Address, "add_role"} - } - if len(args) != 2*32 { - return nil, fmt.Errorf("addRole() takes two arguments (address, role)") - } - addr, role := returnTwoArgs(args) - vmAcc := appState.GetAccount(addr) - if vmAcc == nil { - return nil, fmt.Errorf("Unknown account %X", addr) - } - roleS := string(role.Bytes()) - var permInt byte - if vmAcc.Permissions.AddRole(roleS) { - permInt = 0x1 - } else { - permInt = 0x0 - } - appState.UpdateAccount(vmAcc) - dbg.Printf("snative.addRole(0x%X, %s) = %v\n", addr.Postfix(20), roleS, permInt > 0) - return LeftPadWord256([]byte{permInt}).Bytes(), nil -} - -func rmRole(appState AppState, caller *Account, args []byte, gas *int64) (output []byte, err error) { - if !HasPermission(appState, caller, ptypes.RmRole) { - return nil, ErrInvalidPermission{caller.Address, "rm_role"} - } - if len(args) != 2*32 { - return nil, fmt.Errorf("rmRole() takes two arguments (address, role)") - } - addr, role := returnTwoArgs(args) - vmAcc := appState.GetAccount(addr) - if vmAcc == nil { - return nil, fmt.Errorf("Unknown account %X", addr) - } - roleS := string(role.Bytes()) - var permInt byte - if vmAcc.Permissions.RmRole(roleS) { - permInt = 0x1 - } else { - permInt = 0x0 - } - appState.UpdateAccount(vmAcc) - dbg.Printf("snative.rmRole(0x%X, %s) = %v\n", addr.Postfix(20), roleS, permInt > 0) - return LeftPadWord256([]byte{permInt}).Bytes(), nil -} - -//------------------------------------------------------------------------------------------------ -// Errors and utility funcs - -type ErrInvalidPermission struct { - Address Word256 - SNative string -} - -func (e ErrInvalidPermission) Error() string { - return fmt.Sprintf("Account %X does not have permission snative.%s", e.Address.Postfix(20), e.SNative) -} - -// Checks if a permission flag is valid (a known base chain or snative permission) -func ValidPermN(n ptypes.PermFlag) bool { - if n > ptypes.TopPermFlag { - return false - } - return true -} - -// CONTRACT: length has already been checked -func returnTwoArgs(args []byte) (a Word256, b Word256) { - copy(a[:], args[:32]) - copy(b[:], args[32:64]) - return -} - -// CONTRACT: length has already been checked -func returnThreeArgs(args []byte) (a Word256, b Word256, c Word256) { - copy(a[:], args[:32]) - copy(b[:], args[32:64]) - copy(c[:], args[64:96]) - return -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/stack.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/stack.go deleted file mode 100644 index 7dae3e71..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/stack.go +++ /dev/null @@ -1,126 +0,0 @@ -package vm - -import ( - "fmt" - . "github.com/tendermint/tendermint/common" -) - -// Not goroutine safe -type Stack struct { - data []Word256 - ptr int - - gas *int64 - err *error -} - -func NewStack(capacity int, gas *int64, err *error) *Stack { - return &Stack{ - data: make([]Word256, capacity), - ptr: 0, - gas: gas, - err: err, - } -} - -func (st *Stack) useGas(gasToUse int64) { - if *st.gas > gasToUse { - *st.gas -= gasToUse - } else { - st.setErr(ErrInsufficientGas) - } -} - -func (st *Stack) setErr(err error) { - if *st.err == nil { - *st.err = err - } -} - -func (st *Stack) Push(d Word256) { - st.useGas(GasStackOp) - if st.ptr == cap(st.data) { - st.setErr(ErrDataStackOverflow) - return - } - st.data[st.ptr] = d - st.ptr++ -} - -// currently only called after Sha3 -func (st *Stack) PushBytes(bz []byte) { - if len(bz) != 32 { - PanicSanity("Invalid bytes size: expected 32") - } - st.Push(LeftPadWord256(bz)) -} - -func (st *Stack) Push64(i int64) { - st.Push(Int64ToWord256(i)) -} - -func (st *Stack) Pop() Word256 { - st.useGas(GasStackOp) - if st.ptr == 0 { - st.setErr(ErrDataStackUnderflow) - return Zero256 - } - st.ptr-- - return st.data[st.ptr] -} - -func (st *Stack) PopBytes() []byte { - return st.Pop().Bytes() -} - -func (st *Stack) Pop64() int64 { - d := st.Pop() - return Int64FromWord256(d) -} - -func (st *Stack) Len() int { - return st.ptr -} - -func (st *Stack) Swap(n int) { - st.useGas(GasStackOp) - if st.ptr < n { - st.setErr(ErrDataStackUnderflow) - return - } - st.data[st.ptr-n], st.data[st.ptr-1] = st.data[st.ptr-1], st.data[st.ptr-n] - return -} - -func (st *Stack) Dup(n int) { - st.useGas(GasStackOp) - if st.ptr < n { - st.setErr(ErrDataStackUnderflow) - return - } - st.Push(st.data[st.ptr-n]) - return -} - -// Not an opcode, costs no gas. -func (st *Stack) Peek() Word256 { - if st.ptr == 0 { - st.setErr(ErrDataStackUnderflow) - return Zero256 - } - return st.data[st.ptr-1] -} - -func (st *Stack) Print(n int) { - fmt.Println("### stack ###") - if st.ptr > 0 { - nn := MinInt(n, st.ptr) - for j, i := 0, st.ptr-1; i > st.ptr-1-nn; i-- { - fmt.Printf("%-3d %X\n", j, st.data[i]) - j += 1 - } - } else { - fmt.Println("-- empty --") - } - fmt.Println("#############") -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/fake_app_state.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/fake_app_state.go deleted file mode 100644 index 72dcca58..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/fake_app_state.go +++ /dev/null @@ -1,79 +0,0 @@ -package vm - -import ( - . "github.com/tendermint/tendermint/common" - . "github.com/tendermint/tendermint/vm" - "github.com/tendermint/tendermint/vm/sha3" -) - -type FakeAppState struct { - accounts map[string]*Account - storage map[string]Word256 -} - -func (fas *FakeAppState) GetAccount(addr Word256) *Account { - account := fas.accounts[addr.String()] - return account -} - -func (fas *FakeAppState) UpdateAccount(account *Account) { - fas.accounts[account.Address.String()] = account -} - -func (fas *FakeAppState) RemoveAccount(account *Account) { - _, ok := fas.accounts[account.Address.String()] - if !ok { - panic(Fmt("Invalid account addr: %X", account.Address)) - } else { - // Remove account - delete(fas.accounts, account.Address.String()) - } -} - -func (fas *FakeAppState) CreateAccount(creator *Account) *Account { - addr := createAddress(creator) - account := fas.accounts[addr.String()] - if account == nil { - return &Account{ - Address: addr, - Balance: 0, - Code: nil, - Nonce: 0, - } - } else { - panic(Fmt("Invalid account addr: %X", addr)) - } -} - -func (fas *FakeAppState) GetStorage(addr Word256, key Word256) Word256 { - _, ok := fas.accounts[addr.String()] - if !ok { - panic(Fmt("Invalid account addr: %X", addr)) - } - - value, ok := fas.storage[addr.String()+key.String()] - if ok { - return value - } else { - return Zero256 - } -} - -func (fas *FakeAppState) SetStorage(addr Word256, key Word256, value Word256) { - _, ok := fas.accounts[addr.String()] - if !ok { - panic(Fmt("Invalid account addr: %X", addr)) - } - - fas.storage[addr.String()+key.String()] = value -} - -// Creates a 20 byte address and bumps the nonce. -func createAddress(creator *Account) Word256 { - nonce := creator.Nonce - creator.Nonce += 1 - temp := make([]byte, 32+8) - copy(temp, creator.Address[:]) - PutInt64BE(temp[32:], nonce) - return LeftPadWord256(sha3.Sha3(temp)[:20]) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/log_event_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/log_event_test.go deleted file mode 100644 index fa598b00..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/log_event_test.go +++ /dev/null @@ -1,90 +0,0 @@ -package vm - -import ( - "bytes" - "reflect" - "testing" - - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/types" - . "github.com/tendermint/tendermint/vm" -) - -var expectedData = []byte{0x10} -var expectedHeight int64 = 0 -var expectedTopics = []Word256{ - Int64ToWord256(1), - Int64ToWord256(2), - Int64ToWord256(3), - Int64ToWord256(4)} - -// Tests logs and events. -func TestLog4(t *testing.T) { - - st := newAppState() - // Create accounts - account1 := &Account{ - Address: LeftPadWord256(makeBytes(20)), - } - account2 := &Account{ - Address: LeftPadWord256(makeBytes(20)), - } - st.accounts[account1.Address.String()] = account1 - st.accounts[account2.Address.String()] = account2 - - ourVm := NewVM(st, newParams(), Zero256, nil) - - eventSwitch := events.NewEventSwitch() - _, err := eventSwitch.Start() - if err != nil { - t.Errorf("Failed to start eventSwitch: %v", err) - } - eventID := types.EventStringLogEvent(account2.Address.Postfix(20)) - - doneChan := make(chan struct{}, 1) - - eventSwitch.AddListenerForEvent("test", eventID, func(event types.EventData) { - logEvent := event.(types.EventDataLog) - // No need to test address as this event would not happen if it wasn't correct - if !reflect.DeepEqual(logEvent.Topics, expectedTopics) { - t.Errorf("Event topics are wrong. Got: %v. Expected: %v", logEvent.Topics, expectedTopics) - } - if !bytes.Equal(logEvent.Data, expectedData) { - t.Errorf("Event data is wrong. Got: %s. Expected: %s", logEvent.Data, expectedData) - } - if logEvent.Height != expectedHeight { - t.Errorf("Event block height is wrong. Got: %d. Expected: %d", logEvent.Height, expectedHeight) - } - doneChan <- struct{}{} - }) - - ourVm.SetFireable(eventSwitch) - - var gas int64 = 100000 - - mstore8 := byte(MSTORE8) - push1 := byte(PUSH1) - log4 := byte(LOG4) - stop := byte(STOP) - - code := []byte{ - push1, 16, // data value - push1, 0, // memory slot - mstore8, - push1, 4, // topic 4 - push1, 3, // topic 3 - push1, 2, // topic 2 - push1, 1, // topic 1 - push1, 1, // size of data - push1, 0, // data starts at this offset - log4, - stop, - } - - _, err = ourVm.Call(account1, account2, code, []byte{}, 0, &gas) - <-doneChan - if err != nil { - t.Fatal(err) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go deleted file mode 100644 index dc268a6a..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go +++ /dev/null @@ -1,207 +0,0 @@ -package vm - -import ( - "crypto/rand" - "encoding/hex" - "fmt" - "strings" - "testing" - "time" - - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - ptypes "github.com/tendermint/tendermint/permission/types" - "github.com/tendermint/tendermint/types" - . "github.com/tendermint/tendermint/vm" -) - -func newAppState() *FakeAppState { - fas := &FakeAppState{ - accounts: make(map[string]*Account), - storage: make(map[string]Word256), - } - // For default permissions - fas.accounts[ptypes.GlobalPermissionsAddress256.String()] = &Account{ - Permissions: ptypes.DefaultAccountPermissions, - } - return fas -} - -func newParams() Params { - return Params{ - BlockHeight: 0, - BlockHash: Zero256, - BlockTime: 0, - GasLimit: 0, - } -} - -func makeBytes(n int) []byte { - b := make([]byte, n) - rand.Read(b) - return b -} - -// Runs a basic loop -func TestVM(t *testing.T) { - ourVm := NewVM(newAppState(), newParams(), Zero256, nil) - - // Create accounts - account1 := &Account{ - Address: Int64ToWord256(100), - } - account2 := &Account{ - Address: Int64ToWord256(101), - } - - var gas int64 = 100000 - N := []byte{0x0f, 0x0f} - // Loop N times - code := []byte{0x60, 0x00, 0x60, 0x20, 0x52, 0x5B, byte(0x60 + len(N) - 1)} - code = append(code, N...) - code = append(code, []byte{0x60, 0x20, 0x51, 0x12, 0x15, 0x60, byte(0x1b + len(N)), 0x57, 0x60, 0x01, 0x60, 0x20, 0x51, 0x01, 0x60, 0x20, 0x52, 0x60, 0x05, 0x56, 0x5B}...) - start := time.Now() - output, err := ourVm.Call(account1, account2, code, []byte{}, 0, &gas) - fmt.Printf("Output: %v Error: %v\n", output, err) - fmt.Println("Call took:", time.Since(start)) - if err != nil { - t.Fatal(err) - } -} - -// Tests the code for a subcurrency contract compiled by serpent -func TestSubcurrency(t *testing.T) { - st := newAppState() - // Create accounts - account1 := &Account{ - Address: LeftPadWord256(makeBytes(20)), - } - account2 := &Account{ - Address: LeftPadWord256(makeBytes(20)), - } - st.accounts[account1.Address.String()] = account1 - st.accounts[account2.Address.String()] = account2 - - ourVm := NewVM(st, newParams(), Zero256, nil) - - var gas int64 = 1000 - code_parts := []string{"620f42403355", - "7c0100000000000000000000000000000000000000000000000000000000", - "600035046315cf268481141561004657", - "6004356040526040515460605260206060f35b63693200ce81141561008757", - "60043560805260243560a052335460c0523360e05260a05160c05112151561008657", - "60a05160c0510360e0515560a0516080515401608051555b5b505b6000f3"} - code, _ := hex.DecodeString(strings.Join(code_parts, "")) - fmt.Printf("Code: %x\n", code) - data, _ := hex.DecodeString("693200CE0000000000000000000000004B4363CDE27C2EB05E66357DB05BC5C88F850C1A0000000000000000000000000000000000000000000000000000000000000005") - output, err := ourVm.Call(account1, account2, code, data, 0, &gas) - fmt.Printf("Output: %v Error: %v\n", output, err) - if err != nil { - t.Fatal(err) - } -} - -// Test sending tokens from a contract to another account -func TestSendCall(t *testing.T) { - fakeAppState := newAppState() - ourVm := NewVM(fakeAppState, newParams(), Zero256, nil) - - // Create accounts - account1 := &Account{ - Address: Int64ToWord256(100), - } - account2 := &Account{ - Address: Int64ToWord256(101), - } - account3 := &Account{ - Address: Int64ToWord256(102), - } - - // account1 will call account2 which will trigger CALL opcode to account3 - addr := account3.Address.Postfix(20) - contractCode := callContractCode(addr) - - //---------------------------------------------- - // account2 has insufficient balance, should fail - fmt.Println("Should fail with insufficient balance") - - exception := runVMWaitEvents(t, ourVm, account1, account2, addr, contractCode, 1000) - if exception == "" { - t.Fatal("Expected exception") - } - - //---------------------------------------------- - // give account2 sufficient balance, should pass - - account2.Balance = 100000 - exception = runVMWaitEvents(t, ourVm, account1, account2, addr, contractCode, 1000) - if exception != "" { - t.Fatal("Unexpected exception", exception) - } - - //---------------------------------------------- - // insufficient gas, should fail - fmt.Println("Should fail with insufficient gas") - - account2.Balance = 100000 - exception = runVMWaitEvents(t, ourVm, account1, account2, addr, contractCode, 100) - if exception == "" { - t.Fatal("Expected exception") - } -} - -// subscribes to an AccCall, runs the vm, returns the exception -func runVMWaitEvents(t *testing.T, ourVm *VM, caller, callee *Account, subscribeAddr, contractCode []byte, gas int64) string { - // we need to catch the event from the CALL to check for exceptions - evsw := events.NewEventSwitch() - evsw.Start() - ch := make(chan interface{}) - fmt.Printf("subscribe to %x\n", subscribeAddr) - evsw.AddListenerForEvent("test", types.EventStringAccCall(subscribeAddr), func(msg types.EventData) { - ch <- msg - }) - evc := events.NewEventCache(evsw) - ourVm.SetFireable(evc) - go func() { - start := time.Now() - output, err := ourVm.Call(caller, callee, contractCode, []byte{}, 0, &gas) - fmt.Printf("Output: %v Error: %v\n", output, err) - fmt.Println("Call took:", time.Since(start)) - if err != nil { - ch <- err.Error() - } - evc.Flush() - }() - msg := <-ch - switch ev := msg.(type) { - case types.EventDataTx: - return ev.Exception - case types.EventDataCall: - return ev.Exception - case string: - return ev - } - return "" -} - -// this is code to call another contract (hardcoded as addr) -func callContractCode(addr []byte) []byte { - gas1, gas2 := byte(0x1), byte(0x1) - value := byte(0x69) - inOff, inSize := byte(0x0), byte(0x0) // no call data - retOff, retSize := byte(0x0), byte(0x20) - // this is the code we want to run (send funds to an account and return) - contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, 0x60, value, 0x73} - contractCode = append(contractCode, addr...) - contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...) - return contractCode -} - -/* - // infinite loop - code := []byte{0x5B, 0x60, 0x00, 0x56} - // mstore - code := []byte{0x60, 0x00, 0x60, 0x20} - // mstore, mload - code := []byte{0x60, 0x01, 0x60, 0x20, 0x52, 0x60, 0x20, 0x51} -*/ diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/types.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/types.go deleted file mode 100644 index cb9bc64f..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/types.go +++ /dev/null @@ -1,49 +0,0 @@ -package vm - -import ( - . "github.com/tendermint/tendermint/common" - ptypes "github.com/tendermint/tendermint/permission/types" -) - -const ( - defaultDataStackCapacity = 10 -) - -type Account struct { - Address Word256 - Balance int64 - Code []byte - Nonce int64 - Other interface{} // For holding all other data. - - Permissions ptypes.AccountPermissions -} - -func (acc *Account) String() string { - if acc == nil { - return "nil-VMAccount" - } - return Fmt("VMAccount{%X B:%v C:%X N:%v}", - acc.Address, acc.Balance, acc.Code, acc.Nonce) -} - -type AppState interface { - - // Accounts - GetAccount(addr Word256) *Account - UpdateAccount(*Account) - RemoveAccount(*Account) - CreateAccount(*Account) *Account - - // Storage - GetStorage(Word256, Word256) Word256 - SetStorage(Word256, Word256, Word256) // Setting to Zero is deleting. - -} - -type Params struct { - BlockHeight int64 - BlockHash Word256 - BlockTime int64 - GasLimit int64 -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go deleted file mode 100644 index 7d60752e..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go +++ /dev/null @@ -1,918 +0,0 @@ -package vm - -import ( - "bytes" - "errors" - "fmt" - "math/big" - - . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/events" - ptypes "github.com/tendermint/tendermint/permission/types" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/vm/sha3" -) - -var ( - ErrUnknownAddress = errors.New("Unknown address") - ErrInsufficientBalance = errors.New("Insufficient balance") - ErrInvalidJumpDest = errors.New("Invalid jump dest") - ErrInsufficientGas = errors.New("Insuffient gas") - ErrMemoryOutOfBounds = errors.New("Memory out of bounds") - ErrCodeOutOfBounds = errors.New("Code out of bounds") - ErrInputOutOfBounds = errors.New("Input out of bounds") - ErrCallStackOverflow = errors.New("Call stack overflow") - ErrCallStackUnderflow = errors.New("Call stack underflow") - ErrDataStackOverflow = errors.New("Data stack overflow") - ErrDataStackUnderflow = errors.New("Data stack underflow") - ErrInvalidContract = errors.New("Invalid contract") -) - -type ErrPermission struct { - typ string -} - -func (err ErrPermission) Error() string { - return fmt.Sprintf("Contract does not have permission to %s", err.typ) -} - -type Debug bool - -const ( - dataStackCapacity = 1024 - callStackCapacity = 100 // TODO ensure usage. - memoryCapacity = 1024 * 1024 // 1 MB - dbg Debug = true -) - -func (d Debug) Printf(s string, a ...interface{}) { - if d { - fmt.Printf(s, a...) - } -} - -type VM struct { - appState AppState - params Params - origin Word256 - txid []byte - - callDepth int - - evc events.Fireable -} - -func NewVM(appState AppState, params Params, origin Word256, txid []byte) *VM { - return &VM{ - appState: appState, - params: params, - origin: origin, - callDepth: 0, - txid: txid, - } -} - -// satisfies events.Eventable -func (vm *VM) SetFireable(evc events.Fireable) { - vm.evc = evc -} - -// CONTRACT: it is the duty of the contract writer to call known permissions -// we do not convey if a permission is not set -// (unlike in state/execution, where we guarantee HasPermission is called -// on known permissions and panics else) -// If the perm is not defined in the acc nor set by default in GlobalPermissions, -// prints a log warning and returns false. -func HasPermission(appState AppState, acc *Account, perm ptypes.PermFlag) bool { - v, err := acc.Permissions.Base.Get(perm) - if _, ok := err.(ptypes.ErrValueNotSet); ok { - if appState == nil { - log.Warn(Fmt("\n\n***** Unknown permission %b! ********\n\n", perm)) - return false - } - return HasPermission(nil, appState.GetAccount(ptypes.GlobalPermissionsAddress256), perm) - } - return v -} - -func (vm *VM) fireCallEvent(exception *string, output *[]byte, caller, callee *Account, input []byte, value int64, gas *int64) { - // fire the post call event (including exception if applicable) - if vm.evc != nil { - vm.evc.FireEvent(types.EventStringAccCall(callee.Address.Postfix(20)), types.EventDataCall{ - &types.CallData{caller.Address.Postfix(20), callee.Address.Postfix(20), input, value, *gas}, - vm.origin.Postfix(20), - vm.txid, - *output, - *exception, - }) - } -} - -// CONTRACT appState is aware of caller and callee, so we can just mutate them. -// value: To be transferred from caller to callee. Refunded upon error. -// gas: Available gas. No refunds for gas. -// code: May be nil, since the CALL opcode may be used to send value from contracts to accounts -func (vm *VM) Call(caller, callee *Account, code, input []byte, value int64, gas *int64) (output []byte, err error) { - - exception := new(string) - // fire the post call event (including exception if applicable) - defer vm.fireCallEvent(exception, &output, caller, callee, input, value, gas) - - if err = transfer(caller, callee, value); err != nil { - *exception = err.Error() - return - } - - if len(code) > 0 { - vm.callDepth += 1 - output, err = vm.call(caller, callee, code, input, value, gas) - vm.callDepth -= 1 - if err != nil { - *exception = err.Error() - err := transfer(callee, caller, value) - if err != nil { - // data has been corrupted in ram - PanicCrisis("Could not return value to caller") - } - } - } - - return -} - -// Try to deduct gasToUse from gasLeft. If ok return false, otherwise -// set err and return true. -func useGasNegative(gasLeft *int64, gasToUse int64, err *error) bool { - if *gasLeft >= gasToUse { - *gasLeft -= gasToUse - return false - } else if *err == nil { - *err = ErrInsufficientGas - } - return true -} - -// Just like Call() but does not transfer 'value' or modify the callDepth. -func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas *int64) (output []byte, err error) { - dbg.Printf("(%d) (%X) %X (code=%d) gas: %v (d) %X\n", vm.callDepth, caller.Address[:4], callee.Address, len(callee.Code), *gas, input) - - var ( - pc int64 = 0 - stack = NewStack(dataStackCapacity, gas, &err) - memory = make([]byte, memoryCapacity) - ) - - for { - - // Use BaseOp gas. - if useGasNegative(gas, GasBaseOp, &err) { - return nil, err - } - - var op = codeGetOp(code, pc) - dbg.Printf("(pc) %-3d (op) %-14s (st) %-4d ", pc, op.String(), stack.Len()) - - switch op { - - case ADD: // 0x01 - x, y := stack.Pop(), stack.Pop() - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - sum := new(big.Int).Add(xb, yb) - res := LeftPadWord256(U256(sum).Bytes()) - stack.Push(res) - dbg.Printf(" %v + %v = %v (%X)\n", xb, yb, sum, res) - - case MUL: // 0x02 - x, y := stack.Pop(), stack.Pop() - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - prod := new(big.Int).Mul(xb, yb) - res := LeftPadWord256(U256(prod).Bytes()) - stack.Push(res) - dbg.Printf(" %v * %v = %v (%X)\n", xb, yb, prod, res) - - case SUB: // 0x03 - x, y := stack.Pop(), stack.Pop() - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - diff := new(big.Int).Sub(xb, yb) - res := LeftPadWord256(U256(diff).Bytes()) - stack.Push(res) - dbg.Printf(" %v - %v = %v (%X)\n", xb, yb, diff, res) - - case DIV: // 0x04 - x, y := stack.Pop(), stack.Pop() - if y.IsZero() { - stack.Push(Zero256) - dbg.Printf(" %x / %x = %v\n", x, y, 0) - } else { - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - div := new(big.Int).Div(xb, yb) - res := LeftPadWord256(U256(div).Bytes()) - stack.Push(res) - dbg.Printf(" %v / %v = %v (%X)\n", xb, yb, div, res) - } - - case SDIV: // 0x05 - x, y := stack.Pop(), stack.Pop() - if y.IsZero() { - stack.Push(Zero256) - dbg.Printf(" %x / %x = %v\n", x, y, 0) - } else { - xb := S256(new(big.Int).SetBytes(x[:])) - yb := S256(new(big.Int).SetBytes(y[:])) - div := new(big.Int).Div(xb, yb) - res := LeftPadWord256(U256(div).Bytes()) - stack.Push(res) - dbg.Printf(" %v / %v = %v (%X)\n", xb, yb, div, res) - } - - case MOD: // 0x06 - x, y := stack.Pop(), stack.Pop() - if y.IsZero() { - stack.Push(Zero256) - dbg.Printf(" %v %% %v = %v\n", x, y, 0) - } else { - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - mod := new(big.Int).Mod(xb, yb) - res := LeftPadWord256(U256(mod).Bytes()) - stack.Push(res) - dbg.Printf(" %v %% %v = %v (%X)\n", xb, yb, mod, res) - } - - case SMOD: // 0x07 - x, y := stack.Pop(), stack.Pop() - if y.IsZero() { - stack.Push(Zero256) - dbg.Printf(" %v %% %v = %v\n", x, y, 0) - } else { - xb := S256(new(big.Int).SetBytes(x[:])) - yb := S256(new(big.Int).SetBytes(y[:])) - mod := new(big.Int).Mod(xb, yb) - res := LeftPadWord256(U256(mod).Bytes()) - stack.Push(res) - dbg.Printf(" %v %% %v = %v (%X)\n", xb, yb, mod, res) - } - - case ADDMOD: // 0x08 - x, y, z := stack.Pop(), stack.Pop(), stack.Pop() - if z.IsZero() { - stack.Push(Zero256) - dbg.Printf(" %v %% %v = %v\n", x, y, 0) - } else { - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - zb := new(big.Int).SetBytes(z[:]) - add := new(big.Int).Add(xb, yb) - mod := new(big.Int).Mod(add, zb) - res := LeftPadWord256(U256(mod).Bytes()) - stack.Push(res) - dbg.Printf(" %v + %v %% %v = %v (%X)\n", - xb, yb, zb, mod, res) - } - - case MULMOD: // 0x09 - x, y, z := stack.Pop(), stack.Pop(), stack.Pop() - if z.IsZero() { - stack.Push(Zero256) - dbg.Printf(" %v %% %v = %v\n", x, y, 0) - } else { - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - zb := new(big.Int).SetBytes(z[:]) - mul := new(big.Int).Mul(xb, yb) - mod := new(big.Int).Mod(mul, zb) - res := LeftPadWord256(U256(mod).Bytes()) - stack.Push(res) - dbg.Printf(" %v * %v %% %v = %v (%X)\n", - xb, yb, zb, mod, res) - } - - case EXP: // 0x0A - x, y := stack.Pop(), stack.Pop() - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - pow := new(big.Int).Exp(xb, yb, big.NewInt(0)) - res := LeftPadWord256(U256(pow).Bytes()) - stack.Push(res) - dbg.Printf(" %v ** %v = %v (%X)\n", xb, yb, pow, res) - - case SIGNEXTEND: // 0x0B - back := stack.Pop() - backb := new(big.Int).SetBytes(back[:]) - if backb.Cmp(big.NewInt(31)) < 0 { - bit := uint(backb.Uint64()*8 + 7) - num := stack.Pop() - numb := new(big.Int).SetBytes(num[:]) - mask := new(big.Int).Lsh(big.NewInt(1), bit) - mask.Sub(mask, big.NewInt(1)) - if numb.Bit(int(bit)) == 1 { - numb.Or(numb, mask.Not(mask)) - } else { - numb.Add(numb, mask) - } - res := LeftPadWord256(U256(numb).Bytes()) - dbg.Printf(" = %v (%X)", numb, res) - stack.Push(res) - } - - case LT: // 0x10 - x, y := stack.Pop(), stack.Pop() - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - if xb.Cmp(yb) < 0 { - stack.Push64(1) - dbg.Printf(" %v < %v = %v\n", xb, yb, 1) - } else { - stack.Push(Zero256) - dbg.Printf(" %v < %v = %v\n", xb, yb, 0) - } - - case GT: // 0x11 - x, y := stack.Pop(), stack.Pop() - xb := new(big.Int).SetBytes(x[:]) - yb := new(big.Int).SetBytes(y[:]) - if xb.Cmp(yb) > 0 { - stack.Push64(1) - dbg.Printf(" %v > %v = %v\n", xb, yb, 1) - } else { - stack.Push(Zero256) - dbg.Printf(" %v > %v = %v\n", xb, yb, 0) - } - - case SLT: // 0x12 - x, y := stack.Pop(), stack.Pop() - xb := S256(new(big.Int).SetBytes(x[:])) - yb := S256(new(big.Int).SetBytes(y[:])) - if xb.Cmp(yb) < 0 { - stack.Push64(1) - dbg.Printf(" %v < %v = %v\n", xb, yb, 1) - } else { - stack.Push(Zero256) - dbg.Printf(" %v < %v = %v\n", xb, yb, 0) - } - - case SGT: // 0x13 - x, y := stack.Pop(), stack.Pop() - xb := S256(new(big.Int).SetBytes(x[:])) - yb := S256(new(big.Int).SetBytes(y[:])) - if xb.Cmp(yb) > 0 { - stack.Push64(1) - dbg.Printf(" %v > %v = %v\n", xb, yb, 1) - } else { - stack.Push(Zero256) - dbg.Printf(" %v > %v = %v\n", xb, yb, 0) - } - - case EQ: // 0x14 - x, y := stack.Pop(), stack.Pop() - if bytes.Equal(x[:], y[:]) { - stack.Push64(1) - dbg.Printf(" %X == %X = %v\n", x, y, 1) - } else { - stack.Push(Zero256) - dbg.Printf(" %X == %X = %v\n", x, y, 0) - } - - case ISZERO: // 0x15 - x := stack.Pop() - if x.IsZero() { - stack.Push64(1) - dbg.Printf(" %v == 0 = %v\n", x, 1) - } else { - stack.Push(Zero256) - dbg.Printf(" %v == 0 = %v\n", x, 0) - } - - case AND: // 0x16 - x, y := stack.Pop(), stack.Pop() - z := [32]byte{} - for i := 0; i < 32; i++ { - z[i] = x[i] & y[i] - } - stack.Push(z) - dbg.Printf(" %X & %X = %X\n", x, y, z) - - case OR: // 0x17 - x, y := stack.Pop(), stack.Pop() - z := [32]byte{} - for i := 0; i < 32; i++ { - z[i] = x[i] | y[i] - } - stack.Push(z) - dbg.Printf(" %X | %X = %X\n", x, y, z) - - case XOR: // 0x18 - x, y := stack.Pop(), stack.Pop() - z := [32]byte{} - for i := 0; i < 32; i++ { - z[i] = x[i] ^ y[i] - } - stack.Push(z) - dbg.Printf(" %X ^ %X = %X\n", x, y, z) - - case NOT: // 0x19 - x := stack.Pop() - z := [32]byte{} - for i := 0; i < 32; i++ { - z[i] = ^x[i] - } - stack.Push(z) - dbg.Printf(" !%X = %X\n", x, z) - - case BYTE: // 0x1A - idx, val := stack.Pop64(), stack.Pop() - res := byte(0) - if idx < 32 { - res = val[idx] - } - stack.Push64(int64(res)) - dbg.Printf(" => 0x%X\n", res) - - case SHA3: // 0x20 - if useGasNegative(gas, GasSha3, &err) { - return nil, err - } - offset, size := stack.Pop64(), stack.Pop64() - data, ok := subslice(memory, offset, size) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - data = sha3.Sha3(data) - stack.PushBytes(data) - dbg.Printf(" => (%v) %X\n", size, data) - - case ADDRESS: // 0x30 - stack.Push(callee.Address) - dbg.Printf(" => %X\n", callee.Address) - - case BALANCE: // 0x31 - addr := stack.Pop() - if useGasNegative(gas, GasGetAccount, &err) { - return nil, err - } - acc := vm.appState.GetAccount(addr) - if acc == nil { - return nil, firstErr(err, ErrUnknownAddress) - } - balance := acc.Balance - stack.Push64(balance) - dbg.Printf(" => %v (%X)\n", balance, addr) - - case ORIGIN: // 0x32 - stack.Push(vm.origin) - dbg.Printf(" => %X\n", vm.origin) - - case CALLER: // 0x33 - stack.Push(caller.Address) - dbg.Printf(" => %X\n", caller.Address) - - case CALLVALUE: // 0x34 - stack.Push64(value) - dbg.Printf(" => %v\n", value) - - case CALLDATALOAD: // 0x35 - offset := stack.Pop64() - data, ok := subslice(input, offset, 32) - if !ok { - return nil, firstErr(err, ErrInputOutOfBounds) - } - res := LeftPadWord256(data) - stack.Push(res) - dbg.Printf(" => 0x%X\n", res) - - case CALLDATASIZE: // 0x36 - stack.Push64(int64(len(input))) - dbg.Printf(" => %d\n", len(input)) - - case CALLDATACOPY: // 0x37 - memOff := stack.Pop64() - inputOff := stack.Pop64() - length := stack.Pop64() - data, ok := subslice(input, inputOff, length) - if !ok { - return nil, firstErr(err, ErrInputOutOfBounds) - } - dest, ok := subslice(memory, memOff, length) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - copy(dest, data) - dbg.Printf(" => [%v, %v, %v] %X\n", memOff, inputOff, length, data) - - case CODESIZE: // 0x38 - l := int64(len(code)) - stack.Push64(l) - dbg.Printf(" => %d\n", l) - - case CODECOPY: // 0x39 - memOff := stack.Pop64() - codeOff := stack.Pop64() - length := stack.Pop64() - data, ok := subslice(code, codeOff, length) - if !ok { - return nil, firstErr(err, ErrCodeOutOfBounds) - } - dest, ok := subslice(memory, memOff, length) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - copy(dest, data) - dbg.Printf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data) - - case GASPRICE_DEPRECATED: // 0x3A - stack.Push(Zero256) - dbg.Printf(" => %X (GASPRICE IS DEPRECATED)\n") - - case EXTCODESIZE: // 0x3B - addr := stack.Pop() - if useGasNegative(gas, GasGetAccount, &err) { - return nil, err - } - acc := vm.appState.GetAccount(addr) - if acc == nil { - return nil, firstErr(err, ErrUnknownAddress) - } - code := acc.Code - l := int64(len(code)) - stack.Push64(l) - dbg.Printf(" => %d\n", l) - - case EXTCODECOPY: // 0x3C - addr := stack.Pop() - if useGasNegative(gas, GasGetAccount, &err) { - return nil, err - } - acc := vm.appState.GetAccount(addr) - if acc == nil { - return nil, firstErr(err, ErrUnknownAddress) - } - code := acc.Code - memOff := stack.Pop64() - codeOff := stack.Pop64() - length := stack.Pop64() - data, ok := subslice(code, codeOff, length) - if !ok { - return nil, firstErr(err, ErrCodeOutOfBounds) - } - dest, ok := subslice(memory, memOff, length) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - copy(dest, data) - dbg.Printf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data) - - case BLOCKHASH: // 0x40 - stack.Push(Zero256) - dbg.Printf(" => 0x%X (NOT SUPPORTED)\n", stack.Peek().Bytes()) - - case COINBASE: // 0x41 - stack.Push(Zero256) - dbg.Printf(" => 0x%X (NOT SUPPORTED)\n", stack.Peek().Bytes()) - - case TIMESTAMP: // 0x42 - time := vm.params.BlockTime - stack.Push64(int64(time)) - dbg.Printf(" => 0x%X\n", time) - - case BLOCKHEIGHT: // 0x43 - number := int64(vm.params.BlockHeight) - stack.Push64(number) - dbg.Printf(" => 0x%X\n", number) - - case GASLIMIT: // 0x45 - stack.Push64(vm.params.GasLimit) - dbg.Printf(" => %v\n", vm.params.GasLimit) - - case POP: // 0x50 - popped := stack.Pop() - dbg.Printf(" => 0x%X\n", popped) - - case MLOAD: // 0x51 - offset := stack.Pop64() - data, ok := subslice(memory, offset, 32) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - stack.Push(LeftPadWord256(data)) - dbg.Printf(" => 0x%X\n", data) - - case MSTORE: // 0x52 - offset, data := stack.Pop64(), stack.Pop() - dest, ok := subslice(memory, offset, 32) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - copy(dest, data[:]) - dbg.Printf(" => 0x%X\n", data) - - case MSTORE8: // 0x53 - offset, val := stack.Pop64(), byte(stack.Pop64()&0xFF) - if len(memory) <= int(offset) { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - memory[offset] = val - dbg.Printf(" => [%v] 0x%X\n", offset, val) - - case SLOAD: // 0x54 - loc := stack.Pop() - data := vm.appState.GetStorage(callee.Address, loc) - stack.Push(data) - dbg.Printf(" {0x%X : 0x%X}\n", loc, data) - - case SSTORE: // 0x55 - loc, data := stack.Pop(), stack.Pop() - if useGasNegative(gas, GasStorageUpdate, &err) { - return nil, err - } - vm.appState.SetStorage(callee.Address, loc, data) - dbg.Printf(" {0x%X : 0x%X}\n", loc, data) - - case JUMP: // 0x56 - err = jump(code, stack.Pop64(), &pc) - continue - - case JUMPI: // 0x57 - pos, cond := stack.Pop64(), stack.Pop() - if !cond.IsZero() { - err = jump(code, pos, &pc) - continue - } - dbg.Printf(" ~> false\n") - - case PC: // 0x58 - stack.Push64(pc) - - case MSIZE: // 0x59 - stack.Push64(int64(len(memory))) - - case GAS: // 0x5A - stack.Push64(*gas) - dbg.Printf(" => %X\n", *gas) - - case JUMPDEST: // 0x5B - dbg.Printf("\n") - // Do nothing - - case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: - a := int64(op - PUSH1 + 1) - codeSegment, ok := subslice(code, pc+1, a) - if !ok { - return nil, firstErr(err, ErrCodeOutOfBounds) - } - res := LeftPadWord256(codeSegment) - stack.Push(res) - pc += a - dbg.Printf(" => 0x%X\n", res) - //stack.Print(10) - - case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: - n := int(op - DUP1 + 1) - stack.Dup(n) - dbg.Printf(" => [%d] 0x%X\n", n, stack.Peek().Bytes()) - - case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16: - n := int(op - SWAP1 + 2) - stack.Swap(n) - dbg.Printf(" => [%d] %X\n", n, stack.Peek()) - //stack.Print(10) - - case LOG0, LOG1, LOG2, LOG3, LOG4: - n := int(op - LOG0) - topics := make([]Word256, n) - offset, size := stack.Pop64(), stack.Pop64() - for i := 0; i < n; i++ { - topics[i] = stack.Pop() - } - data, ok := subslice(memory, offset, size) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - if vm.evc != nil { - eventID := types.EventStringLogEvent(callee.Address.Postfix(20)) - fmt.Printf("eventID: %s\n", eventID) - log := types.EventDataLog{ - callee.Address, - topics, - data, - vm.params.BlockHeight, - } - vm.evc.FireEvent(eventID, log) - } - dbg.Printf(" => T:%X D:%X\n", topics, data) - - case CREATE: // 0xF0 - if !HasPermission(vm.appState, callee, ptypes.CreateContract) { - return nil, ErrPermission{"create_contract"} - } - contractValue := stack.Pop64() - offset, size := stack.Pop64(), stack.Pop64() - input, ok := subslice(memory, offset, size) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - - // Check balance - if callee.Balance < contractValue { - return nil, firstErr(err, ErrInsufficientBalance) - } - - // TODO charge for gas to create account _ the code length * GasCreateByte - - newAccount := vm.appState.CreateAccount(callee) - // Run the input to get the contract code. - ret, err_ := vm.Call(callee, newAccount, input, input, contractValue, gas) - if err_ != nil { - stack.Push(Zero256) - } else { - newAccount.Code = ret // Set the code - stack.Push(newAccount.Address) - } - - case CALL, CALLCODE: // 0xF1, 0xF2 - if !HasPermission(vm.appState, callee, ptypes.Call) { - return nil, ErrPermission{"call"} - } - gasLimit := stack.Pop64() - addr, value := stack.Pop(), stack.Pop64() - inOffset, inSize := stack.Pop64(), stack.Pop64() // inputs - retOffset, retSize := stack.Pop64(), stack.Pop64() // outputs - dbg.Printf(" => %X\n", addr) - - // Get the arguments from the memory - args, ok := subslice(memory, inOffset, inSize) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - - // Ensure that gasLimit is reasonable - if *gas < gasLimit { - return nil, firstErr(err, ErrInsufficientGas) - } else { - *gas -= gasLimit - // NOTE: we will return any used gas later. - } - - // Begin execution - var ret []byte - var err error - if nativeContract := registeredNativeContracts[addr]; nativeContract != nil { - // Native contract - ret, err = nativeContract(vm.appState, callee, args, &gasLimit) - - // for now we fire the Call event. maybe later we'll fire more particulars - var exception string - if err != nil { - exception = err.Error() - } - // NOTE: these fire call events and not particular events for eg name reg or permissions - vm.fireCallEvent(&exception, &ret, callee, &Account{Address: addr}, args, value, gas) - } else { - // EVM contract - if useGasNegative(gas, GasGetAccount, &err) { - return nil, err - } - acc := vm.appState.GetAccount(addr) - // since CALL is used also for sending funds, - // acc may not exist yet. This is an error for - // CALLCODE, but not for CALL, though I don't think - // ethereum actually cares - if op == CALLCODE { - if acc == nil { - return nil, firstErr(err, ErrUnknownAddress) - } - ret, err = vm.Call(callee, callee, acc.Code, args, value, gas) - } else { - if acc == nil { - // nil account means we're sending funds to a new account - if !HasPermission(vm.appState, caller, ptypes.CreateAccount) { - return nil, ErrPermission{"create_account"} - } - acc = &Account{Address: addr} - vm.appState.UpdateAccount(acc) - // send funds to new account - ret, err = vm.Call(callee, acc, acc.Code, args, value, gas) - } else { - // call standard contract - ret, err = vm.Call(callee, acc, acc.Code, args, value, gas) - } - } - } - - // Push result - if err != nil { - dbg.Printf("error on call: %s\n", err.Error()) - stack.Push(Zero256) - } else { - stack.Push(One256) - dest, ok := subslice(memory, retOffset, retSize) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - copy(dest, ret) - } - - // Handle remaining gas. - *gas += gasLimit - - dbg.Printf("resume %X (%v)\n", callee.Address, gas) - - case RETURN: // 0xF3 - offset, size := stack.Pop64(), stack.Pop64() - ret, ok := subslice(memory, offset, size) - if !ok { - return nil, firstErr(err, ErrMemoryOutOfBounds) - } - dbg.Printf(" => [%v, %v] (%d) 0x%X\n", offset, size, len(ret), ret) - return ret, nil - - case SUICIDE: // 0xFF - addr := stack.Pop() - if useGasNegative(gas, GasGetAccount, &err) { - return nil, err - } - // TODO if the receiver is , then make it the fee. (?) - // TODO: create account if doesn't exist (no reason not to) - receiver := vm.appState.GetAccount(addr) - if receiver == nil { - return nil, firstErr(err, ErrUnknownAddress) - } - balance := callee.Balance - receiver.Balance += balance - vm.appState.UpdateAccount(receiver) - vm.appState.RemoveAccount(callee) - dbg.Printf(" => (%X) %v\n", addr[:4], balance) - fallthrough - - case STOP: // 0x00 - return nil, nil - - default: - dbg.Printf("(pc) %-3v Invalid opcode %X\n", pc, op) - return nil, fmt.Errorf("Invalid opcode %X", op) - } - - pc++ - - } -} - -func subslice(data []byte, offset, length int64) (ret []byte, ok bool) { - size := int64(len(data)) - if size < offset { - return nil, false - } else if size < offset+length { - ret, ok = data[offset:], true - ret = RightPadBytes(ret, 32) - } else { - ret, ok = data[offset:offset+length], true - } - - return -} - -func rightMostBytes(data []byte, n int) []byte { - size := MinInt(len(data), n) - offset := len(data) - size - return data[offset:] -} - -func codeGetOp(code []byte, n int64) OpCode { - if int64(len(code)) <= n { - return OpCode(0) // stop - } else { - return OpCode(code[n]) - } -} - -func jump(code []byte, to int64, pc *int64) (err error) { - dest := codeGetOp(code, to) - if dest != JUMPDEST { - dbg.Printf(" ~> %v invalid jump dest %v\n", to, dest) - return ErrInvalidJumpDest - } - dbg.Printf(" ~> %v\n", to) - *pc = to - return nil -} - -func firstErr(errA, errB error) error { - if errA != nil { - return errA - } else { - return errB - } -} - -func transfer(from, to *Account, amount int64) error { - if from.Balance < amount { - return ErrInsufficientBalance - } else { - from.Balance -= amount - to.Balance += amount - return nil - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/log.go deleted file mode 100644 index 610b05f6..00000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/wire/log.go +++ /dev/null @@ -1,18 +0,0 @@ -package wire - -import ( - "github.com/tendermint/log15" - "github.com/tendermint/tendermint/logger" -) - -var log = logger.New("module", "binary") - -func init() { - log.SetHandler( - log15.LvlFilterHandler( - log15.LvlWarn, - //log15.LvlDebug, - logger.RootHandler(), - ), - ) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go new file mode 100644 index 00000000..f8478ba6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go @@ -0,0 +1,163 @@ +package server + +import ( + "bufio" + "fmt" + "io" + "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" +) + +// var maxNumberConnections = 2 + +func StartListener(protoAddr string, app types.Application) (net.Listener, error) { + parts := strings.SplitN(protoAddr, "://", 2) + proto, addr := parts[0], parts[1] + ln, err := net.Listen(proto, addr) + if err != nil { + return nil, err + } + + // A goroutine to accept a connection. + go func() { + // semaphore := make(chan struct{}, maxNumberConnections) + + for { + // semaphore <- struct{}{} + + // Accept a connection + fmt.Println("Waiting for new connection...") + conn, err := ln.Accept() + if err != nil { + Exit("Failed to accept connection") + } else { + fmt.Println("Accepted a new connection") + } + + appContext := app.Open() + closeConn := make(chan error, 2) // Push to signal connection closed + responses := make(chan types.Response, 1000) // A channel to buffer responses + + // Read requests from conn and deal with them + go handleRequests(appContext, closeConn, conn, responses) + // Pull responses from 'responses' and write them to conn. + go handleResponses(closeConn, responses, conn) + + go func() { + // Wait until signal to close connection + errClose := <-closeConn + if errClose != nil { + fmt.Printf("Connection error: %v\n", errClose) + } else { + fmt.Println("Connection was closed.") + } + + // Close the connection + err := conn.Close() + if err != nil { + fmt.Printf("Error in closing connection: %v\n", err) + } + + // Close the AppContext + err = appContext.Close() + if err != nil { + fmt.Printf("Error in closing app context: %v\n", err) + } + + // <-semaphore + }() + } + + }() + + return ln, nil +} + +// Read requests from conn and deal with them +func handleRequests(appC types.AppContext, closeConn chan error, conn net.Conn, responses chan<- types.Response) { + var count int + var bufReader = bufio.NewReader(conn) + for { + var n int + var err error + var req types.Request + wire.ReadBinaryPtr(&req, bufReader, 0, &n, &err) + if err != nil { + if err == io.EOF { + closeConn <- fmt.Errorf("Connection closed by client") + } else { + closeConn <- fmt.Errorf("Error in handleRequests: %v", err.Error()) + } + return + } + count++ + handleRequest(appC, req, responses) + } +} + +func handleRequest(appC types.AppContext, req types.Request, responses chan<- types.Response) { + switch req := req.(type) { + case types.RequestEcho: + msg := appC.Echo(req.Message) + responses <- types.ResponseEcho{msg} + case types.RequestFlush: + responses <- types.ResponseFlush{} + case types.RequestInfo: + data := appC.Info() + responses <- types.ResponseInfo{data} + case types.RequestSetOption: + retCode := appC.SetOption(req.Key, req.Value) + responses <- types.ResponseSetOption{retCode} + case types.RequestAppendTx: + events, retCode := appC.AppendTx(req.TxBytes) + responses <- types.ResponseAppendTx{retCode} + for _, event := range events { + responses <- types.ResponseEvent{event} + } + case types.RequestGetHash: + hash, retCode := appC.GetHash() + responses <- types.ResponseGetHash{retCode, hash} + case types.RequestCommit: + retCode := appC.Commit() + responses <- types.ResponseCommit{retCode} + case types.RequestRollback: + retCode := appC.Rollback() + responses <- types.ResponseRollback{retCode} + case types.RequestAddListener: + retCode := appC.AddListener(req.EventKey) + responses <- types.ResponseAddListener{retCode} + case types.RequestRemListener: + retCode := appC.RemListener(req.EventKey) + responses <- types.ResponseRemListener{retCode} + default: + responses <- types.ResponseException{"Unknown request"} + } +} + +// Pull responses from 'responses' and write them to conn. +func handleResponses(closeConn chan error, responses <-chan types.Response, conn net.Conn) { + var count int + var bufWriter = bufio.NewWriter(conn) + for { + var res = <-responses + var n int + var err error + wire.WriteBinary(res, bufWriter, &n, &err) + if err != nil { + closeConn <- fmt.Errorf("Error in handleResponses: %v", err.Error()) + return + } + if _, ok := res.(types.ResponseFlush); ok { + err = bufWriter.Flush() + if err != nil { + closeConn <- fmt.Errorf("Error in handleResponses: %v", err.Error()) + return + } + } + count++ + } +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/types/application.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/application.go new file mode 100644 index 00000000..555f97e7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/application.go @@ -0,0 +1,40 @@ +package types + +type Application interface { + + // For new socket connections + Open() AppContext +} + +type AppContext interface { + + // Echo a message + Echo(message string) string + + // Return application info + Info() []string + + // Set application option (e.g. mode=mempool, mode=consensus) + SetOption(key string, value string) RetCode + + // Append a tx, which may or may not get committed + AppendTx(tx []byte) ([]Event, RetCode) + + // Return the application Merkle root hash + GetHash() ([]byte, RetCode) + + // Set commit checkpoint + Commit() RetCode + + // Rollback to the latest commit + Rollback() RetCode + + // Add event listener + AddListener(key string) RetCode + + // Remove event listener + RemListener(key string) RetCode + + // Close this AppContext + Close() error +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/types/events.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/events.go new file mode 100644 index 00000000..d1ba5f1f --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/events.go @@ -0,0 +1,6 @@ +package types + +type Event struct { + Key string + Data []byte +} diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go new file mode 100644 index 00000000..e8756a41 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go @@ -0,0 +1,184 @@ +package types + +import "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + +const ( + requestTypeEcho = byte(0x01) + requestTypeFlush = byte(0x02) + requestTypeInfo = byte(0x03) + requestTypeSetOption = byte(0x04) + // reserved for GetOption = byte(0x05) + + responseTypeException = byte(0x10) + responseTypeEcho = byte(0x11) + responseTypeFlush = byte(0x12) + responseTypeInfo = byte(0x13) + responseTypeSetOption = byte(0x14) + // reserved for GetOption = byte(0x15) + + requestTypeAppendTx = byte(0x21) + requestTypeGetHash = byte(0x22) + requestTypeCommit = byte(0x23) + requestTypeRollback = byte(0x24) + requestTypeAddListener = byte(0x25) + requestTypeRemListener = byte(0x26) + // reserved for responseTypeEvent 0x27 + + responseTypeAppendTx = byte(0x31) + responseTypeGetHash = byte(0x32) + responseTypeCommit = byte(0x33) + responseTypeRollback = byte(0x34) + responseTypeAddListener = byte(0x35) + responseTypeRemListener = byte(0x36) + responseTypeEvent = byte(0x37) +) + +//---------------------------------------- + +type RequestEcho struct { + Message string +} + +type RequestFlush struct { +} + +type RequestInfo struct { +} + +type RequestSetOption struct { + Key string + Value string +} + +type RequestAppendTx struct { + TxBytes []byte +} + +type RequestGetHash struct { +} + +type RequestCommit struct { +} + +type RequestRollback struct { +} + +type RequestAddListener struct { + EventKey string +} + +type RequestRemListener struct { + EventKey string +} + +type Request interface { + AssertRequestType() +} + +func (_ RequestEcho) AssertRequestType() {} +func (_ RequestFlush) AssertRequestType() {} +func (_ RequestInfo) AssertRequestType() {} +func (_ RequestSetOption) AssertRequestType() {} +func (_ RequestAppendTx) AssertRequestType() {} +func (_ RequestGetHash) AssertRequestType() {} +func (_ RequestCommit) AssertRequestType() {} +func (_ RequestRollback) AssertRequestType() {} +func (_ RequestAddListener) AssertRequestType() {} +func (_ RequestRemListener) AssertRequestType() {} + +var _ = wire.RegisterInterface( + struct{ Request }{}, + wire.ConcreteType{RequestEcho{}, requestTypeEcho}, + wire.ConcreteType{RequestFlush{}, requestTypeFlush}, + wire.ConcreteType{RequestInfo{}, requestTypeInfo}, + wire.ConcreteType{RequestSetOption{}, requestTypeSetOption}, + wire.ConcreteType{RequestAppendTx{}, requestTypeAppendTx}, + wire.ConcreteType{RequestGetHash{}, requestTypeGetHash}, + wire.ConcreteType{RequestCommit{}, requestTypeCommit}, + wire.ConcreteType{RequestRollback{}, requestTypeRollback}, + wire.ConcreteType{RequestAddListener{}, requestTypeAddListener}, + wire.ConcreteType{RequestRemListener{}, requestTypeRemListener}, +) + +//---------------------------------------- + +type ResponseEcho struct { + Message string +} + +type ResponseFlush struct { +} + +type ResponseInfo struct { + Data []string +} + +type ResponseSetOption struct { + RetCode +} + +type ResponseAppendTx struct { + RetCode +} + +type ResponseGetHash struct { + RetCode + Hash []byte +} + +type ResponseCommit struct { + RetCode +} + +type ResponseRollback struct { + RetCode +} + +type ResponseAddListener struct { + RetCode +} + +type ResponseRemListener struct { + RetCode +} + +type ResponseException struct { + Error string +} + +type ResponseEvent struct { + Event +} + +type Response interface { + AssertResponseType() +} + +func (_ ResponseEcho) AssertResponseType() {} +func (_ ResponseFlush) AssertResponseType() {} +func (_ ResponseInfo) AssertResponseType() {} +func (_ ResponseSetOption) AssertResponseType() {} +func (_ ResponseAppendTx) AssertResponseType() {} +func (_ ResponseGetHash) AssertResponseType() {} +func (_ ResponseCommit) AssertResponseType() {} +func (_ ResponseRollback) AssertResponseType() {} +func (_ ResponseAddListener) AssertResponseType() {} +func (_ ResponseRemListener) AssertResponseType() {} +func (_ ResponseException) AssertResponseType() {} +func (_ ResponseEvent) AssertResponseType() {} + +var _ = wire.RegisterInterface( + struct{ Response }{}, + wire.ConcreteType{ResponseEcho{}, responseTypeEcho}, + wire.ConcreteType{ResponseFlush{}, responseTypeFlush}, + wire.ConcreteType{ResponseInfo{}, responseTypeInfo}, + wire.ConcreteType{ResponseSetOption{}, responseTypeSetOption}, + wire.ConcreteType{ResponseAppendTx{}, responseTypeAppendTx}, + wire.ConcreteType{ResponseGetHash{}, responseTypeGetHash}, + wire.ConcreteType{ResponseCommit{}, responseTypeCommit}, + wire.ConcreteType{ResponseRollback{}, responseTypeRollback}, + wire.ConcreteType{ResponseAddListener{}, responseTypeAddListener}, + wire.ConcreteType{ResponseRemListener{}, responseTypeRemListener}, + wire.ConcreteType{ResponseException{}, responseTypeException}, + wire.ConcreteType{ResponseEvent{}, responseTypeEvent}, +) diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/types/retcode.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/retcode.go new file mode 100644 index 00000000..559164c6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/retcode.go @@ -0,0 +1,32 @@ +package types + +import ( + "errors" +) + +type RetCode int + +// Reserved return codes +const ( + RetCodeOK RetCode = 0 + RetCodeInternalError RetCode = 1 + RetCodeUnauthorized RetCode = 2 + RetCodeInsufficientFees RetCode = 3 + RetCodeUnknownRequest RetCode = 4 + RetCodeEncodingError RetCode = 5 +) + +func (r RetCode) Error() error { + switch r { + case RetCodeOK: + return nil + default: + return errors.New(r.String()) + } +} + +//go:generate stringer -type=RetCode + +// NOTE: The previous comment generates r.String(). +// To run it, `go get golang.org/x/tools/cmd/stringer` +// and `go generate` in tmsp/types diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/types/retcode_string.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/retcode_string.go new file mode 100644 index 00000000..f60dca15 --- /dev/null +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/retcode_string.go @@ -0,0 +1,16 @@ +// generated by stringer -type=RetCode; DO NOT EDIT + +package types + +import "fmt" + +const _RetCode_name = "RetCodeOKRetCodeInternalErrorRetCodeUnauthorizedRetCodeInsufficientFeesRetCodeUnknownRequestRetCodeEncodingError" + +var _RetCode_index = [...]uint8{0, 9, 29, 48, 71, 92, 112} + +func (i RetCode) String() string { + if i < 0 || i+1 >= RetCode(len(_RetCode_index)) { + return fmt.Sprintf("RetCode(%d)", i) + } + return _RetCode_name[_RetCode_index[i]:_RetCode_index[i+1]] +} diff --git a/Godeps/_workspace/src/github.com/tommy351/gin-cors/cors.go b/Godeps/_workspace/src/github.com/tommy351/gin-cors/cors.go index a2945804..8c9735f1 100644 --- a/Godeps/_workspace/src/github.com/tommy351/gin-cors/cors.go +++ b/Godeps/_workspace/src/github.com/tommy351/gin-cors/cors.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" ) var ( diff --git a/Godeps/_workspace/src/github.com/tommy351/gin-cors/cors_test.go b/Godeps/_workspace/src/github.com/tommy351/gin-cors/cors_test.go index bd12c200..3fca7178 100644 --- a/Godeps/_workspace/src/github.com/tommy351/gin-cors/cors_test.go +++ b/Godeps/_workspace/src/github.com/tommy351/gin-cors/cors_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/gin-gonic/gin" - "github.com/stretchr/testify/assert" + "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/assert" ) func init() { diff --git a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/const_amd64.s b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/const_amd64.s index 797f9b05..0517fc19 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/const_amd64.s +++ b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/const_amd64.s @@ -5,7 +5,7 @@ // This code was translated into a form compatible with 6a from the public // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF GLOBL ·REDMASK51(SB), 8, $8 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/cswap_amd64.s b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/cswap_amd64.s index 45484d1b..16204ed6 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/cswap_amd64.s +++ b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/cswap_amd64.s @@ -5,7 +5,7 @@ // This code was translated into a form compatible with 6a from the public // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo // func cswap(inout *[5]uint64, v uint64) TEXT ·cswap(SB),7,$0 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/curve25519.go b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/curve25519.go index 6918c47f..5b7b9bc9 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/curve25519.go +++ b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/curve25519.go @@ -4,7 +4,7 @@ // We have a implementation in amd64 assembly so this code is only run on // non-amd64 platforms. The amd64 assembly does not support gccgo. -// +build !amd64 gccgo appengine +// +build !amd64 gccgo package curve25519 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/freeze_amd64.s b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/freeze_amd64.s index 37599fac..0b80eefe 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/freeze_amd64.s +++ b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/freeze_amd64.s @@ -5,7 +5,7 @@ // This code was translated into a form compatible with 6a from the public // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo // func freeze(inout *[5]uint64) TEXT ·freeze(SB),7,$96-8 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/ladderstep_amd64.s b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/ladderstep_amd64.s index 3949f9cf..10bb89fe 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/ladderstep_amd64.s +++ b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/ladderstep_amd64.s @@ -5,7 +5,7 @@ // This code was translated into a form compatible with 6a from the public // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo // func ladderstep(inout *[5][5]uint64) TEXT ·ladderstep(SB),0,$384-8 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/mont25519_amd64.go b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/mont25519_amd64.go index 5822bd53..3275877b 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/mont25519_amd64.go +++ b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/mont25519_amd64.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo package curve25519 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/mul_amd64.s b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/mul_amd64.s index e48d183e..5404f320 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/mul_amd64.s +++ b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/mul_amd64.s @@ -5,7 +5,7 @@ // This code was translated into a form compatible with 6a from the public // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo // func mul(dest, a, b *[5]uint64) TEXT ·mul(SB),0,$128-24 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/square_amd64.s b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/square_amd64.s index 78d1a50d..cb0053fa 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/curve25519/square_amd64.s +++ b/Godeps/_workspace/src/golang.org/x/crypto/curve25519/square_amd64.s @@ -5,7 +5,7 @@ // This code was translated into a form compatible with 6a from the public // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo // func square(out, in *[5]uint64) TEXT ·square(SB),7,$96-16 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box.go b/Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box.go index ffe00baf..05868b65 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box.go +++ b/Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box.go @@ -18,9 +18,9 @@ This package is interoperable with NaCl: http://nacl.cr.yp.to/box.html. package box import ( - "golang.org/x/crypto/curve25519" - "golang.org/x/crypto/nacl/secretbox" - "golang.org/x/crypto/salsa20/salsa" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/curve25519" + "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/salsa20/salsa" "io" ) diff --git a/Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box_test.go b/Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box_test.go index 481ade28..dbae504e 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box_test.go +++ b/Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box_test.go @@ -10,7 +10,7 @@ import ( "encoding/hex" "testing" - "golang.org/x/crypto/curve25519" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/curve25519" ) func TestSealOpen(t *testing.T) { diff --git a/Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox/secretbox.go b/Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox/secretbox.go index ed46ba2f..800cc5b5 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox/secretbox.go +++ b/Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox/secretbox.go @@ -18,8 +18,8 @@ This package is interoperable with NaCl: http://nacl.cr.yp.to/secretbox.html. package secretbox import ( - "golang.org/x/crypto/poly1305" - "golang.org/x/crypto/salsa20/salsa" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/poly1305" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/salsa20/salsa" ) // Overhead is the number of bytes of overhead when boxing a message. diff --git a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/const_amd64.s b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/const_amd64.s index 8e861f33..33fcd6ee 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/const_amd64.s +++ b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/const_amd64.s @@ -5,7 +5,7 @@ // This code was translated into a form compatible with 6a from the public // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo DATA ·SCALE(SB)/8, $0x37F4000000000000 GLOBL ·SCALE(SB), 8, $8 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_amd64.s b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_amd64.s index f8d4ee92..b9ad0ba4 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_amd64.s +++ b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_amd64.s @@ -5,7 +5,7 @@ // This code was translated into a form compatible with 6a from the public // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo // func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key) TEXT ·poly1305(SB),0,$224-32 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_arm.s b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_arm.s deleted file mode 100644 index c9ceaeb8..00000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_arm.s +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This code was translated into a form compatible with 5a from the public -// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305. - -// +build arm,!gccgo,!appengine - -DATA poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff -DATA poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03 -DATA poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff -DATA poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff -DATA poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff -GLOBL poly1305_init_constants_armv6<>(SB), 8, $20 - -// Warning: the linker may use R11 to synthesize certain instructions. Please -// take care and verify that no synthetic instructions use it. - -TEXT poly1305_init_ext_armv6<>(SB),4,$-4 - MOVM.DB.W [R4-R11], (R13) - MOVM.IA.W (R1), [R2-R5] - MOVW $poly1305_init_constants_armv6<>(SB), R7 - MOVW R2, R8 - MOVW R2>>26, R9 - MOVW R3>>20, g - MOVW R4>>14, R11 - MOVW R5>>8, R12 - ORR R3<<6, R9, R9 - ORR R4<<12, g, g - ORR R5<<18, R11, R11 - MOVM.IA (R7), [R2-R6] - AND R8, R2, R2 - AND R9, R3, R3 - AND g, R4, R4 - AND R11, R5, R5 - AND R12, R6, R6 - MOVM.IA.W [R2-R6], (R0) - EOR R2, R2, R2 - EOR R3, R3, R3 - EOR R4, R4, R4 - EOR R5, R5, R5 - EOR R6, R6, R6 - MOVM.IA.W [R2-R6], (R0) - MOVM.IA.W (R1), [R2-R5] - MOVM.IA [R2-R6], (R0) - MOVM.IA.W (R13), [R4-R11] - RET - -TEXT poly1305_blocks_armv6<>(SB),4,$-4 - MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13) - SUB $128, R13 - MOVW R0, 36(R13) - MOVW R1, 40(R13) - MOVW R2, 44(R13) - MOVW R1, R14 - MOVW R2, R12 - MOVW 56(R0), R8 - WORD $0xe1180008 // TST R8, R8 not working see issue 5921 - EOR R6, R6, R6 - MOVW.EQ $(1<<24), R6 - MOVW R6, 32(R13) - ADD $64, R13, g - MOVM.IA (R0), [R0-R9] - MOVM.IA [R0-R4], (g) - CMP $16, R12 - BLO poly1305_blocks_armv6_done -poly1305_blocks_armv6_mainloop: - MOVM.IA.W (R14), [R0-R3] - MOVW R0>>26, g - MOVW R1>>20, R11 - MOVW R2>>14, R12 - MOVW R14, 40(R13) - MOVW R3>>8, R4 - ORR R1<<6, g, g - ORR R2<<12, R11, R11 - ORR R3<<18, R12, R12 - BIC $0xfc000000, R0, R0 - BIC $0xfc000000, g, g - MOVW 32(R13), R3 - BIC $0xfc000000, R11, R11 - BIC $0xfc000000, R12, R12 - ADD R0, R5, R5 - ADD g, R6, R6 - ORR R3, R4, R4 - ADD R11, R7, R7 - ADD $64, R13, R14 - ADD R12, R8, R8 - ADD R4, R9, R9 - MOVM.IA (R14), [R0-R4] - MULLU R4, R5, (R11, g) - MULLU R3, R5, (R14, R12) - MULALU R3, R6, (R11, g) - MULALU R2, R6, (R14, R12) - MULALU R2, R7, (R11, g) - MULALU R1, R7, (R14, R12) - ADD R4<<2, R4, R4 - ADD R3<<2, R3, R3 - MULALU R1, R8, (R11, g) - MULALU R0, R8, (R14, R12) - MULALU R0, R9, (R11, g) - MULALU R4, R9, (R14, R12) - MOVW g, 24(R13) - MOVW R11, 28(R13) - MOVW R12, 16(R13) - MOVW R14, 20(R13) - MULLU R2, R5, (R11, g) - MULLU R1, R5, (R14, R12) - MULALU R1, R6, (R11, g) - MULALU R0, R6, (R14, R12) - MULALU R0, R7, (R11, g) - MULALU R4, R7, (R14, R12) - ADD R2<<2, R2, R2 - ADD R1<<2, R1, R1 - MULALU R4, R8, (R11, g) - MULALU R3, R8, (R14, R12) - MULALU R3, R9, (R11, g) - MULALU R2, R9, (R14, R12) - MOVW g, 8(R13) - MOVW R11, 12(R13) - MOVW R12, 0(R13) - MOVW R14, w+4(SP) - MULLU R0, R5, (R11, g) - MULALU R4, R6, (R11, g) - MULALU R3, R7, (R11, g) - MULALU R2, R8, (R11, g) - MULALU R1, R9, (R11, g) - MOVM.IA (R13), [R0-R7] - MOVW g>>26, R12 - MOVW R4>>26, R14 - ORR R11<<6, R12, R12 - ORR R5<<6, R14, R14 - BIC $0xfc000000, g, g - BIC $0xfc000000, R4, R4 - ADD.S R12, R0, R0 - ADC $0, R1, R1 - ADD.S R14, R6, R6 - ADC $0, R7, R7 - MOVW R0>>26, R12 - MOVW R6>>26, R14 - ORR R1<<6, R12, R12 - ORR R7<<6, R14, R14 - BIC $0xfc000000, R0, R0 - BIC $0xfc000000, R6, R6 - ADD R14<<2, R14, R14 - ADD.S R12, R2, R2 - ADC $0, R3, R3 - ADD R14, g, g - MOVW R2>>26, R12 - MOVW g>>26, R14 - ORR R3<<6, R12, R12 - BIC $0xfc000000, g, R5 - BIC $0xfc000000, R2, R7 - ADD R12, R4, R4 - ADD R14, R0, R0 - MOVW R4>>26, R12 - BIC $0xfc000000, R4, R8 - ADD R12, R6, R9 - MOVW w+44(SP), R12 - MOVW w+40(SP), R14 - MOVW R0, R6 - CMP $32, R12 - SUB $16, R12, R12 - MOVW R12, 44(R13) - BHS poly1305_blocks_armv6_mainloop -poly1305_blocks_armv6_done: - MOVW 36(R13), R12 - MOVW R5, 20(R12) - MOVW R6, 24(R12) - MOVW R7, 28(R12) - MOVW R8, 32(R12) - MOVW R9, 36(R12) - ADD $128, R13, R13 - MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14] - RET - -TEXT poly1305_finish_ext_armv6<>(SB),4,$-4 - MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13) - SUB $16, R13, R13 - MOVW R0, R5 - MOVW R1, R6 - MOVW R2, R7 - MOVW R3, R8 - AND.S R2, R2, R2 - BEQ poly1305_finish_ext_armv6_noremaining - EOR R0, R0 - MOVW R13, R9 - MOVW R0, 0(R13) - MOVW R0, 4(R13) - MOVW R0, 8(R13) - MOVW R0, 12(R13) - WORD $0xe3120008 // TST R2, #8 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip8 - MOVM.IA.W (R1), [g-R11] - MOVM.IA.W [g-R11], (R9) -poly1305_finish_ext_armv6_skip8: - WORD $0xe3120004 // TST $4, R2 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip4 - MOVW.P 4(R1), g - MOVW.P g, 4(R9) -poly1305_finish_ext_armv6_skip4: - WORD $0xe3120002 // TST $2, R2 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip2 - MOVHU.P 2(R1), g - MOVH.P g, 2(R9) -poly1305_finish_ext_armv6_skip2: - WORD $0xe3120001 // TST $1, R2 not working see issue 5921 - BEQ poly1305_finish_ext_armv6_skip1 - MOVBU.P 1(R1), g - MOVBU.P g, 1(R9) -poly1305_finish_ext_armv6_skip1: - MOVW $1, R11 - MOVBU R11, 0(R9) - MOVW R11, 56(R5) - MOVW R5, R0 - MOVW R13, R1 - MOVW $16, R2 - BL poly1305_blocks_armv6<>(SB) -poly1305_finish_ext_armv6_noremaining: - MOVW 20(R5), R0 - MOVW 24(R5), R1 - MOVW 28(R5), R2 - MOVW 32(R5), R3 - MOVW 36(R5), R4 - MOVW R4>>26, R12 - BIC $0xfc000000, R4, R4 - ADD R12<<2, R12, R12 - ADD R12, R0, R0 - MOVW R0>>26, R12 - BIC $0xfc000000, R0, R0 - ADD R12, R1, R1 - MOVW R1>>26, R12 - BIC $0xfc000000, R1, R1 - ADD R12, R2, R2 - MOVW R2>>26, R12 - BIC $0xfc000000, R2, R2 - ADD R12, R3, R3 - MOVW R3>>26, R12 - BIC $0xfc000000, R3, R3 - ADD R12, R4, R4 - ADD $5, R0, R6 - MOVW R6>>26, R12 - BIC $0xfc000000, R6, R6 - ADD R12, R1, R7 - MOVW R7>>26, R12 - BIC $0xfc000000, R7, R7 - ADD R12, R2, g - MOVW g>>26, R12 - BIC $0xfc000000, g, g - ADD R12, R3, R11 - MOVW $-(1<<26), R12 - ADD R11>>26, R12, R12 - BIC $0xfc000000, R11, R11 - ADD R12, R4, R14 - MOVW R14>>31, R12 - SUB $1, R12 - AND R12, R6, R6 - AND R12, R7, R7 - AND R12, g, g - AND R12, R11, R11 - AND R12, R14, R14 - MVN R12, R12 - AND R12, R0, R0 - AND R12, R1, R1 - AND R12, R2, R2 - AND R12, R3, R3 - AND R12, R4, R4 - ORR R6, R0, R0 - ORR R7, R1, R1 - ORR g, R2, R2 - ORR R11, R3, R3 - ORR R14, R4, R4 - ORR R1<<26, R0, R0 - MOVW R1>>6, R1 - ORR R2<<20, R1, R1 - MOVW R2>>12, R2 - ORR R3<<14, R2, R2 - MOVW R3>>18, R3 - ORR R4<<8, R3, R3 - MOVW 40(R5), R6 - MOVW 44(R5), R7 - MOVW 48(R5), g - MOVW 52(R5), R11 - ADD.S R6, R0, R0 - ADC.S R7, R1, R1 - ADC.S g, R2, R2 - ADC.S R11, R3, R3 - MOVM.IA [R0-R3], (R8) - MOVW R5, R12 - EOR R0, R0, R0 - EOR R1, R1, R1 - EOR R2, R2, R2 - EOR R3, R3, R3 - EOR R4, R4, R4 - EOR R5, R5, R5 - EOR R6, R6, R6 - EOR R7, R7, R7 - MOVM.IA.W [R0-R7], (R12) - MOVM.IA [R0-R7], (R12) - ADD $16, R13, R13 - MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14] - RET - -// func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]key) -TEXT ·poly1305_auth_armv6(SB),0,$280-16 - MOVW out+0(FP), R4 - MOVW m+4(FP), R5 - MOVW mlen+8(FP), R6 - MOVW key+12(FP), R7 - - MOVW R13, R8 - BIC $63, R13 - SUB $64, R13, R13 - MOVW R13, R0 - MOVW R7, R1 - BL poly1305_init_ext_armv6<>(SB) - BIC.S $15, R6, R2 - BEQ poly1305_auth_armv6_noblocks - MOVW R13, R0 - MOVW R5, R1 - ADD R2, R5, R5 - SUB R2, R6, R6 - BL poly1305_blocks_armv6<>(SB) -poly1305_auth_armv6_noblocks: - MOVW R13, R0 - MOVW R5, R1 - MOVW R6, R2 - MOVW R4, R3 - BL poly1305_finish_ext_armv6<>(SB) - MOVW R8, R13 - RET diff --git a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_amd64.go b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_amd64.go index 6775c703..eb22ca15 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_amd64.go +++ b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_amd64.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build amd64,!gccgo,!appengine +// +build amd64,!gccgo package poly1305 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_arm.go b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_arm.go deleted file mode 100644 index 50b979c2..00000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_arm.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build arm,!gccgo,!appengine - -package poly1305 - -// This function is implemented in poly1305_arm.s - -//go:noescape - -func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte) - -// Sum generates an authenticator for m using a one-time key and puts the -// 16-byte result into out. Authenticating two different messages with the same -// key allows an attacker to forge messages at will. -func Sum(out *[16]byte, m []byte, key *[32]byte) { - var mPtr *byte - if len(m) > 0 { - mPtr = &m[0] - } - poly1305_auth_armv6(out, mPtr, uint32(len(m)), key) -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_ref.go b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_ref.go index 0b24fc78..12568a2f 100644 --- a/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_ref.go +++ b/Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_ref.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !amd64,!arm gccgo appengine +// +build !amd64 gccgo package poly1305 diff --git a/Godeps/_workspace/src/golang.org/x/net/context/withtimeout_test.go b/Godeps/_workspace/src/golang.org/x/net/context/withtimeout_test.go index a6754dc3..1a6006dc 100644 --- a/Godeps/_workspace/src/golang.org/x/net/context/withtimeout_test.go +++ b/Godeps/_workspace/src/golang.org/x/net/context/withtimeout_test.go @@ -8,7 +8,7 @@ import ( "fmt" "time" - "golang.org/x/net/context" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/net/context" ) func ExampleWithTimeout() { diff --git a/Godeps/_workspace/src/gopkg.in/tylerb/graceful.v1/graceful.go b/Godeps/_workspace/src/gopkg.in/tylerb/graceful.v1/graceful.go index 8fa2b44e..873bd9bd 100644 --- a/Godeps/_workspace/src/gopkg.in/tylerb/graceful.v1/graceful.go +++ b/Godeps/_workspace/src/gopkg.in/tylerb/graceful.v1/graceful.go @@ -11,7 +11,7 @@ import ( "syscall" "time" - "golang.org/x/net/netutil" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/net/netutil" ) // Server wraps an http.Server with graceful connection handling. diff --git a/account/account.go b/account/account.go index fef07dbf..2caea0d2 100644 --- a/account/account.go +++ b/account/account.go @@ -5,9 +5,9 @@ import ( "fmt" "io" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-merkle" - "github.com/tendermint/go-wire" + . "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" ) diff --git a/account/priv_account.go b/account/priv_account.go index ebdc9585..1def3a2a 100644 --- a/account/priv_account.go +++ b/account/priv_account.go @@ -1,9 +1,9 @@ package account import ( - "github.com/tendermint/ed25519" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-wire" + "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" ) type PrivAccount struct { diff --git a/account/priv_key.go b/account/priv_key.go index 11985fb0..b7f1dd9f 100644 --- a/account/priv_key.go +++ b/account/priv_key.go @@ -1,10 +1,10 @@ package account import ( - "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/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. diff --git a/account/pub_key.go b/account/pub_key.go index 243ab712..9b949a51 100644 --- a/account/pub_key.go +++ b/account/pub_key.go @@ -3,11 +3,11 @@ package account import ( "bytes" - "github.com/tendermint/ed25519" - "github.com/tendermint/ed25519/extra25519" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-wire" - "golang.org/x/crypto/ripemd160" + "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. diff --git a/account/signature.go b/account/signature.go index 2022d140..2b829324 100644 --- a/account/signature.go +++ b/account/signature.go @@ -3,8 +3,8 @@ package account import ( "fmt" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-wire" + . "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. diff --git a/account/signature_test.go b/account/signature_test.go index 45a2947a..0e278935 100644 --- a/account/signature_test.go +++ b/account/signature_test.go @@ -4,9 +4,9 @@ import ( "bytes" "testing" - "github.com/tendermint/ed25519" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-wire" + "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) { diff --git a/client/ws_client.go b/client/ws_client.go index 2f562927..d07d9598 100644 --- a/client/ws_client.go +++ b/client/ws_client.go @@ -3,7 +3,7 @@ package client import ( "fmt" - "github.com/gorilla/websocket" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gorilla/websocket" "net/http" ) diff --git a/cmd/erisdbss/main.go b/cmd/erisdbss/main.go index 69e5542e..ce328336 100644 --- a/cmd/erisdbss/main.go +++ b/cmd/erisdbss/main.go @@ -1,7 +1,7 @@ package main import ( - "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" ess "github.com/eris-ltd/eris-db/erisdb/erisdbss" "github.com/eris-ltd/eris-db/server" "os" diff --git a/erisdb/codec.go b/erisdb/codec.go index 02e96ecd..84d29761 100644 --- a/erisdb/codec.go +++ b/erisdb/codec.go @@ -1,8 +1,8 @@ package erisdb import ( + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" rpc "github.com/eris-ltd/eris-db/rpc" - "github.com/tendermint/go-wire" "io" "io/ioutil" ) diff --git a/erisdb/config.go b/erisdb/config.go index 7873d89d..1c038cd6 100644 --- a/erisdb/config.go +++ b/erisdb/config.go @@ -1,7 +1,7 @@ package erisdb import ( - cfg "github.com/tendermint/go-config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config diff --git a/erisdb/erisdbss/http.go b/erisdb/erisdbss/http.go index be8db6cb..c98a45a6 100644 --- a/erisdb/erisdbss/http.go +++ b/erisdb/erisdbss/http.go @@ -3,12 +3,12 @@ package erisdbss import ( "bytes" "encoding/json" - "github.com/gin-gonic/gin" - . "github.com/tendermint/go-common" - stypes "github.com/eris-ltd/eris-db/state/types" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/go-wire" + "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/eris-ltd/eris-db/server" + stypes "github.com/eris-ltd/eris-db/state/types" "net/http" "os" ) diff --git a/erisdb/erisdbss/log.go b/erisdb/erisdbss/log.go index 71921642..37760e9c 100644 --- a/erisdb/erisdbss/log.go +++ b/erisdb/erisdbss/log.go @@ -1,7 +1,7 @@ package erisdbss import ( - "github.com/tendermint/log15" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/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 43229a6b..6c96ac67 100644 --- a/erisdb/erisdbss/server_manager.go +++ b/erisdb/erisdbss/server_manager.go @@ -3,8 +3,8 @@ package erisdbss import ( "bufio" "fmt" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-wire" + . "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/files" "github.com/eris-ltd/eris-db/server" "os" @@ -63,7 +63,7 @@ func (this *CmdProcess) Start(doneChan chan<- error) { log.Debug(text) if strings.Index(text, this.token) != -1 { log.Debug("Token found", "token", this.token) - go func(){ + go func() { for scanner.Scan() { text := scanner.Text() log.Debug(text) diff --git a/erisdb/event_cache.go b/erisdb/event_cache.go index c9c2bd74..81d4bca5 100644 --- a/erisdb/event_cache.go +++ b/erisdb/event_cache.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "github.com/tendermint/tendermint/types" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" ) var ( diff --git a/erisdb/event_cache_test.go b/erisdb/event_cache_test.go index 2ca5d280..83410eae 100644 --- a/erisdb/event_cache_test.go +++ b/erisdb/event_cache_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/tendermint/tendermint/types" + "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" ) var mockInterval = 10 * time.Millisecond diff --git a/erisdb/json_service.go b/erisdb/json_service.go index 97a7df78..c08eec29 100644 --- a/erisdb/json_service.go +++ b/erisdb/json_service.go @@ -2,7 +2,7 @@ package erisdb import ( "encoding/json" - "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" ep "github.com/eris-ltd/eris-db/erisdb/pipe" rpc "github.com/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/server" diff --git a/erisdb/middleware_test.go b/erisdb/middleware_test.go index 7fc366ef..2774abb2 100644 --- a/erisdb/middleware_test.go +++ b/erisdb/middleware_test.go @@ -1,7 +1,7 @@ package erisdb import ( - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" ep "github.com/eris-ltd/eris-db/erisdb/pipe" "testing" ) diff --git a/erisdb/pipe/accounts.go b/erisdb/pipe/accounts.go index 8dc5c2fb..01b5bded 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" ) diff --git a/erisdb/pipe/blockchain.go b/erisdb/pipe/blockchain.go index 615b8478..e2543282 100644 --- a/erisdb/pipe/blockchain.go +++ b/erisdb/pipe/blockchain.go @@ -2,9 +2,9 @@ package pipe import ( "fmt" - dbm "github.com/tendermint/go-db" + 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" "github.com/eris-ltd/eris-db/state" - "github.com/tendermint/tendermint/types" "math" "strconv" "strings" diff --git a/erisdb/pipe/config.go b/erisdb/pipe/config.go index 6109c225..24e78b5c 100644 --- a/erisdb/pipe/config.go +++ b/erisdb/pipe/config.go @@ -1,8 +1,8 @@ package pipe import ( - "github.com/tendermint/log15" - cfg "github.com/tendermint/go-config" + 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" ) var log = log15.New("module", "eris/erisdb_pipe") diff --git a/erisdb/pipe/consensus.go b/erisdb/pipe/consensus.go index 0e28643e..69f1a7a5 100644 --- a/erisdb/pipe/consensus.go +++ b/erisdb/pipe/consensus.go @@ -1,7 +1,7 @@ package pipe import ( - "github.com/tendermint/tendermint/types" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/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 0b7b8d01..f2d15bdb 100644 --- a/erisdb/pipe/events.go +++ b/erisdb/pipe/events.go @@ -1,8 +1,8 @@ package pipe import ( - evts "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/types" + 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" ) // TODO improve diff --git a/erisdb/pipe/pipe.go b/erisdb/pipe/pipe.go index 3d5f0530..043ba67f 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/tendermint/events" - "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/tmsp" txs "github.com/eris-ltd/eris-db/txs" diff --git a/erisdb/pipe/transactor.go b/erisdb/pipe/transactor.go index 320b309a..07031a7b 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/tendermint/go-common" - tEvents "github.com/tendermint/tendermint/events" - mintTypes "github.com/tendermint/tendermint/types" + 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" "github.com/eris-ltd/eris-db/tmsp" ) diff --git a/erisdb/pipe/types.go b/erisdb/pipe/types.go index e0cd5e4a..5e1b784f 100644 --- a/erisdb/pipe/types.go +++ b/erisdb/pipe/types.go @@ -1,10 +1,10 @@ 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/eris-ltd/eris-db/account" - "github.com/tendermint/go-p2p" // NodeInfo (drop this!) - csus "github.com/tendermint/tendermint/consensus" - "github.com/tendermint/tendermint/types" ) type ( diff --git a/erisdb/restServer.go b/erisdb/restServer.go index 181edbba..f6846bdf 100644 --- a/erisdb/restServer.go +++ b/erisdb/restServer.go @@ -6,7 +6,7 @@ import ( "strconv" "strings" - "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" ep "github.com/eris-ltd/eris-db/erisdb/pipe" rpc "github.com/eris-ltd/eris-db/rpc" diff --git a/erisdb/serve.go b/erisdb/serve.go index 920c043e..d74e70cd 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" - dbm "github.com/tendermint/go-db" - "github.com/tendermint/go-p2p" - "github.com/tendermint/go-wire" - "github.com/tendermint/log15" - cfg "github.com/tendermint/go-config" - tmcfg "github.com/tendermint/tendermint/config/tendermint" - "github.com/tendermint/tendermint/events" - "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" diff --git a/erisdb/wsService.go b/erisdb/wsService.go index 35ad0ea3..f146a50e 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/tendermint/tendermint/types" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" ) // Used for ErisDb. Implements WebSocketService. diff --git a/evm/log.go b/evm/log.go index 82880ae9..e0861876 100644 --- a/evm/log.go +++ b/evm/log.go @@ -1,7 +1,7 @@ package vm import ( - "github.com/tendermint/go-logger" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" ) var log = logger.New("module", "vm") diff --git a/evm/native.go b/evm/native.go index 207e2df1..6dbc7763 100644 --- a/evm/native.go +++ b/evm/native.go @@ -2,8 +2,8 @@ package vm import ( "crypto/sha256" - "code.google.com/p/go.crypto/ripemd160" - . "github.com/tendermint/go-common" + "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" ) var registeredNativeContracts = make(map[Word256]NativeContract) diff --git a/evm/opcodes.go b/evm/opcodes.go index 87e09bfd..505d536c 100644 --- a/evm/opcodes.go +++ b/evm/opcodes.go @@ -2,7 +2,7 @@ package vm import ( "fmt" - "gopkg.in/fatih/set.v0" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/gopkg.in/fatih/set.v0" ) type OpCode byte diff --git a/evm/snative.go b/evm/snative.go index 9c50cd4e..209dcd5e 100644 --- a/evm/snative.go +++ b/evm/snative.go @@ -3,7 +3,7 @@ package vm import ( "fmt" - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/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 979aba2e..287b34ab 100644 --- a/evm/stack.go +++ b/evm/stack.go @@ -2,7 +2,7 @@ package vm import ( "fmt" - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/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 9204218f..952c02b6 100644 --- a/evm/test/fake_app_state.go +++ b/evm/test/fake_app_state.go @@ -1,7 +1,7 @@ package vm import ( - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/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 d12ab508..a120d349 100644 --- a/evm/test/log_event_test.go +++ b/evm/test/log_event_test.go @@ -5,9 +5,9 @@ import ( "reflect" "testing" - . "github.com/tendermint/go-common" - "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/types" + . "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/eris-ltd/eris-db/evm" ) diff --git a/evm/test/vm_test.go b/evm/test/vm_test.go index 6ea23aeb..6753fe8e 100644 --- a/evm/test/vm_test.go +++ b/evm/test/vm_test.go @@ -8,9 +8,9 @@ import ( "testing" "time" - . "github.com/tendermint/go-common" - "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/types" + . "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/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 5588d996..f13cd730 100644 --- a/evm/types.go +++ b/evm/types.go @@ -1,7 +1,7 @@ package vm import ( - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/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 ad911e68..d93395da 100644 --- a/evm/vm.go +++ b/evm/vm.go @@ -6,8 +6,8 @@ import ( "fmt" "math/big" - . "github.com/tendermint/go-common" - "github.com/tendermint/tendermint/events" + . "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" diff --git a/files/files_test.go b/files/files_test.go index 2d9cdc23..bdfa4426 100644 --- a/files/files_test.go +++ b/files/files_test.go @@ -2,7 +2,7 @@ package files import ( "bytes" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" "os" "path" "testing" diff --git a/files/log.go b/files/log.go index a18f6b6a..9067bf13 100644 --- a/files/log.go +++ b/files/log.go @@ -1,7 +1,7 @@ package files import ( - "github.com/tendermint/log15" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/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 3c43ed17..13c32964 100644 --- a/permission/types/permissions.go +++ b/permission/types/permissions.go @@ -2,7 +2,7 @@ package types import ( "fmt" - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) //------------------------------------------------------------------------------------------------ diff --git a/permission/types/snatives.go b/permission/types/snatives.go index 57315ac9..94e602b7 100644 --- a/permission/types/snatives.go +++ b/permission/types/snatives.go @@ -1,7 +1,7 @@ package types import ( - "github.com/tendermint/go-wire" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" ) //--------------------------------------------------------------------------------------------------- diff --git a/rpc/rpc_test.go b/rpc/rpc_test.go index bfafa4c2..a5debf5f 100644 --- a/rpc/rpc_test.go +++ b/rpc/rpc_test.go @@ -1,7 +1,7 @@ package rpc import ( - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" "testing" ) diff --git a/server/config.go b/server/config.go index 720dddcd..bd84d476 100644 --- a/server/config.go +++ b/server/config.go @@ -1,7 +1,7 @@ package server import ( - "github.com/naoina/toml" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/naoina/toml" "github.com/eris-ltd/eris-db/files" ) diff --git a/server/log.go b/server/log.go index aacad33d..09e6fbda 100644 --- a/server/log.go +++ b/server/log.go @@ -1,7 +1,7 @@ package server import ( - "github.com/tendermint/log15" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" ) var log = log15.New("module", "eris/server") diff --git a/server/logging.go b/server/logging.go index a5a70031..8b1ba444 100644 --- a/server/logging.go +++ b/server/logging.go @@ -2,7 +2,7 @@ package server import ( "fmt" - "github.com/tendermint/log15" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" "os" ) diff --git a/server/server.go b/server/server.go index e6bc35dd..f333b1ff 100644 --- a/server/server.go +++ b/server/server.go @@ -3,9 +3,9 @@ package server import ( "crypto/tls" "fmt" - "github.com/gin-gonic/gin" - cors "github.com/tommy351/gin-cors" - "gopkg.in/tylerb/graceful.v1" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" + cors "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tommy351/gin-cors" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/gopkg.in/tylerb/graceful.v1" "net" "net/http" "time" diff --git a/server/server_test.go b/server/server_test.go index 05d954b7..55bfb666 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -2,7 +2,7 @@ package server import ( //"fmt" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" "testing" ) diff --git a/server/websocket.go b/server/websocket.go index b37166fd..b5d4b4ca 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -2,8 +2,8 @@ package server import ( "fmt" - "github.com/gin-gonic/gin" - "github.com/gorilla/websocket" + "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/gorilla/websocket" "net/http" "sync" "time" @@ -223,14 +223,14 @@ func (this *WSSession) readPump() { this.writeCloseChan <- struct{}{} return } - + if msgType != websocket.TextMessage { log.Info("Receiving non text-message from client, closing.") this.writeCloseChan <- struct{}{} return } - - go func(){ + + go func() { // Process the request. this.service.Process(msg, this) }() @@ -274,16 +274,16 @@ func (this *WSSession) writePump() { } case <-this.writeCloseChan: return - // Ticker run out. Time for another ping message. - /* - case <-ticker.C: - if err := this.write(websocket.PingMessage, []byte{}); err != nil { - log.Debug("Failed to write ping message to socket. Closing.") - return - } + // Ticker run out. Time for another ping message. + /* + case <-ticker.C: + if err := this.write(websocket.PingMessage, []byte{}); err != nil { + log.Debug("Failed to write ping message to socket. Closing.") + return + } */ } - + } } diff --git a/state/block_cache.go b/state/block_cache.go index 069ef8bc..a53675bd 100644 --- a/state/block_cache.go +++ b/state/block_cache.go @@ -4,10 +4,10 @@ import ( "bytes" "sort" - . "github.com/tendermint/go-common" - dbm "github.com/tendermint/go-db" - "github.com/tendermint/go-merkle" - "github.com/tendermint/go-wire" + . "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" acm "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/txs" diff --git a/state/common.go b/state/common.go index 1f572a21..4e65bf06 100644 --- a/state/common.go +++ b/state/common.go @@ -1,7 +1,7 @@ package state import ( - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/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 b4149fde..295cc1ae 100644 --- a/state/execution.go +++ b/state/execution.go @@ -5,8 +5,8 @@ import ( "errors" "fmt" - . "github.com/tendermint/go-common" - "github.com/tendermint/tendermint/events" + . "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" 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 e47f98f8..4f1c03d0 100644 --- a/state/genesis_test.go +++ b/state/genesis_test.go @@ -6,7 +6,7 @@ import ( "fmt" "testing" - tdb "github.com/tendermint/go-db" + tdb "github.com/eris-ltd/eris-db/Godeps/_workspace/src/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 5b102b57..316471ea 100644 --- a/state/log.go +++ b/state/log.go @@ -1,7 +1,7 @@ package state import ( - "github.com/tendermint/go-logger" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" ) var log = logger.New("module", "state") diff --git a/state/permissions_test.go b/state/permissions_test.go index 15443688..12ab10a4 100644 --- a/state/permissions_test.go +++ b/state/permissions_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - . "github.com/tendermint/go-common" - dbm "github.com/tendermint/go-db" - "github.com/tendermint/tendermint/events" - "github.com/tendermint/tendermint/types" + . "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" 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 fa1fb628..da2dc1e2 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/tendermint/go-common" - dbm "github.com/tendermint/go-db" - "github.com/tendermint/go-merkle" - "github.com/tendermint/go-wire" + . "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/tendermint/events" - "github.com/tendermint/tendermint/types" + "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 ( diff --git a/state/state_test.go b/state/state_test.go index 9c917e78..596b1782 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - _ "github.com/tendermint/tendermint/config/tendermint_test" - "github.com/tendermint/tendermint/types" + _ "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/eris-ltd/eris-db/account" ) diff --git a/state/test.go b/state/test.go index 49d6dd28..32a070bd 100644 --- a/state/test.go +++ b/state/test.go @@ -4,9 +4,9 @@ import ( "sort" "time" - . "github.com/tendermint/go-common" - dbm "github.com/tendermint/go-db" - "github.com/tendermint/tendermint/types" + . "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" diff --git a/state/tx_cache.go b/state/tx_cache.go index b3ed160c..06e55bf1 100644 --- a/state/tx_cache.go +++ b/state/tx_cache.go @@ -6,7 +6,7 @@ import ( ptypes "github.com/eris-ltd/eris-db/permission/types" // for GlobalPermissionAddress ... "github.com/eris-ltd/eris-db/txs" - . "github.com/tendermint/go-common" + . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" ) type TxCache struct { diff --git a/state/tx_cache_test.go b/state/tx_cache_test.go index a943ec72..f07d2cfa 100644 --- a/state/tx_cache_test.go +++ b/state/tx_cache_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - "github.com/tendermint/go-wire" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" ) func TestStateToFromVMAccount(t *testing.T) { diff --git a/state/types/genesis.go b/state/types/genesis.go index 8886da40..95e34d23 100644 --- a/state/types/genesis.go +++ b/state/types/genesis.go @@ -3,9 +3,9 @@ package types import ( "time" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-crypto" - "github.com/tendermint/go-wire" + . "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" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/test/filters/filter_test.go b/test/filters/filter_test.go index ba0905f2..adfbc98b 100644 --- a/test/filters/filter_test.go +++ b/test/filters/filter_test.go @@ -2,7 +2,7 @@ package filters import ( "fmt" - "github.com/stretchr/testify/suite" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/suite" . "github.com/eris-ltd/eris-db/erisdb/pipe" "sync" "testing" diff --git a/test/mock/mock_web_api_test.go b/test/mock/mock_web_api_test.go index 0d2944b1..fc5c65ca 100644 --- a/test/mock/mock_web_api_test.go +++ b/test/mock/mock_web_api_test.go @@ -5,12 +5,12 @@ import ( "bytes" "encoding/hex" // edb "github.com/eris-ltd/erisdb/erisdb" - "github.com/gin-gonic/gin" - "github.com/stretchr/testify/suite" - "github.com/tendermint/log15" + "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/eris-ltd/eris-db/account" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/types" edb "github.com/eris-ltd/eris-db/erisdb" ep "github.com/eris-ltd/eris-db/erisdb/pipe" "github.com/eris-ltd/eris-db/rpc" diff --git a/test/mock/pipe.go b/test/mock/pipe.go index c8b71556..03d09e47 100644 --- a/test/mock/pipe.go +++ b/test/mock/pipe.go @@ -4,9 +4,9 @@ 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" "github.com/eris-ltd/eris-db/account" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - "github.com/tendermint/tendermint/types" ) // Base struct. diff --git a/test/server/http_burst_test.go b/test/server/http_burst_test.go index 2ac5dbcc..cc415a0e 100644 --- a/test/server/http_burst_test.go +++ b/test/server/http_burst_test.go @@ -2,7 +2,7 @@ package server import ( // "fmt" - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" "net/http" "testing" "time" diff --git a/test/server/scumbag.go b/test/server/scumbag.go index 80720601..dbf50eff 100644 --- a/test/server/scumbag.go +++ b/test/server/scumbag.go @@ -2,8 +2,8 @@ package server import ( "encoding/json" - "github.com/gin-gonic/gin" - "github.com/tendermint/log15" + "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/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/server" "os" diff --git a/test/server/ws_burst_test.go b/test/server/ws_burst_test.go index 3b5749aa..2d624013 100644 --- a/test/server/ws_burst_test.go +++ b/test/server/ws_burst_test.go @@ -1,7 +1,7 @@ package server import ( - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" "github.com/eris-ltd/eris-db/client" "github.com/eris-ltd/eris-db/server" "testing" @@ -102,7 +102,7 @@ func wsClient(doneChan chan bool, errChan chan error) { i++ } client.Close() - time.Sleep(100*time.Millisecond) - + time.Sleep(100 * time.Millisecond) + doneChan <- true } diff --git a/test/transacting/transacting_tes.go b/test/transacting/transacting_tes.go index 69777eac..e7fa397b 100644 --- a/test/transacting/transacting_tes.go +++ b/test/transacting/transacting_tes.go @@ -4,11 +4,13 @@ package transacting import ( "bytes" "fmt" - "github.com/stretchr/testify/suite" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/suite" // "github.com/tendermint/tendermint/types" edb "github.com/eris-ltd/eris-db/erisdb" 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/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/server" td "github.com/eris-ltd/eris-db/test/testdata/testdata" @@ -16,10 +18,8 @@ import ( "net/http" "os" "path" - "testing" - "github.com/gin-gonic/gin" - "github.com/tendermint/log15" "runtime" + "testing" ) func init() { @@ -136,4 +136,4 @@ func (this *TxSuite) postJson(endpoint string, v interface{}) *http.Response { func TestQuerySuite(t *testing.T) { suite.Run(t, &TxSuite{}) -} \ No newline at end of file +} diff --git a/test/web_api/query_test.go b/test/web_api/query_test.go index 54d2ce48..3acb0a7e 100644 --- a/test/web_api/query_test.go +++ b/test/web_api/query_test.go @@ -4,7 +4,7 @@ package web_api import ( "bytes" "fmt" - "github.com/stretchr/testify/suite" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/suite" edb "github.com/eris-ltd/eris-db/erisdb" ess "github.com/eris-ltd/eris-db/erisdb/erisdbss" ep "github.com/eris-ltd/eris-db/erisdb/pipe" @@ -133,4 +133,4 @@ func generateQuery(fda []*ep.FilterData) string { func TestQuerySuite(t *testing.T) { suite.Run(t, &QuerySuite{}) -} \ No newline at end of file +} diff --git a/test/web_api/shared.go b/test/web_api/shared.go index 406fbbcd..4f08a3c4 100644 --- a/test/web_api/shared.go +++ b/test/web_api/shared.go @@ -1,8 +1,8 @@ package web_api import ( - "github.com/gin-gonic/gin" - "github.com/tendermint/log15" + "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" "os" "runtime" ) diff --git a/test/web_api/web_api_test.go b/test/web_api/web_api_test.go index c47bb8ce..444d28ab 100644 --- a/test/web_api/web_api_test.go +++ b/test/web_api/web_api_test.go @@ -6,8 +6,8 @@ import ( "encoding/hex" "fmt" // edb "github.com/eris-ltd/erisdb/erisdb" - "github.com/gin-gonic/gin" - "github.com/stretchr/testify/suite" + "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/account" edb "github.com/eris-ltd/eris-db/erisdb" ess "github.com/eris-ltd/eris-db/erisdb/erisdbss" diff --git a/tmsp/erisdb.go b/tmsp/erisdb.go index 9059773c..dd89e533 100644 --- a/tmsp/erisdb.go +++ b/tmsp/erisdb.go @@ -10,10 +10,10 @@ import ( sm "github.com/eris-ltd/eris-db/state" types "github.com/eris-ltd/eris-db/txs" - "github.com/tendermint/go-wire" - "github.com/tendermint/tendermint/events" + "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" - tmsp "github.com/tendermint/tmsp/types" + tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" ) //-------------------------------------------------------------------------------- diff --git a/txs/config.go b/txs/config.go index cb982879..e8f96401 100644 --- a/txs/config.go +++ b/txs/config.go @@ -1,7 +1,7 @@ package types import ( - cfg "github.com/tendermint/go-config" + cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/txs/events.go b/txs/events.go index edf7046c..522658e4 100644 --- a/txs/events.go +++ b/txs/events.go @@ -4,10 +4,10 @@ import ( "fmt" "time" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-wire" + . "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/tendermint/types" // Block + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" // Block ) // Functions to generate eventId strings diff --git a/txs/log.go b/txs/log.go index dbe8a678..1f22008f 100644 --- a/txs/log.go +++ b/txs/log.go @@ -1,7 +1,7 @@ package types import ( - "github.com/tendermint/go-logger" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" ) var log = logger.New("module", "types") diff --git a/txs/tx.go b/txs/tx.go index e39dd447..a65666c3 100644 --- a/txs/tx.go +++ b/txs/tx.go @@ -5,14 +5,14 @@ import ( "errors" "io" - "golang.org/x/crypto/ripemd160" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/ripemd160" - . "github.com/tendermint/go-common" - "github.com/tendermint/go-wire" + . "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" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" - "github.com/tendermint/tendermint/types" // votes for dupeout .. + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" // votes for dupeout .. ) var ( diff --git a/txs/tx_test.go b/txs/tx_test.go index 8e772b9a..b52e4df7 100644 --- a/txs/tx_test.go +++ b/txs/tx_test.go @@ -3,8 +3,8 @@ package types import ( "testing" - . "github.com/tendermint/go-common" - _ "github.com/tendermint/tendermint/config/tendermint_test" + . "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" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/util/util_test.go b/util/util_test.go index deef5ebb..69046d21 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -1,7 +1,7 @@ package util import ( - "github.com/stretchr/testify/assert" + "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" "testing" ) -- GitLab