diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 2ec0e90df4ff4d5df937f237ca4b3f5aa83b749f..b3a9d001ffcf7c99c405ef40b211956e123eb7c4 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 b22d9ced6a77a400755c687a7e87cdaf2b9d4d5d..8fc2f233d7a7dd71a0d08c21ffd115645df8e061 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 db1678e425527c726f1be3aba0d379f059aec9f7..8c25afd980a9f9ac36e0b9e65d9a4cf8285d5c5b 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 7f12152b0989c55d9cb09b652a2fe86fb7edf7db..d5a6f2e99f223aa316109ee610bdf3191a82e9f5 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 27ba7b6671d5fc9ebd7dc8fe80a5c58b4c5adb62..8ab0bc5246ace0820bcacb3b6a5d5763124b38c6 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 f5f0de4a8a7fd60c60063d3776a44bc88f336947..a5e946ccc5655dc498b5866c0da8cc2fb1b34f49 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 a638d6ddcb105c1e3853bcef867cc9c9a607d3cb..9e9f3dda4b8ea983c96fd42c1b3ff4a302d07414 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 425aff0fe7f64b855455fda54fde40bfecd0f2bc..ea5896167769f444debeba3e88e60675f641c5a6 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 748e3fe059f116de02e8d0b394b2bbe314fc5292..aa7cc3ddc05bbc39c8ea1bf13c4d56e2ef11a39c 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 a5e1796237e607f0a5825c05a8e909b528e3d8a2..2b09841028313a030a5c24a97c57f03635043209 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 80f2bd3c7f3ff8773433af41441e23c611589784..b0f1ece7c982d576e76f754f8d8a66390d941c68 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 1f3c8585ff9032a8f326f365bd0528b83f60dfa4..538cea7456dc31e663483a32d11a54c27926863c 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 b187756580b8c699a5695e29fc90653c3dcba31a..cc7c008794caa87208dac752f38f5d9bed2ce1d5 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 e4b55a0f094380343cbac19cf68f1bdf066a3409..8f7f473fd3bb6454b3e1bb5e8f3b1aea3ef48455 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 e18d5b6da3f349a343314ac7345a9ae326cb3f69..05369c61ff77f7fbccadf5036bf30dad69de5be8 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 f7ae0758e08892803d3eee5353b01266e3939cdc..fe2fe754249a0cf4762696477f67ca7b8467582a 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 fc9e821233d5de654c3b8fdf9b2d08161f7a7211..96cbf572c31260b1880cf28b1daab1ef9991ddeb 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 2227fa6ae8fcf61d919a02873f095bc58048d168..fe2328246665397d8cbb28ec0547c708a78e3919 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 1cdaa94cb5d31f220c6e08cd694256a88980e509..1d4755ec79903e774e1d0b452af8659174ef02be 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 7876c7ef493c41bef2d6b8759ad5decd2b820a6b..8af80d333d5b88142131abf6673c550775adc7f6 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 15efaeb872d9127b592b0662b2e890c5720a0db3..5dcf4e85a2385fdbf6c4f5f61af2485236b84b5b 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 2a23d85e94f5171e4ee9c5d91f374e705ff4b421..8fd7a43b898cfef11a209e6243422396179b1ef1 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 01cb758a4f517a2523f7d06718a8ce7a809944f8..16eb439bdd50fb674223d60479f1e83a4603a5ab 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 39e71e816023b0efee4a8e766f957d526e77203a..aae0ef2c0097207d09e7f74ed1533bb7db8f1b9d 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 7a6ffb7d5cf28d353cf6b98e9b09d6f552a45236..8be5220ca911c79cf95020d891d729301653b2ed 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 7306d192573c53891b53bde3c6fd1f17cdd5662b..ec7133a80d58d24b2cb6176fe610315bf3c139d3 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 14c7421bd350aa4c56292af88b41024acb33db35..67f7f8e60e9d8ff8425ace26d93d49f60bc3eb81 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 2f451f84eb0bc4ad96eb9029bc1585d95a81c0f6..3f5d23ed4a05dfd05d7c5fd1d76f4490276b9611 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 ba0cc20d9db5a9f3a641b2e48282e8a03f5f407d..e2fcf4f4ad3f821708706f54c0c0bd8a976a01d3 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 d96ac84dbf282d639c2619f233e124cedcb7a0d0..b7eed0da47c4cddf21b7fd9d37fc1f6e6dce0218 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 7cc0496c3e05d930ce8e47b218b696af3cad33d4..00b4645a47bb9ea0790e2cebf7b3bcd766d720e4 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 a2c7b85fab38b96b19c9c6145b80f95cd5262dea..37d7433ebf93f58856211f2050caf3ade9059ded 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 52371b1e45ab1ac08469a56607133e18cc6716d5..64cd7d08075a7c43b884ce6076545c30a0564990 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 b1c2d9bc3a2d55ad6a68ba66f225e415fbc1192c..f1e15440afd80e113863015035c75306fc81888c 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 90c280bda102f6cf23c7370fdf43231d4c880eb6..9e9dbc45133be54bae72d4c567d91b5624d9bc46 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 69c831e1238ca7e1068090be1b121b96573b05a2..89384c2c0b3c822d4868f1092507b1cc72c57862 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 c5446fe922d5fbd2e3ca6816f6bcccd268a19e5a..d9cb862404ae19d9d58a42d6401dbe2f6a32c22f 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 b85c1c680ffc50bd35f9789434ac820140d6fb3d..94ffdfb365ba1f69ecb48a0a9a098956abe5a2b0 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 1fcae9b7abcd64a96572e7640fcd449536d415ad..17dd2e79b56155af3609167becb7975ffafe5b66 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 1932538e67b9e4f6c3db7b14e85a49a48517d09a..94302f44d04d6166a3ee5e6401ed16f84f24e5db 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 17e04fd0a9d501d30e905db2f93333040f4c1c5e..3445c879e5756aab000beca1931bdcf125daac35 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 e0186662525a4ae11660a97a6c16b6c683132331..f7a3c83cdb47604ca716a0da17fd2e33b4b0ff0d 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 069d4198400a87947695b7cc7eb91ac6bededbd3..62c75b9ca033451c973d8e1b43cb551a7d518957 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 122a3f3abd874add239f666f4f97880e04f64d91..6b10a61109031a5e61ab3766de6c12bdfbd07959 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 ac6744d479a5d69e9cfd3723da32c8c8a91debd8..4dbe6ecad250e888d05ebd8dff602628ff4e702b 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 6a1bb2c6c0ea6d5227267bf4dcf06ae87e61186f..630c5869de0e97302b8d0eebcb07d82151ee692a 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 ccf390c9cff4bd120180dd47b5b58e9a0c00b102..354ebe4fee5f2bfd622b5ec8700f5de7cc45af56 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 7fc842f4fedd6f8dbd9902945d6098d4d556b6f4..e98b683cde11ad97fa83134167be6b7f74eb6b13 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 91b426709d59a8fb0860cec31ba601f9daca3605..621e52db283da81202a19a0f464ae3ab0b0a0fb4 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 c9670de5de6f70f4ba905df39776f67a42ff32d1..9ae499311026ce392b16b641577337f946754ef0 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 d33d5e9c78fcf566114dce757ffe4ea6e0f0ba46..6e57fab707a08b08c1bd088dac3088c7bd6e48a9 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 a351874ed4351f6d0abf67719bf7698d4228216a..f1ef0743e955f114cea9018d051e45d898787464 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 def86bc1aa8240e30aba67c204f0e0c311a48b37..5e03cc33b368be0182d1f5e3bf684b0e519e3f47 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 26003106ead5ad7436db63da0f49dbfcd1c2cdf1..2f14a588fec1b697d89073853761c3184047ea88 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 656ae98567f38ecae293500a2649021ec9fd525f..884598d41989ab11618f86736c7405d7530949bd 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 0372848ff1e4f62ececce67d9abe04d8e08121bd..4af7403317888b03177c989614003cff84009589 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 24671dd39ede09ec35cc01a5f0e9bdec926a11bc..87421ff2d903ccdc94cd96bff8a534d9199f64db 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 9d91ebf1a80e78e399b745edeb8e61bbaa3bf0c8..1dce770486554afa02ac2840c3a26640716c8d68 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 a8a2bdf72e173d592b4eba894a2996595cb1af12..0cd4a99ec78d217d0e84d14e5f1eafece9903ade 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 176ee893f10c6896ceb5e2cabaa2f38426c7c1c8..0f7ba29892ba34ba2badbd5d84d876a1e4ef9a74 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 c8bd66a5aa9ab6aded8e4782358e4621c3e019e7..d5ba768413b5d23b0ddbb4a4343a232e7bdd8d52 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 84b5d6b7b2149744c0098d7ca31b0669554be8ed..a22b4b9d5722df1336e8b14dffeb97d019140681 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 b328ece4e2caffe0b1004bed2047d3a3cb56eb4d..8ae2e50e8ea41980e5a5e2a7c3e8fb147fe67a98 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 37c1e146bcc088a5f7dc7ba621d68f3a9c7c8509..fcad1fbf8474328d7b01dd20f33e357f40176b40 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 bab0e99705f59201d6920633893012938dc8a592..68c925522f4fa25ced117d2b78a4785b53dcb51c 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 1fb56f07136f23a4314455852a242109587fbcd6..70bfdaa54ea848419067098e7978a8f61cb9d94a 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 a23ab05f70fe8e45c0c0a8e0e4617884219a0cbf..3050fb86ae651d0dbf9de64f39df378b122825ba 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 1ed6d07cbb6e041e4e999112fa3ccf0ec1328c6b..9c9c27a686462b1afa5b2a2ffbacfba8292d7c14 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 939adbb9332bcc2ce462303b9f95c9601fada105..71843607f34ae43d607f25712c91feee5ff7d950 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 72a7978924ebf0aaa52eefd16ef79ac57a40f086..8d64ed8b4ad803a45f777107ebd51f695f5c692e 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 c2522860b0b8c0477fec8d54068053e22de6a1d4..f6876eea87fbfd824c77831de93b911c06084f21 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 5ef8d5bafb3f265754c74562d987ed2858bb174f..3e54f8b1977d9e29bf744acc78d28163231e77a5 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 1a7e29df8fbd975902e5042031cd777b9a9764ce..df1daffa352f21c63c16e6c6a2429f90be74ec88 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 e523b63e4b6694cf6e0a016b06830aefdf8e8831..8ef775f31657728ff39962dfda0f6fe890d130da 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 6519ec660eb7110425d545d6e7154c0a447a869f..4e4aae982c72c8148dd3253050e6c02bc7f8c636 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 572ae8150c792dd43a3cc0477d1ff44075a51db3..eeff53321e810198c67d6920ea6c437bd22eab99 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 30eadf7847ed9b35495c2ee56f800de9fff79b84..eb9526f751f320238b90945a2dd4e8db359247cb 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 fefa007a7047c7c0f5dcf69769db92d74702a087..33be15d6b59ec77c8b2ff71f8e9bf146c9b106fa 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 b05084caa65eb0a607b796d8819dcd0656acdf3f..51ca66ba7d1b1125136ff074d13f2b314f0d78a1 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 1395bd928080f5514643e2c7d24a53d57025c702..67c7254c482f543afc91ef6ca2353cd488a39c87 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 18c304b7f19a6c66b008e7fe2f6d879cf0a0a6ad..7be1214f39d1186edb10e096581599af7b08f5b7 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 5dd6dbc7b7bbdb1d3e252c3cc1bb1995eb99ae4a..131333c16a033197f9ba0da6b7fdcd6a6bbbf39f 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 f9a309dac6f499fffaee3138179b1c0b46bd2912..0e244d4a310c5a6486b39a5829e2bd78c467a65b 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 a3d84ef60d53d4afb73ba7bdf1f848ebbb202808..a13abb675a960c430b5acb5084812c3794922d9e 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 f0bba4602ca528493576243aaef1da156556cb58..e8c81572a542c1b0b14698e5b761beeca27e7d53 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 7c5a79418cc4bb2a3bf70ba7314c4804e04349f9..0000000000000000000000000000000000000000 --- 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 405e07bef4f1f7b881044a7e449d96b99c4bd68e..5fad6105b36eda1a7237e2007878e0110e955607 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 33c14875618b53cd0408e77f4819c47adf9a1994..ba3864b20828dd0452324765ddba8c780b91c73d 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 399a788bad2de7b07974e09f14e400f99e484d06..23f3d80fab2b57e0fb7ac3ac3d42b3743e32d478 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 46cc9d07012e91141cae7c08903f8421c394c412..9329faf7a7676b75572f4ef612e6d7e320272858 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 fc1c8165df1a0d05d432e47889fe8ccb0b943c7f..8952193112728a24485df4d5cfca73ebae92ca6d 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 85dd70b06f9f6c8955d60b382d4a8652b1ba1292..bdda8c447e241d497b6dfc41fa6812b26ae157e2 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 08be0bab3da3b28e9c889c50ef813f6c0603d29b..768dfc88ec200c74acadd8ef02acc6f399a02b42 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 db386f3b5465b68faff4b7f709482bdfdb830b6f..357e51845d1618453e65117b1f80f09726ee0a23 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 00e6f9eea0dd97ae892eab1934d4f096f73a1b65..a8580cf324784e3d1122680de1e26477db26a4f2 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 95c369d14ece57a79ba628f8fdc1e0c7284981a4..1bfc3978768c2126690c6aa9f707532539e1a8f0 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 6465da6e3707c48ab28ebc176c33b80b66c0c8b3..d35a13051497c79133aa293560897c9b63276e67 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 4b59b31f52b42f12e8e098ea3a20d3b10d6b334e..5429c465b6938b75d1f7e39662b66f1d4a507797 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 45819282b349c2c14dd729d1e8ebbf8747b0172c..51f9fc7173978511abb9ab83a1e91bfd5b60197e 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 ec3f177a12febb5259fb9d88a5b8b58e7d37dca7..a0995a4b7b7c83efb955bb97f46b319b35b69d3b 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 df6d9db6a335bf388ba844ee0af918707e9caf34..5e3cbb160d543800a09960a01c63b1c60e6ed4fd 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 471d5708c37d826d7c5e75139f209c816b13f7c5..83a01a4719b84ab5da4aa0e23258fa9e057089bb 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 a0b58f0e7252b632651a6480f32fc47e973cca01..78d981c7dcd38fc198fa4c70fd3b46a9c134d83a 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 59c496d54c62e90afe4cd057d81f412b10edef6b..d515438b175e1ae785a6ae3ee500808dc7c62cdb 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 97c5294b1b5dd0c16162cd49fb55ad27274cb89a..7ac261ddba2bd4c5056f737f2af07dd0cdca1f61 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 25bf2b29f99310e6af6ab1532ccfc9cdf1621e87..868f7ffab3e0df8ba7c583e05b1960529148e8ad 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 1a5bf71a3254044964beba9aee5362e5da1ed763..7de9260d0d38eb3b21e5e2c5d2841695bda8a4ad 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 011d982da82c13eaf18b9b2abb9c106f2c4a012e..39468b73d792308d8bcc6aa85d2d50da0b8bc4a3 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 48ac4a423ec0452caf979154573e15485834a25a..6c7e5cbc4109740ed3d2ecb517d02d63e89b84cd 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 571218f5516f5f679364e57cb3db1fcbf3fb3225..bbda91686372ac2982d68a41dac8b7fb446eb67a 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 0000000000000000000000000000000000000000..57cfcf41c34912045f1514b1dae03eb4cb7ac9fa --- /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 0000000000000000000000000000000000000000..5295dd995007808bba89cca9a7a74d1b6e8985cb --- /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 0000000000000000000000000000000000000000..d5a3f8ed7c7a493208b2c36828b204be9561a535 --- /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 0000000000000000000000000000000000000000..aaf0cf06de3e69d531bdfc873d7149ca2ea6aa90 --- /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 0000000000000000000000000000000000000000..dc7987a63adc602563fc1507a1da2eca54c4963d --- /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 0000000000000000000000000000000000000000..8822415c1682452d51595e91c9bed83c2c798354 --- /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 0000000000000000000000000000000000000000..378c19fc6a7361e9ba49877f2e2df471db19a40c --- /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 0000000000000000000000000000000000000000..2f9c9c8c2ec1cbf25f9ddbe79a7b01eefef27a48 --- /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 170c6f82ae5b97544a3a8a5ebd39a95fef8b5570..1d0b538d20bcdb8174f982c25de4da6a222ab8ab 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 0c007f958e1773b05416095b01e2a22a48f2bc3a..d2d8f2c1e763cdaf8c406ddeb5df4c59bb3a52a0 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 39bf9055705c31ffd0237d32ffe6d8c6022e2656..2c5a0156a68a69abb65e7452412cc6e83761fc8f 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 0000000000000000000000000000000000000000..5315ab52020d369f3d3afaa7c9d872c562f9c490 --- /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 43963e25ad7f5aa302db7df3e3d26dab5e160850..d0f2ccb3f17576314fdf7a17bf66ba6f07145395 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 0000000000000000000000000000000000000000..25db84e64c185ff86b919ef657d5ee70336f3198 --- /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 5245a2d62cdc56b0eb9f63c3cdaf6f3cee40b7a8..d81d53201455f0ada1fe33ea6e4a4bace2203c36 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 b5ee7dd8b058c2cea9bd31b33bf467f4fe2fec89..cb9d368e53eb0efa32a50e1afd5203fc75e4973b 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 32dc86687cc060a309d2b34266a89639050d3924..efa05793972245de19d37510402fa1fe615b5159 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 1d22cc69c60317bcbd5697ccc722867d1556ccb7..daf6c1b32e1f0ef2ea3d07d981a17b59a6701bef 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 0000000000000000000000000000000000000000..25c3191e90da23748aac0dbf3714598c1ce0b21b --- /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 8c24d2fdf838c4239d425617e9d8559f1959d414..fcd46e65a992258935ced219dfa50be1d79a7534 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 7c2bdaaebce054bcd5ff2dff65c8092a59e8d921..e60ac59a15dd4de104ae6249623495c0de3bd56d 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 7dba589877cb986515ada0aee2763c3b698abba0..f0409b167250392b459c3696e23a18ffc2b0029d 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 0000000000000000000000000000000000000000..ee1d394da88fa207ef74162ab2a116a6c70395ee --- /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 88eb6b61356c73616007c7fcbea948b4b34db103..0c390168af587782e4337ed9f69a89960882c343 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 b2d0a5e3ab5b98a9bb1e95fc3760ae247fdc705a..663e472901603e6e2c8f62bdef5e674e8b4a222e 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 0000000000000000000000000000000000000000..e6e48bfd02abd7759109d46b53fea4a3956e9de3 --- /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 af9e7152a3b19bf339d30d62495389bc3a4fc4cb..365b33b0b557787895f3b6fd9738f5d5e983595a 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 50cacdafbb690c85db8833f14eebe5971f912363..b8a1b960bd571b72c367fb1e381cdfadc51bc571 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 457fe4facda4463ed73a8bed3a23432414e2bca9..28679d7e18790ac5bedaac2df5b989e842ffc792 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 4446f11d1b7bd97743cb61dc432ba8220c5aba70..7b9a228195025966a572a489f1dd3165bbb09dc8 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 ee65f4017e0120c2656809218f0b3e18d48fb7e7..7fd51a87c1d723955686a93d8f6ae0fa86b86fd9 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 af6ff4df926885011ea0fd429a0306acd522997a..5a1b0957e60f5e5edae5f633e0f74967c5140598 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 0000000000000000000000000000000000000000..ec02173eb86cd483f4cd897cccf2601b452096eb --- /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 6149d9c0ffad26c4e2435b0612a36bb6dd777085..3fc02e2f2afa67c4c5ad9b04614e43b3a8139231 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 9e24475104ee843278da56c132398ebf2dae7d8b..b827ae2c1cee1e6041ca2e38a7a6b650fef802b3 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 f0c6417805d0d77e07bcf3548dda2b8b0028e741..adc64a10f669b0dffaa3c27d42bfb15f6cd1526c 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 0000000000000000000000000000000000000000..85d9d407a77e18d2a9677ce3398bf3ef98557c5a --- /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 131d969570a13667352a0198c2331fe04d0aabd1..9bb7c62dda9afea42fddab3d9358fc53a3935712 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 0000000000000000000000000000000000000000..06f360e8dd91e225f86b0827ecf964ea07ce61da --- /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 0730ab94272fc933490d1df184f8c9276c8046f5..06615cd59467242206be9f96ecc258aff791c767 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 a03f8713bdbee2aa29921bb084e6997991af54fe..13f5d2a747db327d26f4a249aaea52b775023974 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 0000000000000000000000000000000000000000..f3bc1edafe480f8845a754941554caa3b131bfe3 --- /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 0000000000000000000000000000000000000000..50454369d540a14bee9111b84adf35173eacabe4 --- /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 e203063c6e194ef4a3e2b6fe95e86662db2dbd1e..0e28156b3209d544c5ec2313ebde403d279d4145 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 732521f44ea59edc13763e4c79471a4ae63a4208..fe319ace2b42a4e0fec78c4eab905595dd36732e 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 28921ff72182ea2565151f9b23597a86c160c0cd..9f40250b2984a1301ea0ae9f12d86ffa29cce2c0 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 d260cf032ad4451d028a95abdf88cb0b2a5f5b25..486b8999b088d0840978f8afa54880160cbd5841 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 ac4d35cf60270236ef81dd5f881b782842a14790..93e3a7df2be494c56b0276a2a8e38facad238d6d 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 0000000000000000000000000000000000000000..5a0e8b35cd607053c7f021da4ba14773e9512e55 --- /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 0000000000000000000000000000000000000000..1b02cb12275c51f47939438c4bcfaf202bd75cbf --- /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 3f9f8ad94eb495a6aa68ac2dd8b6890790318a18..9532729d47152438a1ebe0456189a6343042944d 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 0000000000000000000000000000000000000000..a2c8ecdfbc20e1c8fc1def0a8be1c2ac982a102b --- /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 3108505ed9779ea00a92b3637be3c8c4c081f707..e9b20bf16041943a5df78d09d4d326839f4f2920 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 ee4bb941cf6bd10c6d4be930e57aafe8e02054a3..71348817a36845c6b989f3136ac989aa0abd00b3 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 0000000000000000000000000000000000000000..1768e445ac37378fc05f8dd001c546fa58453c45 --- /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 63edb94aa5b716410447511ddae9bf94c24cc1da..bfd19652b68fdebfa2e723849ab4db87d567c841 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 c63666faf3bf512c328a3c82878f1bc0d1c55198..dee066cba5b1807045997b8444b6c58df6dfe389 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 3baceaa4d9c85f7e270e17f7c760d872e14c6f94..a48d6ead14efc0e42da53eadc99e379e139774b3 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 0000000000000000000000000000000000000000..66e9e733beef620d46cbb873ad4e55a6aa7289d2 --- /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 d964d585a7b9ab62590c63e1b24230e66c4d091b..cc4185e87136b64225d905431e31fe511c00bf17 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 b21b8bf2a29645e4c7e886a7aa91782f233e899f..8050ba5e666308143361a5eff0aedbe430925e53 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 00ee3e9998fe4b9cea2541694eb2cb4ca81ad40f..e762221af52d33bf2372bbd2bfef5fcf06fefd78 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 0000000000000000000000000000000000000000..2a4e3b1a846e0e92044a09e3757e42a1d7c46c10 --- /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 fde8b8ae5c1c632500f14f0400e38a46907a4538..1d6f7e46f8b58e6b42dcd6eb4338affe3d474824 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 70e2b3ff732ca44c31acac386c57245178798275..bde328d9e5e3cc362f15d59b7a77316502ea4775 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 aece054fded3a51c92dd41a4b09b770e4b7aecdb..b983ff0eaa73070b714f8bb06134e21004e6356d 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 4c771b4ba65c25eddec2741d29863af9cb17222b..5dc7299843978865fec11d9103ea519e1ee5af89 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 98103173063315850752f8c4752b70d09799325b..7034447afaeab3524567b74eb98c7bd3c65f7d7e 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 52371b1e45ab1ac08469a56607133e18cc6716d5..64cd7d08075a7c43b884ce6076545c30a0564990 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 9be275dbcbc2dd2895074b44496af4dac6efcaa6..0000000000000000000000000000000000000000 --- 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 e119fc56a965de9e8b83f851b07fab6317e4f27f..0000000000000000000000000000000000000000 --- 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 c47633091d786c9c51ed40861ce8b890de856de0..497be012cd64708407554ad46cf04fbf7209ea46 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 834803facf27aded5a96a460e8279212375a4ba4..b42f61674e7006846d45bea50ff794f170656179 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 0f0740e0c17ea42f74516a8c3592b2579804220b..73e8c457bf22ce7236f06b688646617fb95be4fb 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 f04e99943b32c12669112eb74f7ba031774b9889..41b907764a3dc4d8a1629947c77881f46693294a 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 b2f3c5bd5e047c001db6cc077f52f61fc087220a..db750c1d0118579e6d2c50bfba567200ddeeb689 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 a70c96d58eaa811b0d84ef9e684207e771a7d73e..4d6a34517ac88ab587e833ccd4182a7159855c06 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 b80438a7255e5d2d53f3e3a5317e495abb2031ea..0ca0e2f714c37a6e98b2f3e49d71da27e66211d5 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 69a499291bd58c1a46590a855eaf1e7e9ee31c08..de9a65714b7826481ccc04f2ab949857bd17336d 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 0c33b07569c3977bab84e037a7c567a759ebd923..0000000000000000000000000000000000000000 --- 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 3cd8f430f03a59e723a675590650f913a553168d..0000000000000000000000000000000000000000 --- 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 1c44cf3123563f168c6c139bbd0c25d1cf811ca2..288cf25062591708dac56effdbfe04aa0a10241c 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 0000000000000000000000000000000000000000..eca00696edb4414df42fe6770cc23cde5a758529 --- /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 28cf6a292db199abf6c602b59a4c4c80369bf3f4..01a54da1eda68b49351e554a0f948999f7e2b58f 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 0000000000000000000000000000000000000000..f5860375583148d44d1042f15030d6fee1d9d50e --- /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 8366b36c5446c0039e01e0b787cc5e15d046a5a3..63706a7f727fd976355e7a80c9a90693396300df 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 eb680cd6e1ba34d8a7fd627b79e274c75259e540..1fa956cda86776a7619a84b5c84f58988eb4704c 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 0b3a33dba281547b4145c820460dbfd5ff1a8318..ba38a689e78a170489905bbebd4cb38bad7a7a5c 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 dcf28e56b847357509782ecc66a860199e703d09..bbefb21dabdab1ae6f26c2a8d391c17d38c0f931 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 9c46a765683a522fb9f9de7284e9808ff857cd61..7e4b6879ce6f4bf478bf9e7d88c2080303afc73a 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 0000000000000000000000000000000000000000..7ec75bb1ac94ef4667c166316e58cedcac38ecd9 --- /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 be0066e5515ff61332f5a86e800ebebe75f7aff3..0000000000000000000000000000000000000000 --- 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 d0109ae11df6af7892704e224a8174686ce3147f..c37793f95a8a3796c00ccba2b0a7fc343cea5897 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 a4173d242a7554100f8a6f9ce3b49d70000bc63f..0ee25b180b319d20bb348b3ecd09350a48ed99af 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 5b301bdf0971c67d5be7fa840d38a9864263e6eb..8226fc661de41645a5a93aa4b17aa49dca799cc8 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 c9cbf1264f4c4441ca8395f2beb68f5d92edcc87..e624899814f37f2cce63a4a2467e8fac6551a55e 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 0bc62b105489e7202c9ceef57ecca2a8fd1f0fbb..8fdf5aa2b272763a6851b2d3c58a38235077e520 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 e0e09f04ff89d80b934c108168ba931c4ece8560..5a6d5cf775dc69aeeb60b5d85c38d21ff87b803d 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 0000000000000000000000000000000000000000..b01fd685a0a5fcd560e92dcdc7806c6471fc284d --- /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 2e6e36ec654a5437c3fe1ff80ee9fcbffee92995..5b41c11759b308e4a14b8427687ad9cd38689c7e 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 f78e7577249e8095e024e77e41cb110f8956fbc3..b0d9fc60952175441a4849fc190489c91d125a6b 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 2d52213f1f351a643a366e523accc76aa6eadb0b..825117b42dc99d7b35dfa2e76671d14964b30025 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 65e5e78fe614baf888667962da9abcd9879ee615..768cd31584403f539c5dfd8c0214c94463ab76f3 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 99594a33f19537bcaad025088e557d2deea31d4d..4b04f16f274fac8bab95cdbb76bf754e557c4736 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 a958c96cbb571de78c493d9205ed234ce91980f6..d523421507c2288333b41ac4953d2e199b5abdc7 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 7802aa7674585029fa29a18cecd92a4f47cfdc55..0000000000000000000000000000000000000000 --- 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 8a5f8e6d44e33613e17bc47b28d9aa85d20ddfb1..0000000000000000000000000000000000000000 --- 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 90bd86709a471ce333208984a7cb26586a36b13a..0000000000000000000000000000000000000000 --- 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 49f53c863816e9f27a808a14e8dd03645c2ca417..0000000000000000000000000000000000000000 --- 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 4b1d7cb945a40bcc614546ea08587c6478c90c23..0000000000000000000000000000000000000000 --- 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 74242ae48e37339e50b2bd28f2d83b785554ff6d..0000000000000000000000000000000000000000 --- 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 3fad9bd8f16e16b1eb4119bee82d97f4bb01bef7..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..824599a0e3e95a7c14798637f6f3278e41ac6fc3 --- /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 0000000000000000000000000000000000000000..049bec04240cccd805aefa167921a0798ec45696 --- /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 0000000000000000000000000000000000000000..5459d49b4eb130d5151beffdf9f4ea2e0420cf22 --- /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 0000000000000000000000000000000000000000..e3a021bd51846c2c1c4bd03f2a210465291ba5cd --- /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 0000000000000000000000000000000000000000..86d388e4cd5c639766b36b27d20146d2b82dd7dd --- /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 3b138c5b5b8002d6cc2b2c9940d2875d9c002b84..3e295549b5869cbff9370bf1384da36cddbc1e71 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 8b33e2f1000da5c9b825671fa612f0dc00587ca4..bfebc78dba1d3338bcb1ab663561822184cbd0ed 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 47dc8889f5f1ed557e9568c4634fecd58354d3e6..0000000000000000000000000000000000000000 --- 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 427390a2b36945a90a80533bc4bdfe09d12b7f03..ad61bac5d19c52bc31a135e7fa3f930379f2aa05 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 c2593d5b55baad2cec577108e4eeacd6819ed567..bf269a70df482430d3212b6336d33a9a9a4b398b 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 d6abcf72ff2e94656235820db5f43621da696689..ea621b135c09b70dbb096b4b1b60a890a427860b 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 d359bee26498b53017a9aec516a65f6e2472d726..a0dfe3d8642abca18b02ca7e220b57da4840705d 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 eaf1d5c68ec5b84d51279c8e006a2aa20b0aff34..00cbacf5a1957dc6b32fc2fff1bf876d5ad36ab3 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 318beaafc4447579fd829852a66a44580200d607..0000000000000000000000000000000000000000 --- 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 7ce50312a5a22c0b651334dc781be9dc281c35c5..09f8555f0811309e45d8273a14fb39d1560b3fff 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 1cad8013e89bdd1a1059f03ac8115dc926e2b803..98ec21ec948f38b7b156b94ad9c08dca833bd8ae 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 afc9586ae9f451d9014b36f8e8dae3b6e5d826b5..dcbde19281e0ebd0ecbddc870608ff8f39b05e46 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 073b6665cb3f6584126fbf4a6c9df73813b8d987..0000000000000000000000000000000000000000 --- 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 e756544c7f3eba48503d54ea0056c201cf493d63..702b9eca62b6a93dda9847b9404d0e3d4393865b 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 c2417248338a8023ea902ac52dcf67ee7dee311b..0000000000000000000000000000000000000000 --- 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 29c2ac539f9404c4dea84b83760b6121184ce861..0000000000000000000000000000000000000000 --- 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 54b638dc1eafc6095f18e05e47ee64dc6bbd9fd8..0000000000000000000000000000000000000000 --- 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 f2625ec3bf1cb126423b89f0373e040f4e894001..0000000000000000000000000000000000000000 --- 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 693343670872bbcd69091a650005166d2b2ec4b2..42e592856a30781ede116085101320e4d35eda27 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 16f6a9651685aa634dc08bd621b75c354498f9e0..f3e4b2ce8fb040677c92f575304f8ffbe8fc1fc3 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 704e22e303fefe2ebb02575e0e4524084640d005..aab9721fd941db6ddd8080281ef57372b8f4d17e 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 4b5e6d1e3ab61a03f0a55b57b3ef8a4b1b44fc2d..0000000000000000000000000000000000000000 --- 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 991764848866e5a2004ab765ecb93649d1e646bd..0000000000000000000000000000000000000000 --- 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 ef5d54339dcad7ab3459e78c1edc150a095eb63f..0000000000000000000000000000000000000000 --- 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 e49c3f08f7c4888ea20b5c4cc190eaa21823c586..0000000000000000000000000000000000000000 --- 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 e684bbef339b23236cfc230903a665af475009ec..0000000000000000000000000000000000000000 --- 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 b86987bbcc27000cf0098d7508df17e44081d3eb..0000000000000000000000000000000000000000 --- 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 0bbab6fa4ab471c33017e9bbfe79fab52a759080..0000000000000000000000000000000000000000 --- 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 0adad0aa37cc3f6080f0f4555cf06a913fc203bd..0000000000000000000000000000000000000000 --- 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 bdb858ab5c1fba3d9caa5a35ae02189ae1683c99..f323c19b3af44e0e8d86e17af78f69cf65fd8773 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 dfa66339e877e3b702dcc212b7815e60947bd648..0000000000000000000000000000000000000000 --- 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 7f1d3eba2ec3a4b4dc1bf8cdc2e4aadb160a9fc7..316471eac6339438fca259c340423dea26e2f131 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 34dfc9e5d3dd27e6067532eb92e371788a5adc36..0000000000000000000000000000000000000000 --- 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 20f6d134cc7ac71969ba75f5b075ee715dfabecc..e890ea8cd6b389115598194377faf1b1a84514df 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 c98aac82a9bd67b3bda6fe308998146fda707343..0000000000000000000000000000000000000000 --- 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 90d5003d3d72a2e25211c8d4df66a22cf211e7b5..0000000000000000000000000000000000000000 --- 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 8afd1cd0a750b780aca9be75218265584c18669e..0000000000000000000000000000000000000000 --- 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 c1a2d057121ded42b20bf7dad63a22037f2e001c..0000000000000000000000000000000000000000 --- 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 c956286fb510df618dbf66fc589cc9f2d49f65f1..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..0e10d8a5e714545eb97c2ae22cbf433a2eaaf7eb --- /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 718b6a5a5963e541964aca901c1d78cf6613ff45..8b68b96f79e97b9d0939c4e8b2e2b930da6deef7 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 915778ddc99c5cd40cc0adf3c9d4c92213a05082..e8f96401a51ce5577a08ce232b3a295fa336f63a 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 5d717734e439e6f3c32ad1ceaf48b95f00a3fb30..67510baacf7f3f6d1f9ff2afd81678e59f1156b0 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 0000000000000000000000000000000000000000..0966cf2387d39336aba33fe5ea98942f957923fd --- /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 0000000000000000000000000000000000000000..90591b95936e5dc6af8d616a099169f95c9ceca0 --- /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 fed0c559fa7ff25625c315bf679966548bb85873..1f22008fda5edddd2366b1bb2a1d8b8794459b5a 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 Binary files /dev/null and b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/myfile differ 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 2f4c8ff83377289626b8b4414bc96946274ec3ae..0000000000000000000000000000000000000000 --- 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 bf63507434305659ea3ac3e86a69756ee029c0cb..0000000000000000000000000000000000000000 --- 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 646c79ad723e0e94a0f9582e201d71c23e181648..8bf2b3cfb6cd33ace17942ea84a4cee33ff6701b 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 5d2d9142ba3ee36aff56f9016b3c206d7116c98a..565a3b5193b3f1fac8cb3fbc051cde44d3b39dc3 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 b70afe94a758f2d5000b354d3a7755ab6b8e5b76..c4d624070cc6d8d70edc0ac5606140ac0e7f9e85 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 78c393f928427dcf0f910e92b9d218cc67a158c6..e67db26ad48f0bd46899adc7dad36df87777a763 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 f37c11eef9048c54d6ea6d0b9f26aaf78d81feca..a0024828c5ca76afbb346fea40115a865b22c865 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 0000000000000000000000000000000000000000..041f3bc4ef5e418b7a0610df2f71aa90b9415354 --- /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 0000000000000000000000000000000000000000..29e005355a1ff681d4eca36e21eea0a625707ef1 --- /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 245e32f0c14c5036a00ef553012b97713f474eaa..a3cb9fc04fb114d270bf71ec067e10407be50587 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 61acab1567341d02b37cbf306e2a0d38e284ac0d..0000000000000000000000000000000000000000 --- 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 3750483da3edb4513286a0fe6602e2ee114fb0ba..0000000000000000000000000000000000000000 --- 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 dbf4cbde6cea84dd684131fe2ace711289138176..e78070085912ebac2928437e06b4ac3e5f8a2d95 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 7dc4ee6256571c31a104d821b52837af62effb77..d156adc84505c882e1b4561c4f7884be33cd9d81 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 c8b5d3075bbe6591cc3aeac4ae77a4be85d7f40e..5064e7967b2d49c067480ca3c74c5c64789354e8 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 c23ca9cb807ca5ae41578ab0de163e0ee84d38ad..d1ecfe653b301cb959a2496a3cd5205a8cecf3bc 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 621e3076399dcf3afd0af9d1c7d9a2f5a6187d7a..55c24b14dd4f1783a26f40b269a45c17ad98ceef 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 d521478e07a61b677e8e766c35ba6bfd8a0cdf11..d066b9f18c755326de8f450272f47c908094818e 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 00ab93c775f6b4ba8e29c1cc38eca28a9a7920f2..0000000000000000000000000000000000000000 --- 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 fe4a43d80d5ae2ffddbb75b44f0a5633d70bb43e..0000000000000000000000000000000000000000 --- 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 9862495b06c299cc1f6b9a5ddb4d20f65fbd4499..0000000000000000000000000000000000000000 --- 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 a85bd17c5d8432ea3fd46dfc59c57652f5763638..0000000000000000000000000000000000000000 --- 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 87e09bfdd75bc0c78f86010928f497da0abede1a..0000000000000000000000000000000000000000 --- 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 615fee35da59cc1d1cdaa678bdad7352277ce6f2..0000000000000000000000000000000000000000 --- 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 3baf13ba3d89ff1b0274711182f008dc971cb937..0000000000000000000000000000000000000000 --- 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 da6b381f40da8a51c39aeffd5ca7791d3e74dd66..0000000000000000000000000000000000000000 --- 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 2fd3b0f945f687e66542bef066d2fff5dcbf998a..0000000000000000000000000000000000000000 --- 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 7dae3e71d7567f4170d0e9eef74e9d3e4ba65869..0000000000000000000000000000000000000000 --- 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 72dcca58e2d0e39e9a7a857c9521341f9b0b8a22..0000000000000000000000000000000000000000 --- 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 fa598b00e9101369398745a7de151371c1976bfc..0000000000000000000000000000000000000000 --- 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 dc268a6a317f57cf55ffd168afaf9e827c86cc1a..0000000000000000000000000000000000000000 --- 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 cb9bc64ff241ab4b654500886b19efdf99e7150e..0000000000000000000000000000000000000000 --- 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 7d60752e3a64529fec7df4d00bc2ae1662f40311..0000000000000000000000000000000000000000 --- 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 610b05f69c3cd51b50e16d29eb0855eaa7bd2dad..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..f8478ba69bf39bcc30be4e11370d00a4ebc4f751 --- /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 0000000000000000000000000000000000000000..555f97e7302dd286e8989b04475c257c3731187a --- /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 0000000000000000000000000000000000000000..d1ba5f1f1d2f07d34c2bfd27e52b6a12950d587d --- /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 0000000000000000000000000000000000000000..e8756a414f0b7b6ddff72a594ccb676f2a4e2161 --- /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 0000000000000000000000000000000000000000..559164c625ee7e565c11bceb7a2788fdeacfcfd0 --- /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 0000000000000000000000000000000000000000..f60dca15b6482b7ac8376c246040a0ed2df19634 --- /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 a294580420d504bad735dd1fb206f54820ed5d93..8c9735f1bf07cdbf0b3aa735dcd689f3324d35a0 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 bd12c2006e9289c86808d48dd67c4615be93a70d..3fca7178f7dcec3f0e18951623daa5dfb2f6406c 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 797f9b051df959d3c206d2b789b6d1a0bef16488..0517fc19f6bcbd3c2b7893e1ae8325635cbd7ec1 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 45484d1b596f07092c1db2f3b33bdb13dd95551d..16204ed610bb8c5dcb6c8b3d67f541028c8d682a 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 6918c47fc2eceeaf07a08dc0251efcb2e9af5958..5b7b9bc9736b9bbb2521f7fc4c6bf4c9643f23da 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 37599fac043bed54773dd3fede8057f84de1a3b0..0b80eefebb3049d4b54b200bb844ae41110d43be 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 3949f9cfaf4d075035ca1502e6e4c27d0ad079d7..10bb89fe2f2f0e5ea9bdc55fb5199083833529d6 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 5822bd53383495f484075e14cdc5c18dc658101a..3275877b081a95fd5e7c278c9811ca86d29dc46c 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 e48d183ee567411901728d1f92272cf9a9692a8a..5404f320a5a7e89cde0f5ca268916214b2e25cc9 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 78d1a50ddca139c0dfe98abb478c8434394176bc..cb0053fa0f6004466db943030bd70c8f406c9ef9 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 ffe00baf5a48953ea58a97c2438fab39cafd037f..05868b65ca1572d12c1dde0a9301ec795a12ea58 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 481ade28aecd4fa0badbf45db45a99da85604c2f..dbae504ecf475d63ca29a46ec0a8b50b67b9b07c 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 ed46ba2f2efef5d712645fc5d89cd8acd90dc318..800cc5b5ccfb91a7cbeb974e7d53b5c880e49ae0 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 8e861f337cd64097ab158d519002656a1e2d655d..33fcd6ee1ada2f712d221449fbcc338ffb43e337 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 f8d4ee928988bdace3ec14574e2a8e90aaadc6f9..b9ad0ba436192975805b0c5d092821a1f4f58c0a 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 c9ceaeb8df2c93da0dbc00ce28357343578dafd0..0000000000000000000000000000000000000000 --- 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 6775c703f61be92b3f10f29a87ba233c36494983..eb22ca154859080f8e6e77b2904371200f450c67 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 50b979c24c644ea89fddd01b7d26598e60d9e3a4..0000000000000000000000000000000000000000 --- 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 0b24fc78b937b849378212a60ac223f3d9b71e98..12568a2f6422a824f65f3f82c5f3d6cf3631a6ae 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 a6754dc36892827e5af92fb4605edfdda3eb1a04..1a6006dc1ee5f7b76442afd3b3097578f168e697 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 8fa2b44e25baff413907cf45ad5bf52023314889..873bd9bd5abfafb61376aca17d0258e843e9ff85 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 fef07dbfdb7b3d8769c50ef7bea39c44e4a89780..2caea0d2d97262c8041eeb3166189f49d2080069 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 ebdc9585d65a66477059c76d6ec50d48620f0bc3..1def3a2abec94a443b200cdbf759e359dc30566d 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 11985fb01ed87308a66699348bdbeda03de5f57a..b7f1dd9f84a64931b668e6a5816091e5a33d0973 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 243ab7127a429295d08c8332f883e414c21fa852..9b949a518d9b8412b4bc7ecdf7fcd554a207c82a 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 2022d14004d70f7e276f3b98f9d52d96d8cb8f09..2b829324d726b9981bca1626523efb7f20a3263c 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 45a2947a49fc0311d9f5cc230f328d63f60ac061..0e2789357ec21db621650da07dff2f960e1853c6 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 2f562927f6a99bb19852570f46b185f0e3da6c7b..d07d9598bb355d928a8f9f6d2e7b4f553786e2cd 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 69e5542e17a0bb17b733b16a336dec9573aa81fa..ce3283363748e31e8a612bd8b8d4a4f360aac461 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 02e96ecd0076564aefa908185110b6eadc47c285..84d297613198634820160174528f31aed20b66d3 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 7873d89da89fe28d0afd84d6eba94da75591bcde..1c038cd66b6f599ea0b1423af403935c31e1f602 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 be8db6cb37b8ff1084db9726fc6c8ebaa08709f7..c98a45a638e2130fe252c4cb77e2445e64d6cd9a 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 719216427a0cbd239e0ae187dcfac8bf14604a72..37760e9c26334c5751d2e5da0200e196234cda2c 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 43229a6b3c8064d07545ac78a93e2ce8e4b39207..6c96ac674637b33c0103623985cedf679a41ae96 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 c9c2bd746cdd0b40a4eaa9011a50293fc1a33faf..81d4bca5d4394d8f852d4cefbfcec1b1c594f1fd 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 2ca5d280c1b1cdb57330cb67cbaabe6e0c8cd877..83410eae32ca251670dfceb615e8a64d8aed40c9 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 97a7df78c571e45788c20c29ee66225474d5d393..c08eec29eaa8a848daa828c335c5ba922b5324dc 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 7fc366ef92171c2fa9748822b501703bbc8150df..2774abb2a811924b42dc35f73f2a56eef4a0f90e 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 8dc5c2fb0b59418f243bbbb4879ada59ce35fe05..01b5bded239c0bfe396ced056744f65beab4d06d 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 615b8478e1c8378e3f3ca982dfd1915ad464c196..e254328297c607c724a06eec013347a00a799485 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 6109c22531615096ab12f09283e302e384b5d323..24e78b5cf400ca4274cc874f38b60fe1d3aa901d 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 0e28643e7315a2689d9c372c90de9c51dfd5616c..69f1a7a5e8aa4b131a76ae09faf01e460b0d3e13 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 0b7b8d01cd1faccb30fcd8dd2e99429162e18f94..f2d15bdb6f16bd3a8ec3bfc0403411b3a3955129 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 3d5f053080fff9eb60e3ad44ef2328e4a6cee08a..043ba67fce17daf2925e8747827844f07d0b5e75 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 320b309aa590e13ae6bf02aa5ef7f5edfc5393a0..07031a7b9c3bd94af93b8207a6914b928267fd1f 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 e0cd5e4aba3ada36b732e0b390d48cde3bca585c..5e1b784ff2c617298c150a149618a6a7a2aaa252 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 181edbba15ffdb7164d60b90adc14f7f4ba24684..f6846bdf4708ed780ac8a2d9cc152eac3997a42b 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 920c043edaba155bb1f06c00b7f6f43d7f0496ce..d74e70cd6a62456af751f5d6f85ca26159b1904d 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 35ad0ea3ece6f1fe1d1ed105d2df3a0ef56413e5..f146a50e9eefc9cffe67d15d57af2a18cf13741b 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 82880ae975da279da6f2cc43c4f0b547079ef790..e0861876b6606566647c92f221e77da32f9e4f89 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 207e2df1ddf086591b05df0bde7dfe545fa0b5ce..6dbc77631c2d8ea70536e7ac462c3f57228c4534 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 87e09bfdd75bc0c78f86010928f497da0abede1a..505d536cf2ced18767aaebffb3c00b9cc3ead2d1 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 9c50cd4e4ba2c21ac09086fe8eac0f9828c4dd44..209dcd5e5966974fac6b7387311400f2535c5a62 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 979aba2e3ceb1a8d3f61bf4d7935094619579ed8..287b34ab13690075bbdfc08b7e15e885c970c41f 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 9204218fcfe1b72107d359b975cb7c49e7046af5..952c02b6fc06859a42c91f3bb67fc1586f23642a 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 d12ab5080b5248a36dec8237b5066b8a29fce1a2..a120d349fc902cb92a5d779afdcddd9a2289efef 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 6ea23aeb5a7b752e2ae5d961aa9155b150430c32..6753fe8e7ffba4144548d775a47a38062c09470e 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 5588d996161f338f6d6b3b8e928b74d28734d0dd..f13cd7301a7efba200fd2e3d1ddcd72ca41fc015 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 ad911e68bdf44db152144dc407d876157f95d615..d93395dacf42759d83c449ea999f5d65262b8221 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 2d9cdc23ed1646f3acb242904015df3ba1418945..bdfa44265a19b727a8ef9dad251632bcaec26f18 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 a18f6b6a6ec7420d469269b33832a2e5cc277a43..9067bf137b741db2a06094b0de429054bfcc493e 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 3c43ed17bd64c2600d0f6be5292e7d67690ed90e..13c32964dccb2c57208f730462999dfb07b34cdd 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 57315ac937f1c6a58a97410d3f8fe5a0045b3dcd..94e602b72e9b19c7ac885b1a2a8b83d1f6e7492b 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 bfafa4c2f9861f01192de0ad9b9aba05897d304d..a5debf5f78621a45beda0440ebcd95fbfe9bc8e6 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 720dddcdc3558da42500a501031bca8b87d4abfc..bd84d4766feb99d6ce55051fcf17a90a788d945a 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 aacad33d92109b6353e54b91b438b3f2f7e746f3..09e6fbdad3708856ff9bfa14bc8e2236a99ba1eb 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 a5a70031af162f749641075bd1dd01e32087946e..8b1ba444e437a70995ea69461d4d3c31e0500228 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 e6bc35dd44ff41a187084a9f21002001172b3bda..f333b1ffcbc5336199b3135cea926de80784c759 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 05d954b705fe5daf9980c7bd84d9b98dbb5c20b6..55bfb66676a76ad2c610f67874cbb62b0196efcf 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 b37166fdd73c1ebf945830778079a20ceca0b95f..b5d4b4caae74308238f48a5b9ba9ea4f25d25e51 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 069ef8bca00c623b65dcb5ca40ea2267d1ae35dc..a53675bd980c812548de4311523fa68b1a5a5955 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 1f572a2108044082d9be6fbb0229af6a8418286f..4e65bf06746e085c5ddf4597b23751ef8d255a5c 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 b4149fdecc2d6a1be862e3b43957baab830ad01c..295cc1aeda09a4a88820cd16e55b7dcd279c132c 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 e47f98f8cd8197bfd7dd90108773d521c9c034bd..4f1c03d0958fd695c5399a540c54489bea6f567b 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 5b102b5703e0474c1ee2db377f3b95c7a8705c3c..316471eac6339438fca259c340423dea26e2f131 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 15443688e4c874fd86f7bf12aa954bf5f7b3ea97..12ab10a482b6c621a52be362446327745b5c8e12 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 fa1fb628ab9175bd1b28ca2ed806dafbff1b644c..da2dc1e2f92ea7d7bd97e9f15134225c912bd656 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 9c917e78c3103755c42462fccc4f766e54e48ccd..596b1782e4a0c495e0a1f09d0632feffbd227b69 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 49d6dd28d8647a023c7deeb5e0b2d85e351ac5d8..32a070bd9af67f3facc69281cfc802e7e55bdf1e 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 b3ed160c902fce5129b3648bf5044e5ee845bb15..06e55bf12160b25a0af6a6c4747dbf489bc1da70 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 a943ec72844fa37791c4771d78b5931231512ff4..f07d2cfac8f1cd12f32d4c0a253a85fe57bd3f84 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 8886da405c2b3b294fbfa6586b0be9d15f74a7b8..95e34d23979f2edf9921685ccba1b6d24b9e4a7c 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 ba0905f2d9f1710b82a46d230ac68fec15ca4e1a..adfbc98b2918a47670718af17f831ff86b9c199e 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 0d2944b127b9f6407d09c1a3e8bd36ea984fff10..fc5c65caad768b6e54a51bba18a02061dc48bee4 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 c8b71556aec9a058cd76e0b9334b18455a999a69..03d09e470d5a195217e50d12d15d25bc09f49f28 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 2ac5dbcc09a8201c2bde87e2f2114587205408ff..cc415a0e7aefdedbaff975774ca8ab0f88b312e2 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 807206012dc390c919a5c88dd26c64c7abb29d65..dbf50eff00cb111f2eb1e60fea15286c7e361e01 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 3b5749aa245f1010e6fa4e8528be0a60751aad53..2d62401310e52cd5b3b523eec4466b2336e8b458 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 69777eac77c3733f0e81fc2f347d9c15b1dd070e..e7fa397b82a8d4a623bd22f6ef1eab3237a7d3eb 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 54d2ce48271faaa8fd98432e9ba9151c9c83ebe1..3acb0a7ee4033d2c12ae1594a94ca9759af0761f 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 406fbbcd8ac867c51f4460f10e51410afb038aac..4f08a3c45f73170b113a1cef609d13220fb7a2a0 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 c47bb8ceb2ee95fa10d3c97cc8a2059faccecb13..444d28abf173232c322e7390942ce9d68101a198 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 9059773cc2aaddd9ec656cce28e1163b3dab4292..dd89e533ae7c19d5c555c097f4830265b76df1cb 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 cb982879786196ca20c6e3c6eab16b1b1ecb76e9..e8f96401a51ce5577a08ce232b3a295fa336f63a 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 edf7046c4b5e4ba7b54550206a0056b10c0082a2..522658e451199abf9b8ec0a19d93a31e79e5af53 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 dbe8a67821e8d2603e19e7ee716b2c61d80b0309..1f22008fda5edddd2366b1bb2a1d8b8794459b5a 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 e39dd447dc648d64dcd3b66377839caef5fd9117..a65666c32a1dea08511b22585fdce5e0a8e357fc 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 8e772b9ac7fef275e561924c658d50b49ee16917..b52e4df7b2a01e7c88dd73bdf47867921990195e 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 deef5ebb81a9af2c5fe4074d10662ebab3bdb145..69046d219592a4d071331a09855db0c998003e56 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" )