diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index b3a9d001ffcf7c99c405ef40b211956e123eb7c4..3d4efb7296d5b0cc709335125d164beded97cadb 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -125,66 +125,6 @@ "Comment": "v2.3-36-gc65281b", "Rev": "c65281bb703b7612f60558e75b07c434c06e2636" }, - { - "ImportPath": "github.com/tendermint/tendermint/alert", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/blockchain", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/config/tendermint", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/config/tendermint_test", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/consensus", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/events", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/mempool", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/node", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/proxy", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/rpc", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/state", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, - { - "ImportPath": "github.com/tendermint/tendermint/types", - "Comment": "0.2-19-g12c7f00", - "Rev": "12c7f00c44c4a0f9922cbcdf7491d8433639667c" - }, { "ImportPath": "github.com/tendermint/tmsp/server", "Rev": "1b7ca808beb0d1be7bc9a606f6aa46cc1f65fd93" diff --git a/Godeps/_workspace/src/github.com/tendermint/go-common/service.go b/Godeps/_workspace/src/github.com/tendermint/go-common/service.go index d2d8f2c1e763cdaf8c406ddeb5df4c59bb3a52a0..ca923b1d56aa2d6f1503483112621d62f007d1f8 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-common/service.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/service.go @@ -41,7 +41,7 @@ package common import ( "sync/atomic" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" ) type Service interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go b/Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go index 2c5a0156a68a69abb65e7452412cc6e83761fc8f..629e9f865852e8ee3fafbaa058e37f15ef347149 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-common/test/mutate.go @@ -1,7 +1,7 @@ package test import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) // Contract: !bytes.Equal(input, output) && len(input) >= len(output) diff --git a/Godeps/_workspace/src/github.com/tendermint/go-config/config.go b/Godeps/_workspace/src/github.com/tendermint/go-config/config.go index d0f2ccb3f17576314fdf7a17bf66ba6f07145395..342fb128a042433588c85ac66f6f5306910b1e45 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-config/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-config/config.go @@ -5,7 +5,7 @@ import ( "sync" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type Config interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go index d81d53201455f0ada1fe33ea6e4a4bace2203c36..f548172e4e6a4dad19e93eada1522c52cef2021e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/priv_key.go @@ -1,10 +1,10 @@ package crypto import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/ed25519" + "github.com/tendermint/ed25519/extra25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) // PrivKey is part of PrivAccount and state.PrivValidator. diff --git a/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go index cb9d368e53eb0efa32a50e1afd5203fc75e4973b..c4b981c2b8cdd4cef5009e2b6026501973923635 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/pub_key.go @@ -3,10 +3,10 @@ package crypto import ( "bytes" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/ed25519" + "github.com/tendermint/ed25519/extra25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/ripemd160" ) diff --git a/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go index efa05793972245de19d37510402fa1fe615b5159..95925809192150020b571938ce09d81c690c9ec3 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature.go @@ -3,8 +3,8 @@ package crypto import ( "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) // Signature is a part of Txs and consensus Votes. diff --git a/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go index daf6c1b32e1f0ef2ea3d07d981a17b59a6701bef..1dbc580964a9f7c803d19498270f9c755973f853 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-crypto/signature_test.go @@ -4,9 +4,9 @@ import ( "bytes" "testing" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/ed25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) func TestSignAndValidate(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-db/config.go b/Godeps/_workspace/src/github.com/tendermint/go-db/config.go index fcd46e65a992258935ced219dfa50be1d79a7534..da66c21585734b2ffc9008848d799b64dbdf813d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-db/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/config.go @@ -1,7 +1,7 @@ package db import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" + cfg "github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/go-db/db.go b/Godeps/_workspace/src/github.com/tendermint/go-db/db.go index e60ac59a15dd4de104ae6249623495c0de3bd56d..2d9c3d2b17ada8eed6d410748ab3b872f794247b 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-db/db.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/db.go @@ -3,7 +3,7 @@ package db import ( "path" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type DB interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go b/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go index f0409b167250392b459c3696e23a18ffc2b0029d..66df8e27b36f9df862e57b54ad763f8a39ed6c5c 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-db/level_db.go @@ -8,7 +8,7 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type LevelDB struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go b/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go index 0c390168af587782e4337ed9f69a89960882c343..4083152a0fe3a2a86885f238d6ff49aac5127cc1 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-logger/config.go @@ -1,7 +1,7 @@ package logger import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" + cfg "github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go b/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go index 663e472901603e6e2c8f62bdef5e674e8b4a222e..e616d0ac891634ec2d9b53b136583f15eede5bce 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-logger/log.go @@ -3,8 +3,8 @@ package logger import ( "os" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + . "github.com/tendermint/go-common" + "github.com/tendermint/log15" ) var rootHandler log15.Handler diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go index 365b33b0b557787895f3b6fd9738f5d5e983595a..7c6ea1f057790952d90ad8f5052a72e3ecbb4fb0 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_node.go @@ -5,8 +5,8 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" "io" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) // Node diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go index b8a1b960bd571b72c367fb1e381cdfadc51bc571..9fbf2d6b08008c82c8d33af90c73febb7e542880 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_proof.go @@ -5,8 +5,8 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) type IAVLProof struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go index 28679d7e18790ac5bedaac2df5b989e842ffc792..ecf496e764ec128039fe0fe24ea25924fac70927 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_test.go @@ -4,10 +4,10 @@ import ( "bytes" "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common/test" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + . "github.com/tendermint/go-common/test" + "github.com/tendermint/go-db" + "github.com/tendermint/go-wire" "runtime" "testing" diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go index 7b9a228195025966a572a489f1dd3165bbb09dc8..2fafdc741de0745f35fb8961d4748f7674da20a3 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/iavl_tree.go @@ -5,9 +5,9 @@ import ( "container/list" "sync" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-wire" ) /* diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go index 7fd51a87c1d723955686a93d8f6ae0fa86b86fd9..74da2eab8b07ab0ac92e8c53bb0f76386242c7b9 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree.go @@ -31,8 +31,8 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) func SimpleHashFromTwoHashes(left []byte, right []byte) []byte { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go index 5a1b0957e60f5e5edae5f633e0f74967c5140598..016d179dab720d7eb93c442cb80afacb8b76c238 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-merkle/simple_tree_test.go @@ -3,8 +3,8 @@ package merkle import ( "bytes" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common/test" + . "github.com/tendermint/go-common" + . "github.com/tendermint/go-common/test" "fmt" "testing" diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go index b827ae2c1cee1e6041ca2e38a7a6b650fef802b3..14b39b57516b2c87242a70ff54343ba8eddbcddb 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/addrbook.go @@ -14,7 +14,7 @@ import ( "sync" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) const ( diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go index adc64a10f669b0dffaa3c27d42bfb15f6cd1526c..494fdd7535f7ed54901906d4012ee5aba5499202 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/connection.go @@ -10,9 +10,9 @@ import ( "sync/atomic" "time" - flow "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/flowcontrol" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" //"github.com/tendermint/log15" + flow "github.com/tendermint/flowcontrol" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" //"github.com/tendermint/log15" ) const ( diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go index 9bb7c62dda9afea42fddab3d9358fc53a3935712..1d7fb95698c8ded0fccf0d13d957579e10bee72f 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/listener.go @@ -6,8 +6,8 @@ import ( "strconv" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-p2p/upnp" ) type Listener interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go index 06f360e8dd91e225f86b0827ecf964ea07ce61da..ac1ff22a5ed80ff18fa4f84fdc6cd99227a293b6 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/log.go @@ -1,7 +1,7 @@ package p2p import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "p2p") diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go index 06615cd59467242206be9f96ecc258aff791c767..bdb42a00493f5ded6623a593183a9b0c94c6f8bc 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/netaddress.go @@ -10,7 +10,7 @@ import ( "strconv" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type NetAddress struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go index 13f5d2a747db327d26f4a249aaea52b775023974..a0f153fe370638a0528f19a61c3be301fdc6bbd5 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer.go @@ -5,8 +5,8 @@ import ( "io" "net" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) type Peer struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go index 50454369d540a14bee9111b84adf35173eacabe4..ceb10eeee286cf11cf945fb9631d89f9feaf7dad 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/peer_set_test.go @@ -4,7 +4,7 @@ import ( "math/rand" "testing" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) // Returns an empty dummy peer diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go index 0e28156b3209d544c5ec2313ebde403d279d4145..f6dacdb130f0fe9efd4654c3bd4186cf9e2ff241 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/pex_reactor.go @@ -8,8 +8,8 @@ import ( "reflect" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" ) var pexErrInvalidMessage = errors.New("Invalid PEX message") diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go index fe319ace2b42a4e0fec78c4eab905595dd36732e..385a7dab7ebe06fff9c99d2ae367a53a5d4e4665 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection.go @@ -20,9 +20,9 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-wire" ) // 2 + 1024 == 1026 total frame size diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go index 9f40250b2984a1301ea0ae9f12d86ffa29cce2c0..9bf1a7b1dd25c4d0317a79ebdba4ebc138fc6a53 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/secret_connection_test.go @@ -5,8 +5,8 @@ import ( "io" "testing" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" ) type dummyConn struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go index 486b8999b088d0840978f8afa54880160cbd5841..d118d95e5511626235a5da0238bf654fd6f5f37a 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch.go @@ -6,9 +6,9 @@ import ( "net" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/log15" ) type Reactor interface { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go index 93e3a7df2be494c56b0276a2a8e38facad238d6d..046649791303b346e65ff9945f35942179e58ccd 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/switch_test.go @@ -6,9 +6,9 @@ import ( "testing" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-wire" ) type PeerMessage struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go index 5a0e8b35cd607053c7f021da4ba14773e9512e55..0db2c957bcaca2b2b9dc397cada337586530782d 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/types.go @@ -6,7 +6,7 @@ import ( "strconv" "strings" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto" ) const maxNodeInfoSize = 10240 // 10Kb diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go index 1b02cb12275c51f47939438c4bcfaf202bd75cbf..edc5b498072209e651ca43d29df7e734b6a66a3c 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/log.go @@ -1,7 +1,7 @@ package upnp import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "upnp") diff --git a/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go index 9532729d47152438a1ebe0456189a6343042944d..5ba9b237019157c0ce25cbac3d1d86040ebfe13a 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-p2p/upnp/probe.go @@ -6,7 +6,7 @@ import ( "net" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type UPNPCapabilities struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go index 71348817a36845c6b989f3136ac989aa0abd00b3..fda9f3400338bb7117a7cabe0e4f37a08186d799 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/byteslice.go @@ -3,7 +3,7 @@ package wire import ( "io" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) func WriteByteSlice(bz []byte, w io.Writer, n *int, err *error) { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go index bfd19652b68fdebfa2e723849ab4db87d567c841..35d1a74b8827d95b8e30b0250f10bd5dba2ff80b 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/codec.go @@ -4,7 +4,7 @@ import ( "bytes" "errors" "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" "io" "reflect" "time" diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go index 66e9e733beef620d46cbb873ad4e55a6aa7289d2..5aeca07a7f8cde4e8d070faae48b783c665dfc59 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/log.go @@ -1,7 +1,7 @@ package wire import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "binary") diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go index cc4185e87136b64225d905431e31fe511c00bf17..1e25548ed63cf314e8d5a5d305feaa37aa1e7835 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect.go @@ -9,7 +9,7 @@ import ( "sync" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type TypeInfo struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go index 8050ba5e666308143361a5eff0aedbe430925e53..c8cdd66516074623ff937fc2daff611533fc9710 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/reflect_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) type SimpleStruct struct { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go index e762221af52d33bf2372bbd2bfef5fcf06fefd78..83c8fb1b4bb8b3c9c9f7724fdcd422bb53a2f822 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/string.go @@ -3,7 +3,7 @@ package wire import ( "io" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) // String diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go index 1d6f7e46f8b58e6b42dcd6eb4338affe3d474824..746b299ed8917296d80196994cd578880b5d9366 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/time.go @@ -4,7 +4,7 @@ import ( "io" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) /* diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go index bde328d9e5e3cc362f15d59b7a77316502ea4775..db9fa41ffd6a9411c43957276197e94a1e26918e 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/util.go @@ -7,7 +7,7 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) func BinaryBytes(o interface{}) []byte { diff --git a/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go b/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go index b983ff0eaa73070b714f8bb06134e21004e6356d..5bff4ced417e6327413093cb8622fc68731a45a3 100644 --- a/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go +++ b/Godeps/_workspace/src/github.com/tendermint/go-wire/wire.go @@ -6,7 +6,7 @@ import ( "io" "reflect" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) var ErrBinaryReadSizeOverflow = errors.New("Error: binary read size overflow") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go deleted file mode 100644 index 497be012cd64708407554ad46cf04fbf7209ea46..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/alert.go +++ /dev/null @@ -1,64 +0,0 @@ -package alert - -import ( - "fmt" - "time" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/sfreiberg/gotwilio" -) - -var lastAlertUnix int64 = 0 -var alertCountSince int = 0 - -// Sends a critical alert message to administrators. -func Alert(message string) { - log.Error("<!> ALERT <!>\n" + message) - now := time.Now().Unix() - if now-lastAlertUnix > int64(config.GetInt("alert_min_interval")) { - message = fmt.Sprintf("%v:%v", config.GetString("chain_id"), message) - if alertCountSince > 0 { - message = fmt.Sprintf("%v (+%v more since)", message, alertCountSince) - alertCountSince = 0 - } - if len(config.GetString("alert_twilio_sid")) > 0 { - go sendTwilio(message) - } - if len(config.GetString("alert_email_recipients")) > 0 { - go sendEmail(message) - } - } else { - alertCountSince++ - } -} - -func sendTwilio(message string) { - defer func() { - if err := recover(); err != nil { - log.Error("sendTwilio error", "error", err) - } - }() - if len(message) > 50 { - message = message[:50] - } - twilio := gotwilio.NewTwilioClient(config.GetString("alert_twilio_sid"), config.GetString("alert_twilio_token")) - res, exp, err := twilio.SendSMS(config.GetString("alert_twilio_from"), config.GetString("alert_twilio_to"), message, "", "") - if exp != nil || err != nil { - log.Error("sendTwilio error", "res", res, "exp", exp, "error", err) - } -} - -func sendEmail(message string) { - defer func() { - if err := recover(); err != nil { - log.Error("sendEmail error", "error", err) - } - }() - subject := message - if len(subject) > 80 { - subject = subject[:80] - } - err := SendEmail(subject, message, config.GetStringSlice("alert_email_recipients")) - if err != nil { - log.Error("sendEmail error", "error", err, "message", message) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go deleted file mode 100644 index b42f61674e7006846d45bea50ff794f170656179..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package alert - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/email.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/email.go deleted file mode 100644 index c183f1d588ebac91c993f363857ccff64224e24f..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/email.go +++ /dev/null @@ -1,176 +0,0 @@ -// Forked from github.com/SlyMarbo/gmail -package alert - -import ( - "bytes" - "crypto/tls" - "encoding/base64" - "errors" - "fmt" - "io/ioutil" - "net/smtp" - "path/filepath" - "regexp" - "strings" -) - -// Convenience function -func SendEmail(subject, body string, tos []string) error { - email := Compose(subject, body) - email.From = config.GetString("smtp_user") - email.ContentType = "text/html; charset=utf-8" - email.AddRecipients(tos...) - err := email.Send() - return err -} - -// Email represents a single message, which may contain -// attachments. -type Email struct { - From string - To []string - Subject string - ContentType string - Body string - Attachments map[string][]byte -} - -// Compose begins a new email, filling the subject and body, -// and allocating memory for the list of recipients and the -// attachments. -func Compose(Subject, Body string) *Email { - out := new(Email) - out.To = make([]string, 0, 1) - out.Subject = Subject - out.Body = Body - out.Attachments = make(map[string][]byte) - return out -} - -// Attach takes a filename and adds this to the message. -// Note that since only the filename is stored (and not -// its path, for privacy reasons), multiple files in -// different directories but with the same filename and -// extension cannot be sent. -func (e *Email) Attach(Filename string) error { - b, err := ioutil.ReadFile(Filename) - if err != nil { - return err - } - - _, fname := filepath.Split(Filename) - e.Attachments[fname] = b - return nil -} - -// AddRecipient adds a single recipient. -func (e *Email) AddRecipient(Recipient string) { - e.To = append(e.To, Recipient) -} - -// AddRecipients adds one or more recipients. -func (e *Email) AddRecipients(Recipients ...string) { - e.To = append(e.To, Recipients...) -} - -// Send sends the email, returning any error encountered. -func (e *Email) Send() error { - if e.From == "" { - return errors.New("Error: No sender specified. Please set the Email.From field.") - } - if e.To == nil || len(e.To) == 0 { - return errors.New("Error: No recipient specified. Please set the Email.To field.") - } - - auth := smtp.PlainAuth( - "", - config.GetString("smtp_user"), - config.GetString("smtp_password"), - config.GetString("smtp_host"), - ) - - conn, err := smtp.Dial(fmt.Sprintf("%v:%v", config.GetString("smtp_host"), config.GetString("smtp_port"))) - if err != nil { - return err - } - - err = conn.StartTLS(&tls.Config{}) - if err != nil { - return err - } - - err = conn.Auth(auth) - if err != nil { - return err - } - - err = conn.Mail(e.From) - if err != nil { - if strings.Contains(err.Error(), "530 5.5.1") { - return errors.New("Error: Authentication failure. Your username or password is incorrect.") - } - return err - } - - for _, recipient := range e.To { - err = conn.Rcpt(recipient) - if err != nil { - return err - } - } - - wc, err := conn.Data() - if err != nil { - return err - } - defer wc.Close() - _, err = wc.Write(e.Bytes()) - if err != nil { - return err - } - - return nil -} - -func (e *Email) Bytes() []byte { - buf := bytes.NewBuffer(nil) - - var subject = e.Subject - subject = regexp.MustCompile("\n+").ReplaceAllString(subject, " ") - subject = regexp.MustCompile(" +").ReplaceAllString(subject, " ") - buf.WriteString("Subject: " + subject + "\n") - buf.WriteString("To: <" + strings.Join(e.To, ">,<") + ">\n") - buf.WriteString("MIME-Version: 1.0\n") - - // Boundary is used by MIME to separate files. - boundary := "f46d043c813270fc6b04c2d223da" - - if len(e.Attachments) > 0 { - buf.WriteString("Content-Type: multipart/mixed; boundary=" + boundary + "\n") - buf.WriteString("--" + boundary + "\n") - } - - if e.ContentType == "" { - e.ContentType = "text/plain; charset=utf-8" - } - buf.WriteString(fmt.Sprintf("Content-Type: %s\n\n", e.ContentType)) - buf.WriteString(e.Body) - - if len(e.Attachments) > 0 { - for k, v := range e.Attachments { - buf.WriteString("\n\n--" + boundary + "\n") - buf.WriteString("Content-Type: application/octet-stream\n") - buf.WriteString("Content-Transfer-Encoding: base64\n") - buf.WriteString("Content-Disposition: attachment; filename=\"" + k + "\"\n\n") - - b := make([]byte, base64.StdEncoding.EncodedLen(len(v))) - base64.StdEncoding.Encode(b, v) - buf.Write(b) - buf.WriteString("\n--" + boundary) - } - - buf.WriteString("--") - } - - return buf.Bytes() -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go deleted file mode 100644 index 73e8c457bf22ce7236f06b688646617fb95be4fb..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/alert/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package alert - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "alert") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/log.go deleted file mode 100644 index 41b907764a3dc4d8a1629947c77881f46693294a..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package blockchain - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "blockchain") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool.go deleted file mode 100644 index db750c1d0118579e6d2c50bfba567200ddeeb689..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool.go +++ /dev/null @@ -1,512 +0,0 @@ -package blockchain - -import ( - "math" - "sync" - "time" - - flow "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/flowcontrol" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - requestIntervalMS = 250 - maxTotalRequesters = 300 - maxPendingRequests = maxTotalRequesters - maxPendingRequestsPerPeer = 75 - peerTimeoutSeconds = 15 - minRecvRate = 10240 // 10Kb/s -) - -/* - Peers self report their heights when we join the block pool. - Starting from our latest pool.height, we request blocks - in sequence from peers that reported higher heights than ours. - Every so often we ask peers what height they're on so we can keep going. - - Requests are continuously made for blocks of heigher heights until - the limits. If most of the requests have no available peers, and we - are not at peer limits, we can probably switch to consensus reactor -*/ - -type BlockPool struct { - QuitService - startTime time.Time - - // block requests - mtx sync.Mutex - requesters map[int]*bpRequester - height int // the lowest key in requesters. - numPending int32 // number of requests pending assignment or block response - - // peers - peersMtx sync.Mutex - peers map[string]*bpPeer - - requestsCh chan<- BlockRequest - timeoutsCh chan<- string -} - -func NewBlockPool(start int, requestsCh chan<- BlockRequest, timeoutsCh chan<- string) *BlockPool { - bp := &BlockPool{ - peers: make(map[string]*bpPeer), - - requesters: make(map[int]*bpRequester), - height: start, - numPending: 0, - - requestsCh: requestsCh, - timeoutsCh: timeoutsCh, - } - bp.QuitService = *NewQuitService(log, "BlockPool", bp) - return bp -} - -func (pool *BlockPool) OnStart() error { - pool.QuitService.OnStart() - go pool.makeRequestersRoutine() - pool.startTime = time.Now() - return nil -} - -func (pool *BlockPool) OnStop() { - pool.QuitService.OnStop() -} - -// Run spawns requesters as needed. -func (pool *BlockPool) makeRequestersRoutine() { - for { - if !pool.IsRunning() { - break - } - _, numPending := pool.GetStatus() - if numPending >= maxPendingRequests { - // sleep for a bit. - time.Sleep(requestIntervalMS * time.Millisecond) - // check for timed out peers - pool.removeTimedoutPeers() - } else if len(pool.requesters) >= maxTotalRequesters { - // sleep for a bit. - time.Sleep(requestIntervalMS * time.Millisecond) - // check for timed out peers - pool.removeTimedoutPeers() - } else { - // request for more blocks. - pool.makeNextRequester() - } - } -} - -func (pool *BlockPool) removeTimedoutPeers() { - for _, peer := range pool.peers { - if !peer.didTimeout && peer.numPending > 0 { - curRate := peer.recvMonitor.Status().CurRate - // XXX remove curRate != 0 - if curRate != 0 && curRate < minRecvRate { - pool.sendTimeout(peer.id) - log.Warn("SendTimeout", "peer", peer.id, "reason", "curRate too low") - peer.didTimeout = true - } - } - if peer.didTimeout { - pool.peersMtx.Lock() // Lock - pool.removePeer(peer.id) - pool.peersMtx.Unlock() - } - } -} - -func (pool *BlockPool) GetStatus() (height int, numPending int32) { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - return pool.height, pool.numPending -} - -// TODO: relax conditions, prevent abuse. -func (pool *BlockPool) IsCaughtUp() bool { - pool.mtx.Lock() - height := pool.height - pool.mtx.Unlock() - - pool.peersMtx.Lock() - numPeers := len(pool.peers) - maxPeerHeight := 0 - for _, peer := range pool.peers { - maxPeerHeight = MaxInt(maxPeerHeight, peer.height) - } - pool.peersMtx.Unlock() - - return numPeers >= 3 && (height > 0 || time.Now().Sub(pool.startTime) > 30*time.Second) && (maxPeerHeight == 0 || height == maxPeerHeight) -} - -// We need to see the second block's Validation to validate the first block. -// So we peek two blocks at a time. -func (pool *BlockPool) PeekTwoBlocks() (first *types.Block, second *types.Block) { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - if r := pool.requesters[pool.height]; r != nil { - first = r.getBlock() - } - if r := pool.requesters[pool.height+1]; r != nil { - second = r.getBlock() - } - return -} - -// Pop the first block at pool.height -// It must have been validated by 'second'.Validation from PeekTwoBlocks(). -func (pool *BlockPool) PopRequest() { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - if r := pool.requesters[pool.height]; r != nil { - /* The block can disappear at any time, due to removePeer(). - if r := pool.requesters[pool.height]; r == nil || r.block == nil { - PanicSanity("PopRequest() requires a valid block") - } - */ - r.Stop() - delete(pool.requesters, pool.height) - pool.height++ - } else { - PanicSanity(Fmt("Expected requester to pop, got nothing at height %v", pool.height)) - } -} - -// Invalidates the block at pool.height, -// Remove the peer and redo request from others. -func (pool *BlockPool) RedoRequest(height int) { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - request := pool.requesters[height] - if request.block == nil { - PanicSanity("Expected block to be non-nil") - } - // RemovePeer will redo all requesters associated with this peer. - // TODO: record this malfeasance - pool.RemovePeer(request.peerID) // Lock on peersMtx. -} - -// TODO: ensure that blocks come in order for each peer. -func (pool *BlockPool) AddBlock(peerID string, block *types.Block, blockSize int) { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - requester := pool.requesters[block.Height] - if requester == nil { - return - } - - if requester.setBlock(block, peerID) { - pool.numPending-- - peer := pool.getPeer(peerID) - peer.decrPending(blockSize) - } else { - // Bad peer? - } -} - -// Sets the peer's alleged blockchain height. -func (pool *BlockPool) SetPeerHeight(peerID string, height int) { - pool.peersMtx.Lock() // Lock - defer pool.peersMtx.Unlock() - - peer := pool.peers[peerID] - if peer != nil { - peer.height = height - } else { - peer = newBPPeer(pool, peerID, height) - pool.peers[peerID] = peer - } -} - -func (pool *BlockPool) RemovePeer(peerID string) { - pool.peersMtx.Lock() // Lock - defer pool.peersMtx.Unlock() - - pool.removePeer(peerID) -} - -func (pool *BlockPool) removePeer(peerID string) { - for _, requester := range pool.requesters { - if requester.getPeerID() == peerID { - pool.numPending++ - go requester.redo() // pick another peer and ... - } - } - delete(pool.peers, peerID) -} - -func (pool *BlockPool) getPeer(peerID string) *bpPeer { - pool.peersMtx.Lock() // Lock - defer pool.peersMtx.Unlock() - - peer := pool.peers[peerID] - return peer -} - -// Pick an available peer with at least the given minHeight. -// If no peers are available, returns nil. -func (pool *BlockPool) pickIncrAvailablePeer(minHeight int) *bpPeer { - pool.peersMtx.Lock() - defer pool.peersMtx.Unlock() - - for _, peer := range pool.peers { - if peer.isBad() { - pool.removePeer(peer.id) - continue - } else { - } - if peer.numPending >= maxPendingRequestsPerPeer { - continue - } - if peer.height < minHeight { - continue - } - peer.incrPending() - return peer - } - return nil -} - -func (pool *BlockPool) makeNextRequester() { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - nextHeight := pool.height + len(pool.requesters) - request := newBPRequester(pool, nextHeight) - - pool.requesters[nextHeight] = request - pool.numPending++ - - request.Start() -} - -func (pool *BlockPool) sendRequest(height int, peerID string) { - if !pool.IsRunning() { - return - } - pool.requestsCh <- BlockRequest{height, peerID} -} - -func (pool *BlockPool) sendTimeout(peerID string) { - if !pool.IsRunning() { - return - } - pool.timeoutsCh <- peerID -} - -func (pool *BlockPool) debug() string { - pool.mtx.Lock() // Lock - defer pool.mtx.Unlock() - - str := "" - for h := pool.height; h < pool.height+len(pool.requesters); h++ { - if pool.requesters[h] == nil { - str += Fmt("H(%v):X ", h) - } else { - str += Fmt("H(%v):", h) - str += Fmt("B?(%v) ", pool.requesters[h].block != nil) - } - } - return str -} - -//------------------------------------- - -type bpPeer struct { - pool *BlockPool - id string - height int - numPending int32 - recvMonitor *flow.Monitor - timeout *time.Timer - didTimeout bool -} - -func newBPPeer(pool *BlockPool, peerID string, height int) *bpPeer { - peer := &bpPeer{ - pool: pool, - id: peerID, - height: height, - numPending: 0, - } - return peer -} - -func (peer *bpPeer) resetMonitor() { - peer.recvMonitor = flow.New(time.Second, time.Second*40) - var initialValue = float64(minRecvRate) * math.E - peer.recvMonitor.SetREMA(initialValue) -} - -func (peer *bpPeer) resetTimeout() { - if peer.timeout == nil { - peer.timeout = time.AfterFunc(time.Second*peerTimeoutSeconds, peer.onTimeout) - } else { - peer.timeout.Reset(time.Second * peerTimeoutSeconds) - } -} - -func (peer *bpPeer) incrPending() { - if peer.numPending == 0 { - peer.resetMonitor() - peer.resetTimeout() - } - peer.numPending++ -} - -func (peer *bpPeer) decrPending(recvSize int) { - peer.numPending-- - if peer.numPending == 0 { - peer.timeout.Stop() - } else { - peer.recvMonitor.Update(recvSize) - peer.resetTimeout() - } -} - -func (peer *bpPeer) onTimeout() { - peer.pool.sendTimeout(peer.id) - log.Warn("SendTimeout", "peer", peer.id, "reason", "onTimeout") - peer.didTimeout = true -} - -func (peer *bpPeer) isBad() bool { - return peer.didTimeout -} - -//------------------------------------- - -type bpRequester struct { - QuitService - pool *BlockPool - height int - gotBlockCh chan struct{} - redoCh chan struct{} - - mtx sync.Mutex - peerID string - block *types.Block -} - -func newBPRequester(pool *BlockPool, height int) *bpRequester { - bpr := &bpRequester{ - pool: pool, - height: height, - gotBlockCh: make(chan struct{}), - redoCh: make(chan struct{}), - - peerID: "", - block: nil, - } - bpr.QuitService = *NewQuitService(nil, "bpRequester", bpr) - return bpr -} - -func (bpr *bpRequester) OnStart() error { - bpr.QuitService.OnStart() - go bpr.requestRoutine() - return nil -} - -// Returns true if the peer matches -func (bpr *bpRequester) setBlock(block *types.Block, peerID string) bool { - bpr.mtx.Lock() - if bpr.block != nil || bpr.peerID != peerID { - bpr.mtx.Unlock() - return false - } - bpr.block = block - bpr.mtx.Unlock() - - bpr.gotBlockCh <- struct{}{} - return true -} - -func (bpr *bpRequester) getBlock() *types.Block { - bpr.mtx.Lock() - defer bpr.mtx.Unlock() - return bpr.block -} - -func (bpr *bpRequester) getPeerID() string { - bpr.mtx.Lock() - defer bpr.mtx.Unlock() - return bpr.peerID -} - -func (bpr *bpRequester) reset() { - bpr.mtx.Lock() - bpr.peerID = "" - bpr.block = nil - bpr.mtx.Unlock() -} - -// Tells bpRequester to pick another peer and try again. -// NOTE: blocking -func (bpr *bpRequester) redo() { - bpr.redoCh <- struct{}{} -} - -// Responsible for making more requests as necessary -// Returns only when a block is found (e.g. AddBlock() is called) -func (bpr *bpRequester) requestRoutine() { -OUTER_LOOP: - for { - // Pick a peer to send request to. - var peer *bpPeer = nil - PICK_PEER_LOOP: - for { - if !bpr.IsRunning() || !bpr.pool.IsRunning() { - return - } - peer = bpr.pool.pickIncrAvailablePeer(bpr.height) - if peer == nil { - //log.Info("No peers available", "height", height) - time.Sleep(requestIntervalMS * time.Millisecond) - continue PICK_PEER_LOOP - } - break PICK_PEER_LOOP - } - bpr.mtx.Lock() - bpr.peerID = peer.id - bpr.mtx.Unlock() - - // Send request and wait. - bpr.pool.sendRequest(bpr.height, peer.id) - select { - case <-bpr.pool.Quit: - bpr.Stop() - return - case <-bpr.Quit: - return - case <-bpr.redoCh: - bpr.reset() - continue OUTER_LOOP // When peer is removed - case <-bpr.gotBlockCh: - // We got the block, now see if it's good. - select { - case <-bpr.pool.Quit: - bpr.Stop() - return - case <-bpr.Quit: - return - case <-bpr.redoCh: - bpr.reset() - continue OUTER_LOOP - } - } - } -} - -//------------------------------------- - -type BlockRequest struct { - Height int - PeerID string -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool_test.go deleted file mode 100644 index 4d6a34517ac88ab587e833ccd4182a7159855c06..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/pool_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package blockchain - -import ( - "math/rand" - "testing" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -type testPeer struct { - id string - height int -} - -func makePeers(numPeers int, minHeight, maxHeight int) map[string]testPeer { - peers := make(map[string]testPeer, numPeers) - for i := 0; i < numPeers; i++ { - peerID := RandStr(12) - height := minHeight + rand.Intn(maxHeight-minHeight) - peers[peerID] = testPeer{peerID, height} - } - return peers -} - -func TestBasic(t *testing.T) { - start := 42 - peers := makePeers(10, start+1, 1000) - timeoutsCh := make(chan string, 100) - requestsCh := make(chan BlockRequest, 100) - pool := NewBlockPool(start, requestsCh, timeoutsCh) - pool.Start() - - // Introduce each peer. - go func() { - for _, peer := range peers { - pool.SetPeerHeight(peer.id, peer.height) - } - }() - - // Start a goroutine to pull blocks - go func() { - for { - if !pool.IsRunning() { - return - } - first, second := pool.PeekTwoBlocks() - if first != nil && second != nil { - pool.PopRequest() - } else { - time.Sleep(1 * time.Second) - } - } - }() - - // Pull from channels - for { - select { - case peerID := <-timeoutsCh: - t.Errorf("timeout: %v", peerID) - case request := <-requestsCh: - log.Info("TEST: Pulled new BlockRequest", "request", request) - if request.Height == 300 { - return // Done! - } - // Request desired, pretend like we got the block immediately. - go func() { - block := &types.Block{Header: &types.Header{Height: request.Height}} - pool.AddBlock(request.PeerID, block, 123) - log.Info("TEST: Added block", "block", request.Height, "peer", request.PeerID) - }() - } - } - - pool.Stop() -} - -func TestTimeout(t *testing.T) { - start := 42 - peers := makePeers(10, start+1, 1000) - timeoutsCh := make(chan string, 100) - requestsCh := make(chan BlockRequest, 100) - pool := NewBlockPool(start, requestsCh, timeoutsCh) - pool.Start() - - for _, peer := range peers { - log.Info("Peer", "id", peer.id) - } - - // Introduce each peer. - go func() { - for _, peer := range peers { - pool.SetPeerHeight(peer.id, peer.height) - } - }() - - // Start a goroutine to pull blocks - go func() { - for { - if !pool.IsRunning() { - return - } - first, second := pool.PeekTwoBlocks() - if first != nil && second != nil { - pool.PopRequest() - } else { - time.Sleep(1 * time.Second) - } - } - }() - - // Pull from channels - counter := 0 - timedOut := map[string]struct{}{} - for { - select { - case peerID := <-timeoutsCh: - log.Info("Timeout", "peerID", peerID) - if _, ok := timedOut[peerID]; !ok { - counter++ - if counter == len(peers) { - return // Done! - } - } - case request := <-requestsCh: - log.Info("TEST: Pulled new BlockRequest", "request", request) - } - } - - pool.Stop() -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go deleted file mode 100644 index 0ca0e2f714c37a6e98b2f3e49d71da27e66211d5..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/reactor.go +++ /dev/null @@ -1,339 +0,0 @@ -package blockchain - -import ( - "bytes" - "errors" - "fmt" - "reflect" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - BlockchainChannel = byte(0x40) - defaultChannelCapacity = 100 - defaultSleepIntervalMS = 500 - trySyncIntervalMS = 100 - // stop syncing when last block's time is - // within this much of the system time. - // stopSyncingDurationMinutes = 10 - - // ask for best height every 10s - statusUpdateIntervalSeconds = 10 - // check if we should switch to consensus reactor - switchToConsensusIntervalSeconds = 1 - maxBlockchainResponseSize = types.MaxBlockSize + 2 -) - -type consensusReactor interface { - // for when we switch from blockchain reactor and fast sync to - // the consensus machine - SwitchToConsensus(*sm.State) -} - -// BlockchainReactor handles long-term catchup syncing. -type BlockchainReactor struct { - p2p.BaseReactor - - sw *p2p.Switch - state *sm.State - proxyAppCtx proxy.AppContext // same as consensus.proxyAppCtx - store *BlockStore - pool *BlockPool - sync bool - requestsCh chan BlockRequest - timeoutsCh chan string - lastBlock *types.Block - - evsw events.Fireable -} - -func NewBlockchainReactor(state *sm.State, proxyAppCtx proxy.AppContext, store *BlockStore, sync bool) *BlockchainReactor { - if state.LastBlockHeight != store.Height() && - state.LastBlockHeight != store.Height()-1 { // XXX double check this logic. - PanicSanity(Fmt("state (%v) and store (%v) height mismatch", state.LastBlockHeight, store.Height())) - } - requestsCh := make(chan BlockRequest, defaultChannelCapacity) - timeoutsCh := make(chan string, defaultChannelCapacity) - pool := NewBlockPool( - store.Height()+1, - requestsCh, - timeoutsCh, - ) - bcR := &BlockchainReactor{ - state: state, - proxyAppCtx: proxyAppCtx, - store: store, - pool: pool, - sync: sync, - requestsCh: requestsCh, - timeoutsCh: timeoutsCh, - } - bcR.BaseReactor = *p2p.NewBaseReactor(log, "BlockchainReactor", bcR) - return bcR -} - -func (bcR *BlockchainReactor) OnStart() error { - bcR.BaseReactor.OnStart() - if bcR.sync { - _, err := bcR.pool.Start() - if err != nil { - return err - } - go bcR.poolRoutine() - } - return nil -} - -func (bcR *BlockchainReactor) OnStop() { - bcR.BaseReactor.OnStop() - bcR.pool.Stop() -} - -// Implements Reactor -func (bcR *BlockchainReactor) GetChannels() []*p2p.ChannelDescriptor { - return []*p2p.ChannelDescriptor{ - &p2p.ChannelDescriptor{ - ID: BlockchainChannel, - Priority: 5, - SendQueueCapacity: 100, - }, - } -} - -// Implements Reactor -func (bcR *BlockchainReactor) AddPeer(peer *p2p.Peer) { - // Send peer our state. - peer.Send(BlockchainChannel, &bcStatusResponseMessage{bcR.store.Height()}) -} - -// Implements Reactor -func (bcR *BlockchainReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { - // Remove peer from the pool. - bcR.pool.RemovePeer(peer.Key) -} - -// Implements Reactor -func (bcR *BlockchainReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { - _, msg, err := DecodeMessage(msgBytes) - if err != nil { - log.Warn("Error decoding message", "error", err) - return - } - - log.Notice("Received message", "src", src, "chID", chID, "msg", msg) - - switch msg := msg.(type) { - case *bcBlockRequestMessage: - // Got a request for a block. Respond with block if we have it. - block := bcR.store.LoadBlock(msg.Height) - if block != nil { - msg := &bcBlockResponseMessage{Block: block} - queued := src.TrySend(BlockchainChannel, msg) - if !queued { - // queue is full, just ignore. - } - } else { - // TODO peer is asking for things we don't have. - } - case *bcBlockResponseMessage: - // Got a block. - bcR.pool.AddBlock(src.Key, msg.Block, len(msgBytes)) - case *bcStatusRequestMessage: - // Send peer our state. - queued := src.TrySend(BlockchainChannel, &bcStatusResponseMessage{bcR.store.Height()}) - if !queued { - // sorry - } - case *bcStatusResponseMessage: - // Got a peer status. Unverified. - bcR.pool.SetPeerHeight(src.Key, msg.Height) - default: - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } -} - -// Handle messages from the poolReactor telling the reactor what to do. -// NOTE: Don't sleep in the FOR_LOOP or otherwise slow it down! -// (Except for the SYNC_LOOP, which is the primary purpose and must be synchronous.) -func (bcR *BlockchainReactor) poolRoutine() { - - trySyncTicker := time.NewTicker(trySyncIntervalMS * time.Millisecond) - statusUpdateTicker := time.NewTicker(statusUpdateIntervalSeconds * time.Second) - switchToConsensusTicker := time.NewTicker(switchToConsensusIntervalSeconds * time.Second) - -FOR_LOOP: - for { - select { - case request := <-bcR.requestsCh: // chan BlockRequest - peer := bcR.Switch.Peers().Get(request.PeerID) - if peer == nil { - continue FOR_LOOP // Peer has since been disconnected. - } - msg := &bcBlockRequestMessage{request.Height} - queued := peer.TrySend(BlockchainChannel, msg) - if !queued { - // We couldn't make the request, send-queue full. - // The pool handles timeouts, just let it go. - continue FOR_LOOP - } - case peerID := <-bcR.timeoutsCh: // chan string - // Peer timed out. - peer := bcR.Switch.Peers().Get(peerID) - if peer != nil { - bcR.Switch.StopPeerForError(peer, errors.New("BlockchainReactor Timeout")) - } - case _ = <-statusUpdateTicker.C: - // ask for status updates - go bcR.BroadcastStatusRequest() - case _ = <-switchToConsensusTicker.C: - height, numPending := bcR.pool.GetStatus() - outbound, inbound, _ := bcR.Switch.NumPeers() - log.Info("Consensus ticker", "numPending", numPending, "total", len(bcR.pool.requesters), - "outbound", outbound, "inbound", inbound) - if bcR.pool.IsCaughtUp() { - log.Notice("Time to switch to consensus reactor!", "height", height) - bcR.pool.Stop() - - conR := bcR.Switch.Reactor("CONSENSUS").(consensusReactor) - conR.SwitchToConsensus(bcR.state) - - break FOR_LOOP - } - case _ = <-trySyncTicker.C: // chan time - // This loop can be slow as long as it's doing syncing work. - SYNC_LOOP: - for i := 0; i < 10; i++ { - // See if there are any blocks to sync. - first, second := bcR.pool.PeekTwoBlocks() - //log.Info("TrySync peeked", "first", first, "second", second) - if first == nil || second == nil { - // We need both to sync the first block. - break SYNC_LOOP - } - firstParts := first.MakePartSet() - firstPartsHeader := firstParts.Header() - // Finally, verify the first block using the second's validation. - err := bcR.state.Validators.VerifyValidation( - bcR.state.ChainID, first.Hash(), firstPartsHeader, first.Height, second.LastValidation) - if err != nil { - log.Info("error in validation", "error", err) - bcR.pool.RedoRequest(first.Height) - break SYNC_LOOP - } else { - bcR.pool.PopRequest() - err := bcR.state.ExecBlock(bcR.proxyAppCtx, first, firstPartsHeader) - if err != nil { - // TODO This is bad, are we zombie? - PanicQ(Fmt("Failed to process committed block: %v", err)) - } - err = bcR.state.Commit(bcR.proxyAppCtx) - if err != nil { - // TODO Handle gracefully. - PanicQ(Fmt("Failed to commit block at application: %v", err)) - } - bcR.store.SaveBlock(first, firstParts, second.LastValidation) - bcR.state.Save() - } - } - continue FOR_LOOP - case <-bcR.Quit: - break FOR_LOOP - } - } -} - -func (bcR *BlockchainReactor) BroadcastStatusResponse() error { - bcR.Switch.Broadcast(BlockchainChannel, &bcStatusResponseMessage{bcR.store.Height()}) - return nil -} - -func (bcR *BlockchainReactor) BroadcastStatusRequest() error { - bcR.Switch.Broadcast(BlockchainChannel, &bcStatusRequestMessage{bcR.store.Height()}) - return nil -} - -// implements events.Eventable -func (bcR *BlockchainReactor) SetFireable(evsw events.Fireable) { - bcR.evsw = evsw -} - -//----------------------------------------------------------------------------- -// Messages - -const ( - msgTypeBlockRequest = byte(0x10) - msgTypeBlockResponse = byte(0x11) - msgTypeStatusResponse = byte(0x20) - msgTypeStatusRequest = byte(0x21) -) - -type BlockchainMessage interface{} - -var _ = wire.RegisterInterface( - struct{ BlockchainMessage }{}, - wire.ConcreteType{&bcBlockRequestMessage{}, msgTypeBlockRequest}, - wire.ConcreteType{&bcBlockResponseMessage{}, msgTypeBlockResponse}, - wire.ConcreteType{&bcStatusResponseMessage{}, msgTypeStatusResponse}, - wire.ConcreteType{&bcStatusRequestMessage{}, msgTypeStatusRequest}, -) - -// TODO: ensure that bz is completely read. -func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) { - msgType = bz[0] - n := int(0) - r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, maxBlockchainResponseSize, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage - if err != nil && n != len(bz) { - err = errors.New("DecodeMessage() had bytes left over.") - } - return -} - -//------------------------------------- - -type bcBlockRequestMessage struct { - Height int -} - -func (m *bcBlockRequestMessage) String() string { - return fmt.Sprintf("[bcBlockRequestMessage %v]", m.Height) -} - -//------------------------------------- - -// NOTE: keep up-to-date with maxBlockchainResponseSize -type bcBlockResponseMessage struct { - Block *types.Block -} - -func (m *bcBlockResponseMessage) String() string { - return fmt.Sprintf("[bcBlockResponseMessage %v]", m.Block.Height) -} - -//------------------------------------- - -type bcStatusRequestMessage struct { - Height int -} - -func (m *bcStatusRequestMessage) String() string { - return fmt.Sprintf("[bcStatusRequestMessage %v]", m.Height) -} - -//------------------------------------- - -type bcStatusResponseMessage struct { - Height int -} - -func (m *bcStatusResponseMessage) String() string { - return fmt.Sprintf("[bcStatusResponseMessage %v]", m.Height) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go deleted file mode 100644 index de9a65714b7826481ccc04f2ab949857bd17336d..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain/store.go +++ /dev/null @@ -1,231 +0,0 @@ -package blockchain - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -/* -Simple low level store for blocks. - -There are three types of information stored: - - BlockMeta: Meta information about each block - - Block part: Parts of each block, aggregated w/ PartSet - - Validation: The Validation part of each block, for gossiping precommit votes - -Currently the precommit signatures are duplicated in the Block parts as -well as the Validation. In the future this may change, perhaps by moving -the Validation data outside the Block. - -Panics indicate probable corruption in the data -*/ -type BlockStore struct { - height int - db dbm.DB -} - -func NewBlockStore(db dbm.DB) *BlockStore { - bsjson := LoadBlockStoreStateJSON(db) - return &BlockStore{ - height: bsjson.Height, - db: db, - } -} - -// Height() returns the last known contiguous block height. -func (bs *BlockStore) Height() int { - return bs.height -} - -func (bs *BlockStore) GetReader(key []byte) io.Reader { - bytez := bs.db.Get(key) - if bytez == nil { - return nil - } - return bytes.NewReader(bytez) -} - -func (bs *BlockStore) LoadBlock(height int) *types.Block { - var n int - var err error - r := bs.GetReader(calcBlockMetaKey(height)) - if r == nil { - return nil - } - meta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta) - if err != nil { - PanicCrisis(Fmt("Error reading block meta: %v", err)) - } - bytez := []byte{} - for i := 0; i < meta.PartsHeader.Total; i++ { - part := bs.LoadBlockPart(height, i) - bytez = append(bytez, part.Bytes...) - } - block := wire.ReadBinary(&types.Block{}, bytes.NewReader(bytez), 0, &n, &err).(*types.Block) - if err != nil { - PanicCrisis(Fmt("Error reading block: %v", err)) - } - return block -} - -func (bs *BlockStore) LoadBlockPart(height int, index int) *types.Part { - var n int - var err error - r := bs.GetReader(calcBlockPartKey(height, index)) - if r == nil { - return nil - } - part := wire.ReadBinary(&types.Part{}, r, 0, &n, &err).(*types.Part) - if err != nil { - PanicCrisis(Fmt("Error reading block part: %v", err)) - } - return part -} - -func (bs *BlockStore) LoadBlockMeta(height int) *types.BlockMeta { - var n int - var err error - r := bs.GetReader(calcBlockMetaKey(height)) - if r == nil { - return nil - } - meta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta) - if err != nil { - PanicCrisis(Fmt("Error reading block meta: %v", err)) - } - return meta -} - -// The +2/3 and other Precommit-votes for block at `height`. -// This Validation comes from block.LastValidation for `height+1`. -func (bs *BlockStore) LoadBlockValidation(height int) *types.Validation { - var n int - var err error - r := bs.GetReader(calcBlockValidationKey(height)) - if r == nil { - return nil - } - validation := wire.ReadBinary(&types.Validation{}, r, 0, &n, &err).(*types.Validation) - if err != nil { - PanicCrisis(Fmt("Error reading validation: %v", err)) - } - return validation -} - -// NOTE: the Precommit-vote heights are for the block at `height` -func (bs *BlockStore) LoadSeenValidation(height int) *types.Validation { - var n int - var err error - r := bs.GetReader(calcSeenValidationKey(height)) - if r == nil { - return nil - } - validation := wire.ReadBinary(&types.Validation{}, r, 0, &n, &err).(*types.Validation) - if err != nil { - PanicCrisis(Fmt("Error reading validation: %v", err)) - } - return validation -} - -// blockParts: Must be parts of the block -// seenValidation: The +2/3 precommits that were seen which committed at height. -// If all the nodes restart after committing a block, -// we need this to reload the precommits to catch-up nodes to the -// most recent height. Otherwise they'd stall at H-1. -func (bs *BlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenValidation *types.Validation) { - height := block.Height - if height != bs.height+1 { - PanicSanity(Fmt("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.height+1, height)) - } - if !blockParts.IsComplete() { - PanicSanity(Fmt("BlockStore can only save complete block part sets")) - } - - // Save block meta - meta := types.NewBlockMeta(block, blockParts) - metaBytes := wire.BinaryBytes(meta) - bs.db.Set(calcBlockMetaKey(height), metaBytes) - - // Save block parts - for i := 0; i < blockParts.Total(); i++ { - bs.saveBlockPart(height, i, blockParts.GetPart(i)) - } - - // Save block validation (duplicate and separate from the Block) - blockValidationBytes := wire.BinaryBytes(block.LastValidation) - bs.db.Set(calcBlockValidationKey(height-1), blockValidationBytes) - - // Save seen validation (seen +2/3 precommits for block) - seenValidationBytes := wire.BinaryBytes(seenValidation) - bs.db.Set(calcSeenValidationKey(height), seenValidationBytes) - - // Save new BlockStoreStateJSON descriptor - BlockStoreStateJSON{Height: height}.Save(bs.db) - - // Done! - bs.height = height -} - -func (bs *BlockStore) saveBlockPart(height int, index int, part *types.Part) { - if height != bs.height+1 { - PanicSanity(Fmt("BlockStore can only save contiguous blocks. Wanted %v, got %v", bs.height+1, height)) - } - partBytes := wire.BinaryBytes(part) - bs.db.Set(calcBlockPartKey(height, index), partBytes) -} - -//----------------------------------------------------------------------------- - -func calcBlockMetaKey(height int) []byte { - return []byte(fmt.Sprintf("H:%v", height)) -} - -func calcBlockPartKey(height int, partIndex int) []byte { - return []byte(fmt.Sprintf("P:%v:%v", height, partIndex)) -} - -func calcBlockValidationKey(height int) []byte { - return []byte(fmt.Sprintf("V:%v", height)) -} - -func calcSeenValidationKey(height int) []byte { - return []byte(fmt.Sprintf("SV:%v", height)) -} - -//----------------------------------------------------------------------------- - -var blockStoreKey = []byte("blockStore") - -type BlockStoreStateJSON struct { - Height int -} - -func (bsj BlockStoreStateJSON) Save(db dbm.DB) { - bytes, err := json.Marshal(bsj) - if err != nil { - PanicSanity(Fmt("Could not marshal state bytes: %v", err)) - } - db.Set(blockStoreKey, bytes) -} - -func LoadBlockStoreStateJSON(db dbm.DB) BlockStoreStateJSON { - bytes := db.Get(blockStoreKey) - if bytes == nil { - return BlockStoreStateJSON{ - Height: 0, - } - } - bsj := BlockStoreStateJSON{} - err := json.Unmarshal(bytes, &bsj) - if err != nil { - PanicCrisis(Fmt("Could not unmarshal bytes: %X", bytes)) - } - return bsj -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/config.go deleted file mode 100644 index 288cf25062591708dac56effdbfe04aa0a10241c..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/config.go +++ /dev/null @@ -1,89 +0,0 @@ -package tendermint - -import ( - "os" - "path" - "strings" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -func getTMRoot(rootDir string) string { - if rootDir == "" { - rootDir = os.Getenv("TMROOT") - } - if rootDir == "" { - rootDir = os.Getenv("HOME") + "/.tendermint" - } - return rootDir -} - -func initTMRoot(rootDir string) { - rootDir = getTMRoot(rootDir) - EnsureDir(rootDir, 0700) - - configFilePath := path.Join(rootDir, "config.toml") - - // Write default config file if missing. - if !FileExists(configFilePath) { - // Ask user for moniker - // moniker := cfg.Prompt("Type hostname: ", "anonymous") - MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644) - } -} - -func GetConfig(rootDir string) cfg.Config { - rootDir = getTMRoot(rootDir) - initTMRoot(rootDir) - - configFilePath := path.Join(rootDir, "config.toml") - mapConfig, err := cfg.ReadMapConfigFromFile(configFilePath) - if err != nil { - Exit(Fmt("Could not read config: %v", err)) - } - - // Set defaults or panic - if mapConfig.IsSet("chain_id") { - Exit("Cannot set 'chain_id' via config.toml") - } - if mapConfig.IsSet("revision_file") { - Exit("Cannot set 'revision_file' via config.toml. It must match what's in the Makefile") - } - mapConfig.SetRequired("chain_id") // blows up if you try to use it before setting. - mapConfig.SetDefault("genesis_file", rootDir+"/genesis.json") - mapConfig.SetDefault("proxy_app", "tcp://127.0.0.1:46658") - mapConfig.SetDefault("moniker", "anonymous") - mapConfig.SetDefault("node_laddr", "0.0.0.0:46656") - // mapConfig.SetDefault("seeds", "goldenalchemist.chaintest.net:46656") - mapConfig.SetDefault("fast_sync", true) - mapConfig.SetDefault("skip_upnp", false) - mapConfig.SetDefault("addrbook_file", rootDir+"/addrbook.json") - mapConfig.SetDefault("priv_validator_file", rootDir+"/priv_validator.json") - mapConfig.SetDefault("db_backend", "leveldb") - mapConfig.SetDefault("db_dir", rootDir+"/data") - mapConfig.SetDefault("vm_log", true) - mapConfig.SetDefault("log_level", "info") - mapConfig.SetDefault("rpc_laddr", "0.0.0.0:46657") - mapConfig.SetDefault("prof_laddr", "") - mapConfig.SetDefault("revision_file", rootDir+"/revision") - return mapConfig -} - -var defaultConfigTmpl = `# This is a TOML config file. -# For more information, see https://github.com/toml-lang/toml - -proxy_app = "tcp://127.0.0.1:46658" -moniker = "__MONIKER__" -node_laddr = "0.0.0.0:46656" -seeds = "" -fast_sync = true -db_backend = "leveldb" -log_level = "notice" -rpc_laddr = "0.0.0.0:46657" -` - -func defaultConfig(moniker string) (defaultConfig string) { - defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1) - return -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json deleted file mode 100644 index eca00696edb4414df42fe6770cc23cde5a758529..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/genesis.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "chain_id": "tendermint_testnet_11.c", - "accounts": [ - { - "address": "9FCBA7F840A0BFEBBE755E853C9947270A912D04", - "amount": 1991999998000000 - }, - { - "address": "964B1493BBE3312278B7DEB94C39149F7899A345", - "amount": 100000000000000 - }, - { - "address": "B9FA4AB462B9C6BF6A62DB4AE77C9E7087209A04", - "amount": 1000000000000 - }, - { - "address": "F171824590D69386F709E7B6704B369C5A370D60", - "amount": 1000000000000 - }, - { - "address": "56EFE746A13D9A6054AC89C3E2A361C2DB8B9EAE", - "amount": 1000000000000 - }, - { - "address": "7C2E032D8407EDF66A04D88CF0E1D9B15D98AE2D", - "amount": 1000000000000 - }, - { - "address": "636EF5823E082AD66EBC203FD4DFB1031F0C61CA", - "amount": 1000000000000 - }, - { - "address": "9008419E6351360A59B124E707E4CA2A5BFB9BE6", - "amount": 1000000000000 - }, - { - "address": "C78F48919B8A4030AD3E5ED643F8D2302E41953D", - "amount": 1000000000000 - }, - { - "address": "5290AC90CE2422DDC3F91F6A246F7E3C542EA51A", - "amount": 1000000000000 - }, - { - "address": "A88A61069B6660F30F65E8786AFDD4F1D8F625E9", - "amount": 1000000 - }, - { - "address": "EE2EE9247973B4AFC3867CFE5F415410AC251B61", - "amount": 1000000 - } - ], - "validators": [ - { - "pub_key": [1, "178EC6008A4364508979C70CBF100BD4BCBAA12DDE6251F5F486B4FD09014F06"], - "amount": 100000000000 - }, - { - "pub_key": [1, "2A77777CC51467DE42350D4A8F34720D527734189BE64C7A930DD169E1FED3C6"], - "amount": 100000000000 - }, - { - "pub_key": [1, "3718E69D09B11B3AD3FA31AEF07EC416D2AEED241CACE7B0F30AE9803FFB0F08"], - "amount": 100000000000 - }, - { - "pub_key": [1, "C6B0440DEACD1E4CF1C736CEB8E38E788B700BA2B2045A55CB657A455CF5F889"], - "amount": 100000000000 - }, - { - "pub_key": [1, "3BA1190D54F91EFBF8B0125F7EC116AD4BA2894B6EE38564A5D5FD3230D91F7B"], - "amount": 100000000000 - } - ] -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/logrotate.config b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/logrotate.config deleted file mode 100644 index 73eaf74e74b50cb744de5dfba2dfa3835f0f5c45..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint/logrotate.config +++ /dev/null @@ -1,22 +0,0 @@ -// If you wanted to use logrotate, I suppose this might be the config you want. -// Instead, I'll just write our own, that way we don't need sudo to install. - -$HOME/.tendermint/logs/tendermint.log { - missingok - notifempty - rotate 12 - daily - size 10M - compress - delaycompress -} - -$HOME/.barak/logs/barak.log { - missingok - notifempty - rotate 12 - weekly - size 10M - compress - delaycompress -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test/config.go deleted file mode 100644 index 01a54da1eda68b49351e554a0f948999f7e2b58f..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test/config.go +++ /dev/null @@ -1,142 +0,0 @@ -// Import this in all *_test.go files to initialize ~/.tendermint_test. - -package tendermint_test - -import ( - "os" - "path" - "strings" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -func init() { - // Creates ~/.tendermint_test/* - config := GetConfig("") - cfg.ApplyConfig(config) -} - -func getTMRoot(rootDir string) string { - if rootDir == "" { - rootDir = os.Getenv("HOME") + "/.tendermint_test" - } - return rootDir -} - -func initTMRoot(rootDir string) { - rootDir = getTMRoot(rootDir) - EnsureDir(rootDir, 0700) - - configFilePath := path.Join(rootDir, "config.toml") - genesisFilePath := path.Join(rootDir, "genesis.json") - - // Write default config file if missing. - if !FileExists(configFilePath) { - // Ask user for moniker - // moniker := cfg.Prompt("Type hostname: ", "anonymous") - MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644) - } - if !FileExists(genesisFilePath) { - MustWriteFile(genesisFilePath, []byte(defaultGenesis), 0644) - } -} - -func GetConfig(rootDir string) cfg.Config { - rootDir = getTMRoot(rootDir) - initTMRoot(rootDir) - - configFilePath := path.Join(rootDir, "config.toml") - mapConfig, err := cfg.ReadMapConfigFromFile(configFilePath) - if err != nil { - Exit(Fmt("Could not read config: %v", err)) - } - - // Set defaults or panic - if mapConfig.IsSet("chain_id") { - Exit("Cannot set 'chain_id' via config.toml") - } - mapConfig.SetDefault("chain_id", "tendermint_test") - mapConfig.SetDefault("genesis_file", rootDir+"/genesis.json") - mapConfig.SetDefault("proxy_app", "tcp://127.0.0.1:36658") - mapConfig.SetDefault("moniker", "anonymous") - mapConfig.SetDefault("node_laddr", "0.0.0.0:36656") - mapConfig.SetDefault("fast_sync", false) - mapConfig.SetDefault("skip_upnp", true) - mapConfig.SetDefault("addrbook_file", rootDir+"/addrbook.json") - mapConfig.SetDefault("priv_validator_file", rootDir+"/priv_validator.json") - mapConfig.SetDefault("db_backend", "memdb") - mapConfig.SetDefault("db_dir", rootDir+"/data") - mapConfig.SetDefault("log_level", "debug") - mapConfig.SetDefault("vm_log", true) - mapConfig.SetDefault("rpc_laddr", "0.0.0.0:36657") - mapConfig.SetDefault("prof_laddr", "") - mapConfig.SetDefault("revision_file", rootDir+"/revision") - return mapConfig -} - -var defaultConfigTmpl = `# This is a TOML config file. -# For more information, see https://github.com/toml-lang/toml - -proxy_app = "tcp://127.0.0.1:36658" -moniker = "__MONIKER__" -node_laddr = "0.0.0.0:36656" -seeds = "" -fast_sync = false -db_backend = "memdb" -log_level = "debug" -rpc_laddr = "0.0.0.0:36657" -` - -func defaultConfig(moniker string) (defaultConfig string) { - defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1) - return -} - -// priv keys generated deterministically eg rpc/tests/helpers.go -var defaultGenesis = `{ - "chain_id" : "tendermint_test", - "accounts": [ - { - "address": "E9B5D87313356465FAE33C406CE2C2979DE60BCB", - "amount": 200000000 - }, - { - "address": "DFE4AFFA4CEE17CD01CB9E061D77C3ECED29BD88", - "amount": 200000000 - }, - { - "address": "F60D30722E7B497FA532FB3207C3FB29C31B1992", - "amount": 200000000 - }, - { - "address": "336CB40A5EB92E496E19B74FDFF2BA017C877FD6", - "amount": 200000000 - }, - { - "address": "D218F0F439BF0384F6F5EF8D0F8B398D941BD1DC", - "amount": 200000000 - } - ], - "validators": [ - { - "pub_key": [1, "583779C3BFA3F6C7E23C7D830A9C3D023A216B55079AD38BFED1207B94A19548"], - "amount": 1000000, - "unbond_to": [ - { - "address": "E9B5D87313356465FAE33C406CE2C2979DE60BCB", - "amount": 100000 - } - ] - } - ] -}` - -var defaultPrivValidator = `{ - "address": "1D7A91CB32F758A02EBB9BE1FB6F8DEE56F90D42", - "pub_key": [1,"06FBAC4E285285D1D91FCBC7E91C780ADA11516F67462340B3980CE2B94940E8"], - "priv_key": [1,"C453604BD6480D5538B4C6FD2E3E314B5BCE518D75ADE4DA3DA85AB8ADFD819606FBAC4E285285D1D91FCBC7E91C780ADA11516F67462340B3980CE2B94940E8"], - "last_height":0, - "last_round":0, - "last_step":0 -}` diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/README.md b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/README.md deleted file mode 100644 index 46d33032f88df18aead5b4891c94b3ce102fb264..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/README.md +++ /dev/null @@ -1,4 +0,0 @@ -The core consensus algorithm. - -* state.go - The state machine as detailed in the whitepaper -* reactor.go - A reactor that connects the state machine to the gossip network diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/common_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/common_test.go deleted file mode 100644 index f5860375583148d44d1042f15030d6fee1d9d50e..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/common_test.go +++ /dev/null @@ -1,335 +0,0 @@ -package consensus - -import ( - "bytes" - "fmt" - "sort" - "testing" - "time" - - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - mempl "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" - - "github.com/tendermint/tmsp/example" -) - -var chainID string - -func init() { - chainID = config.GetString("chain_id") -} - -type validatorStub struct { - Height int - Round int - *types.PrivValidator -} - -func NewValidatorStub(privValidator *types.PrivValidator) *validatorStub { - return &validatorStub{ - PrivValidator: privValidator, - } -} - -func (vs *validatorStub) signVote(voteType byte, hash []byte, header types.PartSetHeader) (*types.Vote, error) { - vote := &types.Vote{ - Height: vs.Height, - Round: vs.Round, - Type: voteType, - BlockHash: hash, - BlockPartsHeader: header, - } - err := vs.PrivValidator.SignVote(chainID, vote) - return vote, err -} - -// convenienve function for testing -func signVote(vs *validatorStub, voteType byte, hash []byte, header types.PartSetHeader) *types.Vote { - v, err := vs.signVote(voteType, hash, header) - if err != nil { - panic(fmt.Errorf("failed to sign vote: %v", err)) - } - return v -} - -// create proposal block from cs1 but sign it with vs -func decideProposal(cs1 *ConsensusState, cs2 *validatorStub, height, round int) (proposal *types.Proposal, block *types.Block) { - block, blockParts := cs1.createProposalBlock() - if block == nil { // on error - panic("error creating proposal block") - } - - // Make proposal - proposal = types.NewProposal(height, round, blockParts.Header(), cs1.Votes.POLRound()) - if err := cs2.SignProposal(chainID, proposal); err != nil { - panic(err) - } - return -} - -//------------------------------------------------------------------------------- -// utils - -func nilRound(t *testing.T, startRound int, cs1 *ConsensusState, vss ...*validatorStub) { - height, round := cs1.Height, cs1.Round - - waitFor(t, cs1, height, round, RoundStepPrevote) - - signAddVoteToFromMany(types.VoteTypePrevote, cs1, nil, cs1.ProposalBlockParts.Header(), vss...) - - waitFor(t, cs1, height, round, RoundStepPrecommit) - - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, cs1.ProposalBlockParts.Header(), vss...) - - waitFor(t, cs1, height, round+1, RoundStepNewRound) -} - -// NOTE: this switches the propser as far as `perspectiveOf` is concerned, -// but for simplicity we return a block it generated. -func changeProposer(t *testing.T, perspectiveOf *ConsensusState, newProposer *validatorStub) *types.Block { - _, v1 := perspectiveOf.Validators.GetByAddress(perspectiveOf.privValidator.Address) - v1.Accum, v1.VotingPower = 0, 0 - if updated := perspectiveOf.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - _, v2 := perspectiveOf.Validators.GetByAddress(newProposer.Address) - v2.Accum, v2.VotingPower = 100, 100 - if updated := perspectiveOf.Validators.Update(v2); !updated { - t.Fatal("failed to update validator") - } - - // make the proposal - propBlock, _ := perspectiveOf.createProposalBlock() - if propBlock == nil { - t.Fatal("Failed to create proposal block with cs2") - } - return propBlock -} - -func fixVotingPower(t *testing.T, cs1 *ConsensusState, addr2 []byte) { - _, v1 := cs1.Validators.GetByAddress(cs1.privValidator.Address) - _, v2 := cs1.Validators.GetByAddress(addr2) - v1.Accum, v1.VotingPower = v2.Accum, v2.VotingPower - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } -} - -func addVoteToFromMany(to *ConsensusState, votes []*types.Vote, froms ...*validatorStub) { - if len(votes) != len(froms) { - panic("len(votes) and len(froms) must match") - } - for i, from := range froms { - addVoteToFrom(to, from, votes[i]) - } -} - -func addVoteToFrom(to *ConsensusState, from *validatorStub, vote *types.Vote) { - valIndex, _ := to.Validators.GetByAddress(from.PrivValidator.Address) - added, err := to.TryAddVote(valIndex, vote, "") - if _, ok := err.(*types.ErrVoteConflictingSignature); ok { - // let it fly - } else if !added { - fmt.Println("to, from, vote:", to.Height, from.Height, vote.Height) - panic(fmt.Sprintln("Failed to add vote. Err:", err)) - } else if err != nil { - panic(fmt.Sprintln("Failed to add vote:", err)) - } -} - -func signVoteMany(voteType byte, hash []byte, header types.PartSetHeader, vss ...*validatorStub) []*types.Vote { - votes := make([]*types.Vote, len(vss)) - for i, vs := range vss { - votes[i] = signVote(vs, voteType, hash, header) - } - return votes -} - -// add vote to one cs from another -func signAddVoteToFromMany(voteType byte, to *ConsensusState, hash []byte, header types.PartSetHeader, froms ...*validatorStub) { - for _, from := range froms { - vote := signVote(from, voteType, hash, header) - addVoteToFrom(to, from, vote) - } -} - -func signAddVoteToFrom(voteType byte, to *ConsensusState, from *validatorStub, hash []byte, header types.PartSetHeader) *types.Vote { - vote := signVote(from, voteType, hash, header) - addVoteToFrom(to, from, vote) - return vote -} - -func ensureNoNewStep(t *testing.T, cs *ConsensusState) { - timeout := time.NewTicker(2 * time.Second) - select { - case <-timeout.C: - break - case <-cs.NewStepCh(): - panic("We should be stuck waiting for more votes, not moving to the next step") - } -} - -func ensureNewStep(t *testing.T, cs *ConsensusState) *RoundState { - timeout := time.NewTicker(2 * time.Second) - select { - case <-timeout.C: - panic("We should have gone to the next step, not be stuck waiting") - case rs := <-cs.NewStepCh(): - return rs - } -} - -func waitFor(t *testing.T, cs *ConsensusState, height int, round int, step RoundStepType) { - for { - rs := ensureNewStep(t, cs) - if CompareHRS(rs.Height, rs.Round, rs.Step, height, round, step) < 0 { - continue - } else { - break - } - } -} - -func validatePrevote(t *testing.T, cs *ConsensusState, round int, privVal *validatorStub, blockHash []byte) { - prevotes := cs.Votes.Prevotes(round) - var vote *types.Vote - if vote = prevotes.GetByAddress(privVal.Address); vote == nil { - panic("Failed to find prevote from validator") - } - if blockHash == nil { - if vote.BlockHash != nil { - panic(fmt.Sprintf("Expected prevote to be for nil, got %X", vote.BlockHash)) - } - } else { - if !bytes.Equal(vote.BlockHash, blockHash) { - panic(fmt.Sprintf("Expected prevote to be for %X, got %X", blockHash, vote.BlockHash)) - } - } -} - -func incrementHeight(vss ...*validatorStub) { - for _, vs := range vss { - vs.Height += 1 - } -} - -func incrementRound(vss ...*validatorStub) { - for _, vs := range vss { - vs.Round += 1 - } -} - -func validatePrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound int, privVal *validatorStub, votedBlockHash, lockedBlockHash []byte) { - precommits := cs.Votes.Precommits(thisRound) - var vote *types.Vote - if vote = precommits.GetByAddress(privVal.Address); vote == nil { - panic("Failed to find precommit from validator") - } - - if votedBlockHash == nil { - if vote.BlockHash != nil { - panic("Expected precommit to be for nil") - } - } else { - if !bytes.Equal(vote.BlockHash, votedBlockHash) { - panic("Expected precommit to be for proposal block") - } - } - - if lockedBlockHash == nil { - if cs.LockedRound != lockRound || cs.LockedBlock != nil { - panic(fmt.Sprintf("Expected to be locked on nil at round %d. Got locked at round %d with block %v", lockRound, cs.LockedRound, cs.LockedBlock)) - } - } else { - if cs.LockedRound != lockRound || !bytes.Equal(cs.LockedBlock.Hash(), lockedBlockHash) { - panic(fmt.Sprintf("Expected block to be locked on round %d, got %d. Got locked block %X, expected %X", lockRound, cs.LockedRound, cs.LockedBlock.Hash(), lockedBlockHash)) - } - } - -} - -func validatePrevoteAndPrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound int, privVal *validatorStub, votedBlockHash, lockedBlockHash []byte) { - // verify the prevote - validatePrevote(t, cs, thisRound, privVal, votedBlockHash) - // verify precommit - cs.mtx.Lock() - validatePrecommit(t, cs, thisRound, lockRound, privVal, votedBlockHash, lockedBlockHash) - cs.mtx.Unlock() -} - -func simpleConsensusState(nValidators int) (*ConsensusState, []*validatorStub) { - // Get State - state, privVals := randGenesisState(nValidators, false, 10) - - // fmt.Println(state.Validators) - - vss := make([]*validatorStub, nValidators) - - // make consensus state for lead validator - - // Get BlockStore - blockDB := dbm.NewMemDB() - blockStore := bc.NewBlockStore(blockDB) - - // one for mempool, one for consensus - app := example.NewCounterApplication() - appCMem := app.Open() - appCCon := app.Open() - proxyAppCtxMem := proxy.NewLocalAppContext(appCMem) - proxyAppCtxCon := proxy.NewLocalAppContext(appCCon) - - // Make Mempool - mempool := mempl.NewMempool(proxyAppCtxMem) - - // Make ConsensusReactor - cs := NewConsensusState(state, proxyAppCtxCon, blockStore, mempool) - cs.SetPrivValidator(privVals[0]) - - evsw := events.NewEventSwitch() - cs.SetFireable(evsw) - - // read off the NewHeightStep - <-cs.NewStepCh() - - for i := 0; i < nValidators; i++ { - vss[i] = NewValidatorStub(privVals[i]) - } - // since cs1 starts at 1 - incrementHeight(vss[1:]...) - - return cs, vss -} - -func randGenesisState(numValidators int, randPower bool, minPower int64) (*sm.State, []*types.PrivValidator) { - db := dbm.NewMemDB() - genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower) - s0 := sm.MakeGenesisState(db, genDoc) - s0.Save() - return s0, privValidators -} - -func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.GenesisDoc, []*types.PrivValidator) { - validators := make([]types.GenesisValidator, numValidators) - privValidators := make([]*types.PrivValidator, numValidators) - for i := 0; i < numValidators; i++ { - val, privVal := types.RandValidator(randPower, minPower) - validators[i] = types.GenesisValidator{ - PubKey: val.PubKey, - Amount: val.VotingPower, - } - privValidators[i] = privVal - } - sort.Sort(types.PrivValidatorsByAddress(privValidators)) - return &types.GenesisDoc{ - GenesisTime: time.Now(), - ChainID: config.GetString("chain_id"), - Validators: validators, - }, privValidators - -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/config.go deleted file mode 100644 index 63706a7f727fd976355e7a80c9a90693396300df..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package consensus - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/height_vote_set.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/height_vote_set.go deleted file mode 100644 index 1fa956cda86776a7619a84b5c84f58988eb4704c..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/height_vote_set.go +++ /dev/null @@ -1,182 +0,0 @@ -package consensus - -import ( - "strings" - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -type RoundVoteSet struct { - Prevotes *types.VoteSet - Precommits *types.VoteSet -} - -/* -Keeps track of all VoteSets from round 0 to round 'round'. - -Also keeps track of up to one RoundVoteSet greater than -'round' from each peer, to facilitate catchup syncing of commits. - -A commit is +2/3 precommits for a block at a round, -but which round is not known in advance, so when a peer -provides a precommit for a round greater than mtx.round, -we create a new entry in roundVoteSets but also remember the -peer to prevent abuse. -*/ -type HeightVoteSet struct { - height int - valSet *types.ValidatorSet - - mtx sync.Mutex - round int // max tracked round - roundVoteSets map[int]RoundVoteSet // keys: [0...round] - peerCatchupRounds map[string]int // keys: peer.Key; values: round -} - -func NewHeightVoteSet(height int, valSet *types.ValidatorSet) *HeightVoteSet { - hvs := &HeightVoteSet{ - height: height, - valSet: valSet, - roundVoteSets: make(map[int]RoundVoteSet), - peerCatchupRounds: make(map[string]int), - } - hvs.addRound(0) - hvs.round = 0 - return hvs -} - -func (hvs *HeightVoteSet) Height() int { - return hvs.height -} - -func (hvs *HeightVoteSet) Round() int { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.round -} - -// Create more RoundVoteSets up to round. -func (hvs *HeightVoteSet) SetRound(round int) { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - if hvs.round != 0 && (round < hvs.round+1) { - PanicSanity("SetRound() must increment hvs.round") - } - for r := hvs.round + 1; r <= round; r++ { - if _, ok := hvs.roundVoteSets[r]; ok { - continue // Already exists because peerCatchupRounds. - } - hvs.addRound(r) - } - hvs.round = round -} - -func (hvs *HeightVoteSet) addRound(round int) { - if _, ok := hvs.roundVoteSets[round]; ok { - PanicSanity("addRound() for an existing round") - } - log.Debug("addRound(round)", "round", round) - prevotes := types.NewVoteSet(hvs.height, round, types.VoteTypePrevote, hvs.valSet) - precommits := types.NewVoteSet(hvs.height, round, types.VoteTypePrecommit, hvs.valSet) - hvs.roundVoteSets[round] = RoundVoteSet{ - Prevotes: prevotes, - Precommits: precommits, - } -} - -// Duplicate votes return added=false, err=nil. -// By convention, peerKey is "" if origin is self. -func (hvs *HeightVoteSet) AddByIndex(valIndex int, vote *types.Vote, peerKey string) (added bool, address []byte, err error) { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - voteSet := hvs.getVoteSet(vote.Round, vote.Type) - if voteSet == nil { - if _, ok := hvs.peerCatchupRounds[peerKey]; !ok { - hvs.addRound(vote.Round) - hvs.peerCatchupRounds[peerKey] = vote.Round - } else { - // Peer has sent a vote that does not match our round, - // for more than one round. Bad peer! - // TODO punish peer. - log.Warn("Deal with peer giving votes from unwanted rounds") - } - return - } - added, address, err = voteSet.AddByIndex(valIndex, vote) - return -} - -func (hvs *HeightVoteSet) Prevotes(round int) *types.VoteSet { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.getVoteSet(round, types.VoteTypePrevote) -} - -func (hvs *HeightVoteSet) Precommits(round int) *types.VoteSet { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - return hvs.getVoteSet(round, types.VoteTypePrecommit) -} - -// Last round that has +2/3 prevotes for a particular block or nil. -// Returns -1 if no such round exists. -func (hvs *HeightVoteSet) POLRound() int { - hvs.mtx.Lock() - defer hvs.mtx.Unlock() - for r := hvs.round; r >= 0; r-- { - if hvs.getVoteSet(r, types.VoteTypePrevote).HasTwoThirdsMajority() { - return r - } - } - return -1 -} - -func (hvs *HeightVoteSet) getVoteSet(round int, type_ byte) *types.VoteSet { - log.Debug("getVoteSet(round)", "round", round, "type", type_) - rvs, ok := hvs.roundVoteSets[round] - if !ok { - return nil - } - switch type_ { - case types.VoteTypePrevote: - return rvs.Prevotes - case types.VoteTypePrecommit: - return rvs.Precommits - default: - PanicSanity(Fmt("Unexpected vote type %X", type_)) - return nil - } -} - -func (hvs *HeightVoteSet) String() string { - return hvs.StringIndented("") -} - -func (hvs *HeightVoteSet) StringIndented(indent string) string { - vsStrings := make([]string, 0, (len(hvs.roundVoteSets)+1)*2) - // rounds 0 ~ hvs.round inclusive - for round := 0; round <= hvs.round; round++ { - voteSetString := hvs.roundVoteSets[round].Prevotes.StringShort() - vsStrings = append(vsStrings, voteSetString) - voteSetString = hvs.roundVoteSets[round].Precommits.StringShort() - vsStrings = append(vsStrings, voteSetString) - } - // all other peer catchup rounds - for round, roundVoteSet := range hvs.roundVoteSets { - if round <= hvs.round { - continue - } - voteSetString := roundVoteSet.Prevotes.StringShort() - vsStrings = append(vsStrings, voteSetString) - voteSetString = roundVoteSet.Precommits.StringShort() - vsStrings = append(vsStrings, voteSetString) - } - return Fmt(`HeightVoteSet{H:%v R:0~%v -%s %v -%s}`, - hvs.height, hvs.round, - indent, strings.Join(vsStrings, "\n"+indent+" "), - indent) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go deleted file mode 100644 index ba38a689e78a170489905bbebd4cb38bad7a7a5c..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package consensus - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "consensus") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/reactor.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/reactor.go deleted file mode 100644 index bbefb21dabdab1ae6f26c2a8d391c17d38c0f931..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/reactor.go +++ /dev/null @@ -1,1007 +0,0 @@ -package consensus - -import ( - "bytes" - "errors" - "fmt" - "reflect" - "sync" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - StateChannel = byte(0x20) - DataChannel = byte(0x21) - VoteChannel = byte(0x22) - - peerGossipSleepDuration = 100 * time.Millisecond // Time to sleep if there's nothing to send. - maxConsensusMessageSize = 1048576 // 1MB; NOTE: keep in sync with types.PartSet sizes. -) - -//----------------------------------------------------------------------------- - -type ConsensusReactor struct { - p2p.BaseReactor - - blockStore *bc.BlockStore - conS *ConsensusState - fastSync bool - evsw events.Fireable -} - -func NewConsensusReactor(consensusState *ConsensusState, blockStore *bc.BlockStore, fastSync bool) *ConsensusReactor { - conR := &ConsensusReactor{ - blockStore: blockStore, - conS: consensusState, - fastSync: fastSync, - } - conR.BaseReactor = *p2p.NewBaseReactor(log, "ConsensusReactor", conR) - return conR -} - -func (conR *ConsensusReactor) OnStart() error { - log.Notice("ConsensusReactor ", "fastSync", conR.fastSync) - conR.BaseReactor.OnStart() - if !conR.fastSync { - _, err := conR.conS.Start() - if err != nil { - return err - } - } - go conR.broadcastNewRoundStepRoutine() - return nil -} - -func (conR *ConsensusReactor) OnStop() { - conR.BaseReactor.OnStop() - conR.conS.Stop() -} - -// Switch from the fast_sync to the consensus: -// reset the state, turn off fast_sync, start the consensus-state-machine -func (conR *ConsensusReactor) SwitchToConsensus(state *sm.State) { - log.Notice("SwitchToConsensus") - // NOTE: The line below causes broadcastNewRoundStepRoutine() to - // broadcast a NewRoundStepMessage. - conR.conS.updateToState(state) - conR.fastSync = false - conR.conS.Start() -} - -// Implements Reactor -func (conR *ConsensusReactor) GetChannels() []*p2p.ChannelDescriptor { - // TODO optimize - return []*p2p.ChannelDescriptor{ - &p2p.ChannelDescriptor{ - ID: StateChannel, - Priority: 5, - SendQueueCapacity: 100, - }, - &p2p.ChannelDescriptor{ - ID: DataChannel, - Priority: 5, - SendQueueCapacity: 2, - }, - &p2p.ChannelDescriptor{ - ID: VoteChannel, - Priority: 5, - SendQueueCapacity: 40, - }, - } -} - -// Implements Reactor -func (conR *ConsensusReactor) AddPeer(peer *p2p.Peer) { - if !conR.IsRunning() { - return - } - - // Create peerState for peer - peerState := NewPeerState(peer) - peer.Data.Set(types.PeerStateKey, peerState) - - // Begin gossip routines for this peer. - go conR.gossipDataRoutine(peer, peerState) - go conR.gossipVotesRoutine(peer, peerState) - - // Send our state to peer. - // If we're fast_syncing, broadcast a RoundStepMessage later upon SwitchToConsensus(). - if !conR.fastSync { - conR.sendNewRoundStepMessage(peer) - } -} - -// Implements Reactor -func (conR *ConsensusReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { - if !conR.IsRunning() { - return - } - // TODO - //peer.Data.Get(PeerStateKey).(*PeerState).Disconnect() -} - -// Implements Reactor -// NOTE: We process these messages even when we're fast_syncing. -func (conR *ConsensusReactor) Receive(chID byte, peer *p2p.Peer, msgBytes []byte) { - if !conR.IsRunning() { - log.Debug("Receive", "channel", chID, "peer", peer, "bytes", msgBytes) - return - } - - // Get peer states - ps := peer.Data.Get(types.PeerStateKey).(*PeerState) - _, msg, err := DecodeMessage(msgBytes) - if err != nil { - log.Warn("Error decoding message", "channel", chID, "peer", peer, "msg", msg, "error", err, "bytes", msgBytes) - // TODO punish peer? - return - } - log.Debug("Receive", "channel", chID, "peer", peer, "msg", msg) - - switch chID { - case StateChannel: - switch msg := msg.(type) { - case *NewRoundStepMessage: - ps.ApplyNewRoundStepMessage(msg) - case *CommitStepMessage: - ps.ApplyCommitStepMessage(msg) - case *HasVoteMessage: - ps.ApplyHasVoteMessage(msg) - default: - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - - case DataChannel: - if conR.fastSync { - log.Warn("Ignoring message received during fastSync", "msg", msg) - return - } - switch msg := msg.(type) { - case *ProposalMessage: - ps.SetHasProposal(msg.Proposal) - err = conR.conS.SetProposal(msg.Proposal) - case *ProposalPOLMessage: - ps.ApplyProposalPOLMessage(msg) - case *BlockPartMessage: - ps.SetHasProposalBlockPart(msg.Height, msg.Round, msg.Part.Proof.Index) - _, err = conR.conS.AddProposalBlockPart(msg.Height, msg.Part) - default: - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - - case VoteChannel: - if conR.fastSync { - log.Warn("Ignoring message received during fastSync", "msg", msg) - return - } - switch msg := msg.(type) { - case *VoteMessage: - vote, valIndex := msg.Vote, msg.ValidatorIndex - - // attempt to add the vote and dupeout the validator if its a duplicate signature - added, err := conR.conS.TryAddVote(valIndex, vote, peer.Key) - if err == ErrAddingVote { - // TODO: punish peer - } else if err != nil { - return - } - - cs := conR.conS - cs.mtx.Lock() - height, valSize, lastCommitSize := cs.Height, cs.Validators.Size(), cs.LastCommit.Size() - cs.mtx.Unlock() - ps.EnsureVoteBitArrays(height, valSize) - ps.EnsureVoteBitArrays(height-1, lastCommitSize) - ps.SetHasVote(vote, valIndex) - - if added { - // If rs.Height == vote.Height && rs.Round < vote.Round, - // the peer is sending us CatchupCommit precommits. - // We could make note of this and help filter in broadcastHasVoteMessage(). - conR.broadcastHasVoteMessage(vote, valIndex) - } - - default: - // don't punish (leave room for soft upgrades) - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } - default: - log.Warn(Fmt("Unknown channel %X", chID)) - } - - if err != nil { - log.Warn("Error in Receive()", "error", err) - } -} - -// Broadcasts HasVoteMessage to peers that care. -func (conR *ConsensusReactor) broadcastHasVoteMessage(vote *types.Vote, index int) { - msg := &HasVoteMessage{ - Height: vote.Height, - Round: vote.Round, - Type: vote.Type, - Index: index, - } - conR.Switch.Broadcast(StateChannel, msg) - /* - // TODO: Make this broadcast more selective. - for _, peer := range conR.Switch.Peers().List() { - ps := peer.Data.Get(PeerStateKey).(*PeerState) - prs := ps.GetRoundState() - if prs.Height == vote.Height { - // TODO: Also filter on round? - peer.TrySend(StateChannel, msg) - } else { - // Height doesn't match - // TODO: check a field, maybe CatchupCommitRound? - // TODO: But that requires changing the struct field comment. - } - } - */ -} - -// Sets our private validator account for signing votes. -func (conR *ConsensusReactor) SetPrivValidator(priv *types.PrivValidator) { - conR.conS.SetPrivValidator(priv) -} - -// implements events.Eventable -func (conR *ConsensusReactor) SetFireable(evsw events.Fireable) { - conR.evsw = evsw - conR.conS.SetFireable(evsw) -} - -//-------------------------------------- - -func makeRoundStepMessages(rs *RoundState) (nrsMsg *NewRoundStepMessage, csMsg *CommitStepMessage) { - nrsMsg = &NewRoundStepMessage{ - Height: rs.Height, - Round: rs.Round, - Step: rs.Step, - SecondsSinceStartTime: int(time.Now().Sub(rs.StartTime).Seconds()), - LastCommitRound: rs.LastCommit.Round(), - } - if rs.Step == RoundStepCommit { - csMsg = &CommitStepMessage{ - Height: rs.Height, - BlockPartsHeader: rs.ProposalBlockParts.Header(), - BlockParts: rs.ProposalBlockParts.BitArray(), - } - } - return -} - -// Listens for changes to the ConsensusState.Step by pulling -// on conR.conS.NewStepCh(). -func (conR *ConsensusReactor) broadcastNewRoundStepRoutine() { - for { - // Get RoundState with new Step or quit. - var rs *RoundState - select { - case rs = <-conR.conS.NewStepCh(): - case <-conR.Quit: - return - } - - nrsMsg, csMsg := makeRoundStepMessages(rs) - if nrsMsg != nil { - conR.Switch.Broadcast(StateChannel, nrsMsg) - } - if csMsg != nil { - conR.Switch.Broadcast(StateChannel, csMsg) - } - } -} - -func (conR *ConsensusReactor) sendNewRoundStepMessage(peer *p2p.Peer) { - rs := conR.conS.GetRoundState() - nrsMsg, csMsg := makeRoundStepMessages(rs) - if nrsMsg != nil { - peer.Send(StateChannel, nrsMsg) - } - if csMsg != nil { - peer.Send(StateChannel, csMsg) - } -} - -func (conR *ConsensusReactor) gossipDataRoutine(peer *p2p.Peer, ps *PeerState) { - log := log.New("peer", peer.Key) - -OUTER_LOOP: - for { - // Manage disconnects from self or peer. - if !peer.IsRunning() || !conR.IsRunning() { - log.Notice(Fmt("Stopping gossipDataRoutine for %v.", peer)) - return - } - rs := conR.conS.GetRoundState() - prs := ps.GetRoundState() - - // Send proposal Block parts? - if rs.ProposalBlockParts.HasHeader(prs.ProposalBlockPartsHeader) { - //log.Info("ProposalBlockParts matched", "blockParts", prs.ProposalBlockParts) - if index, ok := rs.ProposalBlockParts.BitArray().Sub(prs.ProposalBlockParts.Copy()).PickRandom(); ok { - part := rs.ProposalBlockParts.GetPart(index) - msg := &BlockPartMessage{ - Height: rs.Height, // This tells peer that this part applies to us. - Round: rs.Round, // This tells peer that this part applies to us. - Part: part, - } - peer.Send(DataChannel, msg) - ps.SetHasProposalBlockPart(prs.Height, prs.Round, index) - continue OUTER_LOOP - } - } - - // If the peer is on a previous height, help catch up. - if (0 < prs.Height) && (prs.Height < rs.Height) { - //log.Info("Data catchup", "height", rs.Height, "peerHeight", prs.Height, "peerProposalBlockParts", prs.ProposalBlockParts) - if index, ok := prs.ProposalBlockParts.Not().PickRandom(); ok { - // Ensure that the peer's PartSetHeader is correct - blockMeta := conR.blockStore.LoadBlockMeta(prs.Height) - if !blockMeta.PartsHeader.Equals(prs.ProposalBlockPartsHeader) { - log.Info("Peer ProposalBlockPartsHeader mismatch, sleeping", - "peerHeight", prs.Height, "blockPartsHeader", blockMeta.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader) - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } - // Load the part - part := conR.blockStore.LoadBlockPart(prs.Height, index) - if part == nil { - log.Warn("Could not load part", "index", index, - "peerHeight", prs.Height, "blockPartsHeader", blockMeta.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader) - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } - // Send the part - msg := &BlockPartMessage{ - Height: prs.Height, // Not our height, so it doesn't matter. - Round: prs.Round, // Not our height, so it doesn't matter. - Part: part, - } - peer.Send(DataChannel, msg) - ps.SetHasProposalBlockPart(prs.Height, prs.Round, index) - continue OUTER_LOOP - } else { - //log.Info("No parts to send in catch-up, sleeping") - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } - } - - // If height and round don't match, sleep. - if (rs.Height != prs.Height) || (rs.Round != prs.Round) { - //log.Info("Peer Height|Round mismatch, sleeping", "peerHeight", prs.Height, "peerRound", prs.Round, "peer", peer) - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } - - // By here, height and round match. - // Proposal block parts were already matched and sent if any were wanted. - // (These can match on hash so the round doesn't matter) - // Now consider sending other things, like the Proposal itself. - - // Send Proposal && ProposalPOL BitArray? - if rs.Proposal != nil && !prs.Proposal { - // Proposal - { - msg := &ProposalMessage{Proposal: rs.Proposal} - peer.Send(DataChannel, msg) - ps.SetHasProposal(rs.Proposal) - } - // ProposalPOL. - // Peer must receive ProposalMessage first. - // rs.Proposal was validated, so rs.Proposal.POLRound <= rs.Round, - // so we definitely have rs.Votes.Prevotes(rs.Proposal.POLRound). - if 0 <= rs.Proposal.POLRound { - msg := &ProposalPOLMessage{ - Height: rs.Height, - ProposalPOLRound: rs.Proposal.POLRound, - ProposalPOL: rs.Votes.Prevotes(rs.Proposal.POLRound).BitArray(), - } - peer.Send(DataChannel, msg) - } - continue OUTER_LOOP - } - - // Nothing to do. Sleep. - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } -} - -func (conR *ConsensusReactor) gossipVotesRoutine(peer *p2p.Peer, ps *PeerState) { - log := log.New("peer", peer.Key) - - // Simple hack to throttle logs upon sleep. - var sleeping = 0 - -OUTER_LOOP: - for { - // Manage disconnects from self or peer. - if !peer.IsRunning() || !conR.IsRunning() { - log.Notice(Fmt("Stopping gossipVotesRoutine for %v.", peer)) - return - } - rs := conR.conS.GetRoundState() - prs := ps.GetRoundState() - - switch sleeping { - case 1: // First sleep - sleeping = 2 - case 2: // No more sleep - sleeping = 0 - } - - log.Debug("gossipVotesRoutine", "rsHeight", rs.Height, "rsRound", rs.Round, - "prsHeight", prs.Height, "prsRound", prs.Round, "prsStep", prs.Step) - - // If height matches, then send LastCommit, Prevotes, Precommits. - if rs.Height == prs.Height { - // If there are lastCommits to send... - if prs.Step == RoundStepNewHeight { - if ps.PickSendVote(rs.LastCommit) { - log.Info("Picked rs.LastCommit to send") - continue OUTER_LOOP - } - } - // If there are prevotes to send... - if prs.Step <= RoundStepPrevote && prs.Round != -1 && prs.Round <= rs.Round { - if ps.PickSendVote(rs.Votes.Prevotes(prs.Round)) { - log.Info("Picked rs.Prevotes(prs.Round) to send") - continue OUTER_LOOP - } - } - // If there are precommits to send... - if prs.Step <= RoundStepPrecommit && prs.Round != -1 && prs.Round <= rs.Round { - if ps.PickSendVote(rs.Votes.Precommits(prs.Round)) { - log.Info("Picked rs.Precommits(prs.Round) to send") - continue OUTER_LOOP - } - } - // If there are POLPrevotes to send... - if prs.ProposalPOLRound != -1 { - if polPrevotes := rs.Votes.Prevotes(prs.ProposalPOLRound); polPrevotes != nil { - if ps.PickSendVote(polPrevotes) { - log.Info("Picked rs.Prevotes(prs.ProposalPOLRound) to send") - continue OUTER_LOOP - } - } - } - } - - // Special catchup logic. - // If peer is lagging by height 1, send LastCommit. - if prs.Height != 0 && rs.Height == prs.Height+1 { - if ps.PickSendVote(rs.LastCommit) { - log.Info("Picked rs.LastCommit to send") - continue OUTER_LOOP - } - } - - // Catchup logic - // If peer is lagging by more than 1, send Validation. - if prs.Height != 0 && rs.Height >= prs.Height+2 { - // Load the block validation for prs.Height, - // which contains precommit signatures for prs.Height. - validation := conR.blockStore.LoadBlockValidation(prs.Height) - log.Info("Loaded BlockValidation for catch-up", "height", prs.Height, "validation", validation) - if ps.PickSendVote(validation) { - log.Info("Picked Catchup validation to send") - continue OUTER_LOOP - } - } - - if sleeping == 0 { - // We sent nothing. Sleep... - sleeping = 1 - log.Info("No votes to send, sleeping", "peer", peer, - "localPV", rs.Votes.Prevotes(rs.Round).BitArray(), "peerPV", prs.Prevotes, - "localPC", rs.Votes.Precommits(rs.Round).BitArray(), "peerPC", prs.Precommits) - } else if sleeping == 2 { - // Continued sleep... - sleeping = 1 - } - - time.Sleep(peerGossipSleepDuration) - continue OUTER_LOOP - } -} - -//----------------------------------------------------------------------------- - -// Read only when returned by PeerState.GetRoundState(). -type PeerRoundState struct { - Height int // Height peer is at - Round int // Round peer is at, -1 if unknown. - Step RoundStepType // Step peer is at - StartTime time.Time // Estimated start of round 0 at this height - Proposal bool // True if peer has proposal for this round - ProposalBlockPartsHeader types.PartSetHeader // - ProposalBlockParts *BitArray // - ProposalPOLRound int // Proposal's POL round. -1 if none. - ProposalPOL *BitArray // nil until ProposalPOLMessage received. - Prevotes *BitArray // All votes peer has for this round - Precommits *BitArray // All precommits peer has for this round - LastCommitRound int // Round of commit for last height. -1 if none. - LastCommit *BitArray // All commit precommits of commit for last height. - CatchupCommitRound int // Round that we have commit for. Not necessarily unique. -1 if none. - CatchupCommit *BitArray // All commit precommits peer has for this height & CatchupCommitRound -} - -//----------------------------------------------------------------------------- - -var ( - ErrPeerStateHeightRegression = errors.New("Error peer state height regression") - ErrPeerStateInvalidStartTime = errors.New("Error peer state invalid startTime") -) - -type PeerState struct { - Peer *p2p.Peer - - mtx sync.Mutex - PeerRoundState -} - -func NewPeerState(peer *p2p.Peer) *PeerState { - return &PeerState{ - Peer: peer, - PeerRoundState: PeerRoundState{ - Round: -1, - ProposalPOLRound: -1, - LastCommitRound: -1, - CatchupCommitRound: -1, - }, - } -} - -// Returns an atomic snapshot of the PeerRoundState. -// There's no point in mutating it since it won't change PeerState. -func (ps *PeerState) GetRoundState() *PeerRoundState { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - prs := ps.PeerRoundState // copy - return &prs -} - -// Returns an atomic snapshot of the PeerRoundState's height -// used by the mempool to ensure peers are caught up before broadcasting new txs -func (ps *PeerState) GetHeight() int { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return ps.PeerRoundState.Height -} - -func (ps *PeerState) SetHasProposal(proposal *types.Proposal) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != proposal.Height || ps.Round != proposal.Round { - return - } - if ps.Proposal { - return - } - - ps.Proposal = true - ps.ProposalBlockPartsHeader = proposal.BlockPartsHeader - ps.ProposalBlockParts = NewBitArray(proposal.BlockPartsHeader.Total) - ps.ProposalPOLRound = proposal.POLRound - ps.ProposalPOL = nil // Nil until ProposalPOLMessage received. -} - -func (ps *PeerState) SetHasProposalBlockPart(height int, round int, index int) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != height || ps.Round != round { - return - } - - ps.ProposalBlockParts.SetIndex(index, true) -} - -// Convenience function to send vote to peer. -// Returns true if vote was sent. -func (ps *PeerState) PickSendVote(votes types.VoteSetReader) (ok bool) { - if index, vote, ok := ps.PickVoteToSend(votes); ok { - msg := &VoteMessage{index, vote} - ps.Peer.Send(VoteChannel, msg) - return true - } - return false -} - -// votes: Must be the correct Size() for the Height(). -func (ps *PeerState) PickVoteToSend(votes types.VoteSetReader) (index int, vote *types.Vote, ok bool) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if votes.Size() == 0 { - return 0, nil, false - } - - height, round, type_, size := votes.Height(), votes.Round(), votes.Type(), votes.Size() - - // Lazily set data using 'votes'. - if votes.IsCommit() { - ps.ensureCatchupCommitRound(height, round, size) - } - ps.ensureVoteBitArrays(height, size) - - psVotes := ps.getVoteBitArray(height, round, type_) - if psVotes == nil { - return 0, nil, false // Not something worth sending - } - if index, ok := votes.BitArray().Sub(psVotes).PickRandom(); ok { - ps.setHasVote(height, round, type_, index) - return index, votes.GetByIndex(index), true - } - return 0, nil, false -} - -func (ps *PeerState) getVoteBitArray(height, round int, type_ byte) *BitArray { - if ps.Height == height { - if ps.Round == round { - switch type_ { - case types.VoteTypePrevote: - return ps.Prevotes - case types.VoteTypePrecommit: - return ps.Precommits - default: - PanicSanity(Fmt("Unexpected vote type %X", type_)) - } - } - if ps.CatchupCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - return nil - case types.VoteTypePrecommit: - return ps.CatchupCommit - default: - PanicSanity(Fmt("Unexpected vote type %X", type_)) - } - } - return nil - } - if ps.Height == height+1 { - if ps.LastCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - return nil - case types.VoteTypePrecommit: - return ps.LastCommit - default: - PanicSanity(Fmt("Unexpected vote type %X", type_)) - } - } - return nil - } - return nil -} - -// 'round': A round for which we have a +2/3 commit. -func (ps *PeerState) ensureCatchupCommitRound(height, round int, numValidators int) { - if ps.Height != height { - return - } - /* - NOTE: This is wrong, 'round' could change. - e.g. if orig round is not the same as block LastValidation round. - if ps.CatchupCommitRound != -1 && ps.CatchupCommitRound != round { - PanicSanity(Fmt("Conflicting CatchupCommitRound. Height: %v, Orig: %v, New: %v", height, ps.CatchupCommitRound, round)) - } - */ - if ps.CatchupCommitRound == round { - return // Nothing to do! - } - ps.CatchupCommitRound = round - if round == ps.Round { - ps.CatchupCommit = ps.Precommits - } else { - ps.CatchupCommit = NewBitArray(numValidators) - } -} - -// NOTE: It's important to make sure that numValidators actually matches -// what the node sees as the number of validators for height. -func (ps *PeerState) EnsureVoteBitArrays(height int, numValidators int) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - ps.ensureVoteBitArrays(height, numValidators) -} - -func (ps *PeerState) ensureVoteBitArrays(height int, numValidators int) { - if ps.Height == height { - if ps.Prevotes == nil { - ps.Prevotes = NewBitArray(numValidators) - } - if ps.Precommits == nil { - ps.Precommits = NewBitArray(numValidators) - } - if ps.CatchupCommit == nil { - ps.CatchupCommit = NewBitArray(numValidators) - } - if ps.ProposalPOL == nil { - ps.ProposalPOL = NewBitArray(numValidators) - } - } else if ps.Height == height+1 { - if ps.LastCommit == nil { - ps.LastCommit = NewBitArray(numValidators) - } - } -} - -func (ps *PeerState) SetHasVote(vote *types.Vote, index int) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - ps.setHasVote(vote.Height, vote.Round, vote.Type, index) -} - -func (ps *PeerState) setHasVote(height int, round int, type_ byte, index int) { - log := log.New("peer", ps.Peer.Key, "peerRound", ps.Round, "height", height, "round", round) - if type_ != types.VoteTypePrevote && type_ != types.VoteTypePrecommit { - PanicSanity("Invalid vote type") - } - - if ps.Height == height { - if ps.Round == round { - switch type_ { - case types.VoteTypePrevote: - ps.Prevotes.SetIndex(index, true) - log.Info("SetHasVote(round-match)", "prevotes", ps.Prevotes, "index", index) - case types.VoteTypePrecommit: - ps.Precommits.SetIndex(index, true) - log.Info("SetHasVote(round-match)", "precommits", ps.Precommits, "index", index) - } - } else if ps.CatchupCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - case types.VoteTypePrecommit: - ps.CatchupCommit.SetIndex(index, true) - log.Info("SetHasVote(CatchupCommit)", "precommits", ps.Precommits, "index", index) - } - } else if ps.ProposalPOLRound == round { - switch type_ { - case types.VoteTypePrevote: - ps.ProposalPOL.SetIndex(index, true) - log.Info("SetHasVote(ProposalPOL)", "prevotes", ps.Prevotes, "index", index) - case types.VoteTypePrecommit: - } - } - } else if ps.Height == height+1 { - if ps.LastCommitRound == round { - switch type_ { - case types.VoteTypePrevote: - case types.VoteTypePrecommit: - ps.LastCommit.SetIndex(index, true) - log.Info("setHasVote(LastCommit)", "lastCommit", ps.LastCommit, "index", index) - } - } - } else { - // Does not apply. - } -} - -func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - // Ignore duplicate messages. - if ps.Height == msg.Height && ps.Round == msg.Round && ps.Step == msg.Step { - return - } - - // Just remember these values. - psHeight := ps.Height - psRound := ps.Round - //psStep := ps.Step - psCatchupCommitRound := ps.CatchupCommitRound - psCatchupCommit := ps.CatchupCommit - - startTime := time.Now().Add(-1 * time.Duration(msg.SecondsSinceStartTime) * time.Second) - ps.Height = msg.Height - ps.Round = msg.Round - ps.Step = msg.Step - ps.StartTime = startTime - if psHeight != msg.Height || psRound != msg.Round { - ps.Proposal = false - ps.ProposalBlockPartsHeader = types.PartSetHeader{} - ps.ProposalBlockParts = nil - ps.ProposalPOLRound = -1 - ps.ProposalPOL = nil - // We'll update the BitArray capacity later. - ps.Prevotes = nil - ps.Precommits = nil - } - if psHeight == msg.Height && psRound != msg.Round && msg.Round == psCatchupCommitRound { - // Peer caught up to CatchupCommitRound. - // Preserve psCatchupCommit! - // NOTE: We prefer to use prs.Precommits if - // pr.Round matches pr.CatchupCommitRound. - ps.Precommits = psCatchupCommit - } - if psHeight != msg.Height { - // Shift Precommits to LastCommit. - if psHeight+1 == msg.Height && psRound == msg.LastCommitRound { - ps.LastCommitRound = msg.LastCommitRound - ps.LastCommit = ps.Precommits - } else { - ps.LastCommitRound = msg.LastCommitRound - ps.LastCommit = nil - } - // We'll update the BitArray capacity later. - ps.CatchupCommitRound = -1 - ps.CatchupCommit = nil - } -} - -func (ps *PeerState) ApplyCommitStepMessage(msg *CommitStepMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != msg.Height { - return - } - - ps.ProposalBlockPartsHeader = msg.BlockPartsHeader - ps.ProposalBlockParts = msg.BlockParts -} - -func (ps *PeerState) ApplyHasVoteMessage(msg *HasVoteMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != msg.Height { - return - } - - ps.setHasVote(msg.Height, msg.Round, msg.Type, msg.Index) -} - -func (ps *PeerState) ApplyProposalPOLMessage(msg *ProposalPOLMessage) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - if ps.Height != msg.Height { - return - } - if ps.ProposalPOLRound != msg.ProposalPOLRound { - return - } - - // TODO: Merge onto existing ps.ProposalPOL? - // We might have sent some prevotes in the meantime. - ps.ProposalPOL = msg.ProposalPOL -} - -//----------------------------------------------------------------------------- -// Messages - -const ( - msgTypeNewRoundStep = byte(0x01) - msgTypeCommitStep = byte(0x02) - msgTypeProposal = byte(0x11) - msgTypeProposalPOL = byte(0x12) - msgTypeBlockPart = byte(0x13) // both block & POL - msgTypeVote = byte(0x14) - msgTypeHasVote = byte(0x15) -) - -type ConsensusMessage interface{} - -var _ = wire.RegisterInterface( - struct{ ConsensusMessage }{}, - wire.ConcreteType{&NewRoundStepMessage{}, msgTypeNewRoundStep}, - wire.ConcreteType{&CommitStepMessage{}, msgTypeCommitStep}, - wire.ConcreteType{&ProposalMessage{}, msgTypeProposal}, - wire.ConcreteType{&ProposalPOLMessage{}, msgTypeProposalPOL}, - wire.ConcreteType{&BlockPartMessage{}, msgTypeBlockPart}, - wire.ConcreteType{&VoteMessage{}, msgTypeVote}, - wire.ConcreteType{&HasVoteMessage{}, msgTypeHasVote}, -) - -// TODO: check for unnecessary extra bytes at the end. -func DecodeMessage(bz []byte) (msgType byte, msg ConsensusMessage, err error) { - msgType = bz[0] - n := new(int) - r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ ConsensusMessage }{}, r, maxConsensusMessageSize, n, &err).(struct{ ConsensusMessage }).ConsensusMessage - return -} - -//------------------------------------- - -// For every height/round/step transition -type NewRoundStepMessage struct { - Height int - Round int - Step RoundStepType - SecondsSinceStartTime int - LastCommitRound int -} - -func (m *NewRoundStepMessage) String() string { - return fmt.Sprintf("[NewRoundStep H:%v R:%v S:%v LCR:%v]", - m.Height, m.Round, m.Step, m.LastCommitRound) -} - -//------------------------------------- - -type CommitStepMessage struct { - Height int - BlockPartsHeader types.PartSetHeader - BlockParts *BitArray -} - -func (m *CommitStepMessage) String() string { - return fmt.Sprintf("[CommitStep H:%v BP:%v BA:%v]", m.Height, m.BlockPartsHeader, m.BlockParts) -} - -//------------------------------------- - -type ProposalMessage struct { - Proposal *types.Proposal -} - -func (m *ProposalMessage) String() string { - return fmt.Sprintf("[Proposal %v]", m.Proposal) -} - -//------------------------------------- - -type ProposalPOLMessage struct { - Height int - ProposalPOLRound int - ProposalPOL *BitArray -} - -func (m *ProposalPOLMessage) String() string { - return fmt.Sprintf("[ProposalPOL H:%v POLR:%v POL:%v]", m.Height, m.ProposalPOLRound, m.ProposalPOL) -} - -//------------------------------------- - -type BlockPartMessage struct { - Height int - Round int - Part *types.Part -} - -func (m *BlockPartMessage) String() string { - return fmt.Sprintf("[BlockPart H:%v R:%v P:%v]", m.Height, m.Round, m.Part) -} - -//------------------------------------- - -type VoteMessage struct { - ValidatorIndex int - Vote *types.Vote -} - -func (m *VoteMessage) String() string { - return fmt.Sprintf("[Vote VI:%v V:%v VI:%v]", m.ValidatorIndex, m.Vote, m.ValidatorIndex) -} - -//------------------------------------- - -type HasVoteMessage struct { - Height int - Round int - Type byte - Index int -} - -func (m *HasVoteMessage) String() string { - return fmt.Sprintf("[HasVote VI:%v V:{%v/%02d/%v} VI:%v]", m.Index, m.Height, m.Round, m.Type, m.Index) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go deleted file mode 100644 index 7e4b6879ce6f4bf478bf9e7d88c2080303afc73a..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state.go +++ /dev/null @@ -1,1189 +0,0 @@ -package consensus - -import ( - "bytes" - "errors" - "fmt" - "sync" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - mempl "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -var ( - timeoutPropose = 3000 * time.Millisecond // Maximum duration of RoundStepPropose - timeoutPrevote0 = 1000 * time.Millisecond // After any +2/3 prevotes received, wait this long for stragglers. - timeoutPrevoteDelta = 0500 * time.Millisecond // timeoutPrevoteN is timeoutPrevote0 + timeoutPrevoteDelta*N - timeoutPrecommit0 = 1000 * time.Millisecond // After any +2/3 precommits received, wait this long for stragglers. - timeoutPrecommitDelta = 0500 * time.Millisecond // timeoutPrecommitN is timeoutPrecommit0 + timeoutPrecommitDelta*N - timeoutCommit = 2000 * time.Millisecond // After +2/3 commits received for committed block, wait this long for stragglers in the next height's RoundStepNewHeight. -) - -var ( - ErrInvalidProposalSignature = errors.New("Error invalid proposal signature") - ErrInvalidProposalPOLRound = errors.New("Error invalid proposal POL round") - ErrAddingVote = errors.New("Error adding vote") - ErrVoteHeightMismatch = errors.New("Error vote height mismatch") -) - -//----------------------------------------------------------------------------- -// RoundStepType enum type - -type RoundStepType uint8 // These must be numeric, ordered. - -const ( - RoundStepNewHeight = RoundStepType(0x01) // Wait til CommitTime + timeoutCommit - RoundStepNewRound = RoundStepType(0x02) // Setup new round and go to RoundStepPropose - RoundStepPropose = RoundStepType(0x03) // Did propose, gossip proposal - RoundStepPrevote = RoundStepType(0x04) // Did prevote, gossip prevotes - RoundStepPrevoteWait = RoundStepType(0x05) // Did receive any +2/3 prevotes, start timeout - RoundStepPrecommit = RoundStepType(0x06) // Did precommit, gossip precommits - RoundStepPrecommitWait = RoundStepType(0x07) // Did receive any +2/3 precommits, start timeout - RoundStepCommit = RoundStepType(0x08) // Entered commit state machine - // NOTE: RoundStepNewHeight acts as RoundStepCommitWait. -) - -func (rs RoundStepType) String() string { - switch rs { - case RoundStepNewHeight: - return "RoundStepNewHeight" - case RoundStepNewRound: - return "RoundStepNewRound" - case RoundStepPropose: - return "RoundStepPropose" - case RoundStepPrevote: - return "RoundStepPrevote" - case RoundStepPrevoteWait: - return "RoundStepPrevoteWait" - case RoundStepPrecommit: - return "RoundStepPrecommit" - case RoundStepPrecommitWait: - return "RoundStepPrecommitWait" - case RoundStepCommit: - return "RoundStepCommit" - default: - return "RoundStepUnknown" // Cannot panic. - } -} - -//----------------------------------------------------------------------------- - -// Immutable when returned from ConsensusState.GetRoundState() -type RoundState struct { - Height int // Height we are working on - Round int - Step RoundStepType - StartTime time.Time - CommitTime time.Time // Subjective time when +2/3 precommits for Block at Round were found - Validators *types.ValidatorSet - Proposal *types.Proposal - ProposalBlock *types.Block - ProposalBlockParts *types.PartSet - LockedRound int - LockedBlock *types.Block - LockedBlockParts *types.PartSet - Votes *HeightVoteSet - CommitRound int // - LastCommit *types.VoteSet // Last precommits at Height-1 - LastValidators *types.ValidatorSet -} - -func (rs *RoundState) RoundStateEvent() *types.EventDataRoundState { - return &types.EventDataRoundState{ - CurrentTime: time.Now(), - Height: rs.Height, - Round: rs.Round, - Step: rs.Step.String(), - StartTime: rs.StartTime, - CommitTime: rs.CommitTime, - Proposal: rs.Proposal, - ProposalBlock: rs.ProposalBlock, - LockedRound: rs.LockedRound, - LockedBlock: rs.LockedBlock, - POLRound: rs.Votes.POLRound(), - } -} - -func (rs *RoundState) String() string { - return rs.StringIndented("") -} - -func (rs *RoundState) StringIndented(indent string) string { - return fmt.Sprintf(`RoundState{ -%s H:%v R:%v S:%v -%s StartTime: %v -%s CommitTime: %v -%s Validators: %v -%s Proposal: %v -%s ProposalBlock: %v %v -%s LockedRound: %v -%s LockedBlock: %v %v -%s Votes: %v -%s LastCommit: %v -%s LastValidators: %v -%s}`, - indent, rs.Height, rs.Round, rs.Step, - indent, rs.StartTime, - indent, rs.CommitTime, - indent, rs.Validators.StringIndented(indent+" "), - indent, rs.Proposal, - indent, rs.ProposalBlockParts.StringShort(), rs.ProposalBlock.StringShort(), - indent, rs.LockedRound, - indent, rs.LockedBlockParts.StringShort(), rs.LockedBlock.StringShort(), - indent, rs.Votes.StringIndented(indent+" "), - indent, rs.LastCommit.StringShort(), - indent, rs.LastValidators.StringIndented(indent+" "), - indent) -} - -func (rs *RoundState) StringShort() string { - return fmt.Sprintf(`RoundState{H:%v R:%v S:%v ST:%v}`, - rs.Height, rs.Round, rs.Step, rs.StartTime) -} - -//----------------------------------------------------------------------------- - -// Tracks consensus state across block heights and rounds. -type ConsensusState struct { - BaseService - - proxyAppCtx proxy.AppContext - blockStore *bc.BlockStore - mempool *mempl.Mempool - privValidator *types.PrivValidator - newStepCh chan *RoundState - - mtx sync.Mutex - RoundState - state *sm.State // State until height-1. - stagedBlock *types.Block // Cache last staged block. - stagedState *sm.State // Cache result of staged block. - - evsw events.Fireable - evc *events.EventCache // set in stageBlock and passed into state -} - -func NewConsensusState(state *sm.State, proxyAppCtx proxy.AppContext, blockStore *bc.BlockStore, mempool *mempl.Mempool) *ConsensusState { - cs := &ConsensusState{ - proxyAppCtx: proxyAppCtx, - blockStore: blockStore, - mempool: mempool, - newStepCh: make(chan *RoundState, 10), - } - cs.updateToState(state) - // Don't call scheduleRound0 yet. - // We do that upon Start(). - cs.reconstructLastCommit(state) - cs.BaseService = *NewBaseService(log, "ConsensusState", cs) - return cs -} - -// Reconstruct LastCommit from SeenValidation, which we saved along with the block, -// (which happens even before saving the state) -func (cs *ConsensusState) reconstructLastCommit(state *sm.State) { - if state.LastBlockHeight == 0 { - return - } - lastPrecommits := types.NewVoteSet(state.LastBlockHeight, 0, types.VoteTypePrecommit, state.LastValidators) - seenValidation := cs.blockStore.LoadSeenValidation(state.LastBlockHeight) - for idx, precommit := range seenValidation.Precommits { - if precommit == nil { - continue - } - added, _, err := lastPrecommits.AddByIndex(idx, precommit) - if !added || err != nil { - PanicCrisis(Fmt("Failed to reconstruct LastCommit: %v", err)) - } - } - if !lastPrecommits.HasTwoThirdsMajority() { - PanicSanity("Failed to reconstruct LastCommit: Does not have +2/3 maj") - } - cs.LastCommit = lastPrecommits -} - -func (cs *ConsensusState) GetState() *sm.State { - cs.mtx.Lock() - defer cs.mtx.Unlock() - return cs.state.Copy() -} - -func (cs *ConsensusState) GetRoundState() *RoundState { - cs.mtx.Lock() - defer cs.mtx.Unlock() - return cs.getRoundState() -} - -func (cs *ConsensusState) getRoundState() *RoundState { - rs := cs.RoundState // copy - return &rs -} - -func (cs *ConsensusState) NewStepCh() chan *RoundState { - return cs.newStepCh -} - -func (cs *ConsensusState) OnStart() error { - cs.BaseService.OnStart() - cs.scheduleRound0(cs.Height) - return nil -} - -func (cs *ConsensusState) OnStop() { - // It's asynchronous so, there's not much to stop. - cs.BaseService.OnStop() -} - -// EnterNewRound(height, 0) at cs.StartTime. -func (cs *ConsensusState) scheduleRound0(height int) { - //log.Info("scheduleRound0", "now", time.Now(), "startTime", cs.StartTime) - sleepDuration := cs.StartTime.Sub(time.Now()) - go func() { - if 0 < sleepDuration { - time.Sleep(sleepDuration) - // TODO: event? - } - cs.EnterNewRound(height, 0, false) - }() -} - -// Updates ConsensusState and increments height to match that of state. -// The round becomes 0 and cs.Step becomes RoundStepNewHeight. -func (cs *ConsensusState) updateToState(state *sm.State) { - if cs.CommitRound > -1 && 0 < cs.Height && cs.Height != state.LastBlockHeight { - PanicSanity(Fmt("updateToState() expected state height of %v but found %v", - cs.Height, state.LastBlockHeight)) - } - if cs.state != nil && cs.state.LastBlockHeight+1 != cs.Height { - // This might happen when someone else is mutating cs.state. - // Someone forgot to pass in state.Copy() somewhere?! - PanicSanity(Fmt("Inconsistent cs.state.LastBlockHeight+1 %v vs cs.Height %v", - cs.state.LastBlockHeight+1, cs.Height)) - } - - // If state isn't further out than cs.state, just ignore. - // This happens when SwitchToConsensus() is called in the reactor. - // We don't want to reset e.g. the Votes. - if cs.state != nil && (state.LastBlockHeight <= cs.state.LastBlockHeight) { - log.Notice("Ignoring updateToState()", "newHeight", state.LastBlockHeight+1, "oldHeight", cs.state.LastBlockHeight+1) - return - } - - // Reset fields based on state. - validators := state.Validators - height := state.LastBlockHeight + 1 // next desired block height - lastPrecommits := (*types.VoteSet)(nil) - if cs.CommitRound > -1 && cs.Votes != nil { - if !cs.Votes.Precommits(cs.CommitRound).HasTwoThirdsMajority() { - PanicSanity("updateToState(state) called but last Precommit round didn't have +2/3") - } - lastPrecommits = cs.Votes.Precommits(cs.CommitRound) - } - - // RoundState fields - cs.Height = height - cs.Round = 0 - cs.Step = RoundStepNewHeight - if cs.CommitTime.IsZero() { - // "Now" makes it easier to sync up dev nodes. - // We add timeoutCommit to allow transactions - // to be gathered for the first block. - // And alternative solution that relies on clocks: - // cs.StartTime = state.LastBlockTime.Add(timeoutCommit) - cs.StartTime = time.Now().Add(timeoutCommit) - } else { - cs.StartTime = cs.CommitTime.Add(timeoutCommit) - } - cs.CommitTime = time.Time{} - cs.Validators = validators - cs.Proposal = nil - cs.ProposalBlock = nil - cs.ProposalBlockParts = nil - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - cs.Votes = NewHeightVoteSet(height, validators) - cs.CommitRound = -1 - cs.LastCommit = lastPrecommits - cs.LastValidators = state.LastValidators - - cs.state = state - cs.stagedBlock = nil - cs.stagedState = nil - - // Finally, broadcast RoundState - cs.newStepCh <- cs.getRoundState() -} - -func (cs *ConsensusState) SetPrivValidator(priv *types.PrivValidator) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - cs.privValidator = priv -} - -//----------------------------------------------------------------------------- - -// Enter: +2/3 precommits for nil at (height,round-1) -// Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1) -// Enter: `startTime = commitTime+timeoutCommit` from NewHeight(height) -// NOTE: cs.StartTime was already set for height. -func (cs *ConsensusState) EnterNewRound(height int, round int, timedOut bool) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != RoundStepNewHeight) { - log.Debug(Fmt("EnterNewRound(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - - if timedOut { - cs.evsw.FireEvent(types.EventStringTimeoutWait(), cs.RoundStateEvent()) - } - - if now := time.Now(); cs.StartTime.After(now) { - log.Warn("Need to set a buffer and log.Warn() here for sanity.", "startTime", cs.StartTime, "now", now) - } - log.Notice(Fmt("EnterNewRound(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Increment validators if necessary - validators := cs.Validators - if cs.Round < round { - validators = validators.Copy() - validators.IncrementAccum(round - cs.Round) - } - - // Setup new round - cs.Round = round - cs.Step = RoundStepNewRound - cs.Validators = validators - if round == 0 { - // We've already reset these upon new height, - // and meanwhile we might have received a proposal - // for round 0. - } else { - cs.Proposal = nil - cs.ProposalBlock = nil - cs.ProposalBlockParts = nil - } - cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping - - cs.evsw.FireEvent(types.EventStringNewRound(), cs.RoundStateEvent()) - - // Immediately go to EnterPropose. - go cs.EnterPropose(height, round) -} - -// Enter: from NewRound(height,round). -func (cs *ConsensusState) EnterPropose(height int, round int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPropose <= cs.Step) { - log.Debug(Fmt("EnterPropose(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - log.Info(Fmt("EnterPropose(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done EnterPropose: - cs.Round = round - cs.Step = RoundStepPropose - cs.newStepCh <- cs.getRoundState() - - // If we have the whole proposal + POL, then goto Prevote now. - // else, we'll EnterPrevote when the rest of the proposal is received (in AddProposalBlockPart), - // or else after timeoutPropose - if cs.isProposalComplete() { - go cs.EnterPrevote(height, cs.Round, false) - } - }() - - // This step times out after `timeoutPropose` - go func() { - time.Sleep(timeoutPropose) - cs.EnterPrevote(height, round, true) - }() - - // Nothing more to do if we're not a validator - if cs.privValidator == nil { - return - } - - if !bytes.Equal(cs.Validators.Proposer().Address, cs.privValidator.Address) { - log.Info("EnterPropose: Not our turn to propose", "proposer", cs.Validators.Proposer().Address, "privValidator", cs.privValidator) - } else { - log.Info("EnterPropose: Our turn to propose", "proposer", cs.Validators.Proposer().Address, "privValidator", cs.privValidator) - cs.decideProposal(height, round) - } -} - -func (cs *ConsensusState) decideProposal(height, round int) { - var block *types.Block - var blockParts *types.PartSet - - // Decide on block - if cs.LockedBlock != nil { - // If we're locked onto a block, just choose that. - block, blockParts = cs.LockedBlock, cs.LockedBlockParts - } else { - // Create a new proposal block from state/txs from the mempool. - block, blockParts = cs.createProposalBlock() - if block == nil { // on error - return - } - } - - // Make proposal - proposal := types.NewProposal(height, round, blockParts.Header(), cs.Votes.POLRound()) - err := cs.privValidator.SignProposal(cs.state.ChainID, proposal) - if err == nil { - log.Notice("Signed and set proposal", "height", height, "round", round, "proposal", proposal) - log.Debug(Fmt("Signed and set proposal block: %v", block)) - // Set fields - cs.Proposal = proposal - cs.ProposalBlock = block - cs.ProposalBlockParts = blockParts - } else { - log.Warn("EnterPropose: Error signing proposal", "height", height, "round", round, "error", err) - } - -} - -// Returns true if the proposal block is complete && -// (if POLRound was proposed, we have +2/3 prevotes from there). -func (cs *ConsensusState) isProposalComplete() bool { - if cs.Proposal == nil || cs.ProposalBlock == nil { - return false - } - // we have the proposal. if there's a POLRound, - // make sure we have the prevotes from it too - if cs.Proposal.POLRound < 0 { - return true - } else { - // if this is false the proposer is lying or we haven't received the POL yet - return cs.Votes.Prevotes(cs.Proposal.POLRound).HasTwoThirdsMajority() - } -} - -// Create the next block to propose and return it. -// Returns nil block upon error. -// NOTE: keep it side-effect free for clarity. -func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts *types.PartSet) { - var validation *types.Validation - if cs.Height == 1 { - // We're creating a proposal for the first block. - // The validation is empty, but not nil. - validation = &types.Validation{} - } else if cs.LastCommit.HasTwoThirdsMajority() { - // Make the validation from LastCommit - validation = cs.LastCommit.MakeValidation() - } else { - // This shouldn't happen. - log.Error("EnterPropose: Cannot propose anything: No validation for the previous block.") - return - } - - // Mempool run transactions and the resulting hash - txs, hash, err := cs.mempool.Reap() - if err != nil { - log.Warn("createProposalBlock: Error getting proposal txs", "error", err) - return nil, nil - } - - block = &types.Block{ - Header: &types.Header{ - ChainID: cs.state.ChainID, - Height: cs.Height, - Time: time.Now(), - Fees: 0, // TODO fees - NumTxs: len(txs), - LastBlockHash: cs.state.LastBlockHash, - LastBlockParts: cs.state.LastBlockParts, - ValidatorsHash: cs.state.Validators.Hash(), - AppHash: hash, - }, - LastValidation: validation, - Data: &types.Data{ - Txs: txs, - }, - } - block.FillHeader() - blockParts = block.MakePartSet() - - return block, blockParts -} - -// Enter: `timeoutPropose` after entering Propose. -// Enter: proposal block and POL is ready. -// Enter: any +2/3 prevotes for future round. -// Prevote for LockedBlock if we're locked, or ProposalBlock if valid. -// Otherwise vote nil. -func (cs *ConsensusState) EnterPrevote(height int, round int, timedOut bool) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPrevote <= cs.Step) { - log.Debug(Fmt("EnterPrevote(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - - // fire event for how we got here - if timedOut { - cs.evsw.FireEvent(types.EventStringTimeoutPropose(), cs.RoundStateEvent()) - } else if cs.isProposalComplete() { - cs.evsw.FireEvent(types.EventStringCompleteProposal(), cs.RoundStateEvent()) - } else { - // we received +2/3 prevotes for a future round - // TODO: catchup event? - } - - log.Info(Fmt("EnterPrevote(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Sign and broadcast vote as necessary - cs.doPrevote(height, round) - - // Done EnterPrevote: - cs.Round = round - cs.Step = RoundStepPrevote - cs.newStepCh <- cs.getRoundState() - - // Once `addVote` hits any +2/3 prevotes, we will go to PrevoteWait - // (so we have more time to try and collect +2/3 prevotes for a single block) -} - -func (cs *ConsensusState) doPrevote(height int, round int) { - // If a block is locked, prevote that. - if cs.LockedBlock != nil { - log.Info("EnterPrevote: Block was locked") - cs.signAddVote(types.VoteTypePrevote, cs.LockedBlock.Hash(), cs.LockedBlockParts.Header()) - return - } - - // If ProposalBlock is nil, prevote nil. - if cs.ProposalBlock == nil { - log.Warn("EnterPrevote: ProposalBlock is nil") - cs.signAddVote(types.VoteTypePrevote, nil, types.PartSetHeader{}) - return - } - - // Try staging cs.ProposalBlock - err := cs.stageBlock(cs.ProposalBlock, cs.ProposalBlockParts) - if err != nil { - // ProposalBlock is invalid, prevote nil. - log.Warn("EnterPrevote: ProposalBlock is invalid", "error", err) - cs.signAddVote(types.VoteTypePrevote, nil, types.PartSetHeader{}) - return - } - - // Prevote cs.ProposalBlock - // NOTE: the proposal signature is validated when it is received, - // and the proposal block parts are validated as they are received (against the merkle hash in the proposal) - cs.signAddVote(types.VoteTypePrevote, cs.ProposalBlock.Hash(), cs.ProposalBlockParts.Header()) - return -} - -// Enter: any +2/3 prevotes at next round. -func (cs *ConsensusState) EnterPrevoteWait(height int, round int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPrevoteWait <= cs.Step) { - log.Debug(Fmt("EnterPrevoteWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - if !cs.Votes.Prevotes(round).HasTwoThirdsAny() { - PanicSanity(Fmt("EnterPrevoteWait(%v/%v), but Prevotes does not have any +2/3 votes", height, round)) - } - log.Info(Fmt("EnterPrevoteWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Done EnterPrevoteWait: - cs.Round = round - cs.Step = RoundStepPrevoteWait - cs.newStepCh <- cs.getRoundState() - - // After `timeoutPrevote0+timeoutPrevoteDelta*round`, EnterPrecommit() - go func() { - time.Sleep(timeoutPrevote0 + timeoutPrevoteDelta*time.Duration(round)) - cs.EnterPrecommit(height, round, true) - }() -} - -// Enter: +2/3 precomits for block or nil. -// Enter: `timeoutPrevote` after any +2/3 prevotes. -// Enter: any +2/3 precommits for next round. -// Lock & precommit the ProposalBlock if we have enough prevotes for it (a POL in this round) -// else, unlock an existing lock and precommit nil if +2/3 of prevotes were nil, -// else, precommit nil otherwise. -func (cs *ConsensusState) EnterPrecommit(height int, round int, timedOut bool) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPrecommit <= cs.Step) { - log.Debug(Fmt("EnterPrecommit(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - - if timedOut { - cs.evsw.FireEvent(types.EventStringTimeoutWait(), cs.RoundStateEvent()) - } - - log.Info(Fmt("EnterPrecommit(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done EnterPrecommit: - cs.Round = round - cs.Step = RoundStepPrecommit - cs.newStepCh <- cs.getRoundState() - }() - - hash, partsHeader, ok := cs.Votes.Prevotes(round).TwoThirdsMajority() - - // If we don't have a polka, we must precommit nil - if !ok { - if cs.LockedBlock != nil { - log.Info("EnterPrecommit: No +2/3 prevotes during EnterPrecommit while we're locked. Precommitting nil") - } else { - log.Info("EnterPrecommit: No +2/3 prevotes during EnterPrecommit. Precommitting nil.") - } - cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) - return - } - - // At this point +2/3 prevoted for a particular block or nil - cs.evsw.FireEvent(types.EventStringPolka(), cs.RoundStateEvent()) - - // the latest POLRound should be this round - if cs.Votes.POLRound() < round { - PanicSanity(Fmt("This POLRound should be %v but got %", round, cs.Votes.POLRound())) - } - - // +2/3 prevoted nil. Unlock and precommit nil. - if len(hash) == 0 { - if cs.LockedBlock == nil { - log.Info("EnterPrecommit: +2/3 prevoted for nil.") - } else { - log.Info("EnterPrecommit: +2/3 prevoted for nil. Unlocking") - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - cs.evsw.FireEvent(types.EventStringUnlock(), cs.RoundStateEvent()) - } - cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) - return - } - - // At this point, +2/3 prevoted for a particular block. - - // If we're already locked on that block, precommit it, and update the LockedRound - if cs.LockedBlock.HashesTo(hash) { - log.Info("EnterPrecommit: +2/3 prevoted locked block. Relocking") - cs.LockedRound = round - cs.evsw.FireEvent(types.EventStringRelock(), cs.RoundStateEvent()) - cs.signAddVote(types.VoteTypePrecommit, hash, partsHeader) - return - } - - // If +2/3 prevoted for proposal block, stage and precommit it - if cs.ProposalBlock.HashesTo(hash) { - log.Info("EnterPrecommit: +2/3 prevoted proposal block. Locking", "hash", hash) - // Validate the block. - if err := cs.stageBlock(cs.ProposalBlock, cs.ProposalBlockParts); err != nil { - PanicConsensus(Fmt("EnterPrecommit: +2/3 prevoted for an invalid block: %v", err)) - } - cs.LockedRound = round - cs.LockedBlock = cs.ProposalBlock - cs.LockedBlockParts = cs.ProposalBlockParts - cs.evsw.FireEvent(types.EventStringLock(), cs.RoundStateEvent()) - cs.signAddVote(types.VoteTypePrecommit, hash, partsHeader) - return - } - - // There was a polka in this round for a block we don't have. - // Fetch that block, unlock, and precommit nil. - // The +2/3 prevotes for this round is the POL for our unlock. - // TODO: In the future save the POL prevotes for justification. - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - if !cs.ProposalBlockParts.HasHeader(partsHeader) { - cs.ProposalBlock = nil - cs.ProposalBlockParts = types.NewPartSetFromHeader(partsHeader) - } - cs.evsw.FireEvent(types.EventStringUnlock(), cs.RoundStateEvent()) - cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) - return -} - -// Enter: any +2/3 precommits for next round. -func (cs *ConsensusState) EnterPrecommitWait(height int, round int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || round < cs.Round || (cs.Round == round && RoundStepPrecommitWait <= cs.Step) { - log.Debug(Fmt("EnterPrecommitWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - return - } - if !cs.Votes.Precommits(round).HasTwoThirdsAny() { - PanicSanity(Fmt("EnterPrecommitWait(%v/%v), but Precommits does not have any +2/3 votes", height, round)) - } - log.Info(Fmt("EnterPrecommitWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) - - // Done EnterPrecommitWait: - cs.Round = round - cs.Step = RoundStepPrecommitWait - cs.newStepCh <- cs.getRoundState() - - // After `timeoutPrecommit0+timeoutPrecommitDelta*round`, EnterNewRound() - go func() { - time.Sleep(timeoutPrecommit0 + timeoutPrecommitDelta*time.Duration(round)) - // If we have +2/3 of precommits for a particular block (or nil), - // we already entered commit (or the next round). - // So just try to transition to the next round, - // which is what we'd do otherwise. - cs.EnterNewRound(height, round+1, true) - }() -} - -// Enter: +2/3 precommits for block -func (cs *ConsensusState) EnterCommit(height int, commitRound int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - if cs.Height != height || RoundStepCommit <= cs.Step { - log.Debug(Fmt("EnterCommit(%v/%v): Invalid args. Current step: %v/%v/%v", height, commitRound, cs.Height, cs.Round, cs.Step)) - return - } - log.Info(Fmt("EnterCommit(%v/%v). Current: %v/%v/%v", height, commitRound, cs.Height, cs.Round, cs.Step)) - - defer func() { - // Done Entercommit: - // keep ca.Round the same, it points to the right Precommits set. - cs.Step = RoundStepCommit - cs.CommitRound = commitRound - cs.newStepCh <- cs.getRoundState() - - // Maybe finalize immediately. - cs.tryFinalizeCommit(height) - }() - - hash, partsHeader, ok := cs.Votes.Precommits(commitRound).TwoThirdsMajority() - if !ok { - PanicSanity("RunActionCommit() expects +2/3 precommits") - } - - // The Locked* fields no longer matter. - // Move them over to ProposalBlock if they match the commit hash, - // otherwise they'll be cleared in updateToState. - if cs.LockedBlock.HashesTo(hash) { - cs.ProposalBlock = cs.LockedBlock - cs.ProposalBlockParts = cs.LockedBlockParts - } - - // If we don't have the block being committed, set up to get it. - if !cs.ProposalBlock.HashesTo(hash) { - if !cs.ProposalBlockParts.HasHeader(partsHeader) { - // We're getting the wrong block. - // Set up ProposalBlockParts and keep waiting. - cs.ProposalBlock = nil - cs.ProposalBlockParts = types.NewPartSetFromHeader(partsHeader) - } else { - // We just need to keep waiting. - } - } -} - -// If we have the block AND +2/3 commits for it, finalize. -func (cs *ConsensusState) tryFinalizeCommit(height int) { - if cs.Height != height { - PanicSanity(Fmt("tryFinalizeCommit() cs.Height: %v vs height: %v", cs.Height, height)) - } - - hash, _, ok := cs.Votes.Precommits(cs.CommitRound).TwoThirdsMajority() - if !ok || len(hash) == 0 { - log.Warn("Attempt to finalize failed. There was no +2/3 majority, or +2/3 was for <nil>.") - return - } - if !cs.ProposalBlock.HashesTo(hash) { - log.Warn("Attempt to finalize failed. We don't have the commit block.") - return - } - go cs.FinalizeCommit(height) -} - -// Increment height and goto RoundStepNewHeight -func (cs *ConsensusState) FinalizeCommit(height int) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - if cs.Height != height || cs.Step != RoundStepCommit { - log.Debug(Fmt("FinalizeCommit(%v): Invalid args. Current step: %v/%v/%v", height, cs.Height, cs.Round, cs.Step)) - return - } - - hash, header, ok := cs.Votes.Precommits(cs.CommitRound).TwoThirdsMajority() - - if !ok { - PanicSanity(Fmt("Cannot FinalizeCommit, commit does not have two thirds majority")) - } - if !cs.ProposalBlockParts.HasHeader(header) { - PanicSanity(Fmt("Expected ProposalBlockParts header to be commit header")) - } - if !cs.ProposalBlock.HashesTo(hash) { - PanicSanity(Fmt("Cannot FinalizeCommit, ProposalBlock does not hash to commit hash")) - } - if err := cs.stageBlock(cs.ProposalBlock, cs.ProposalBlockParts); err != nil { - PanicConsensus(Fmt("+2/3 committed an invalid block: %v", err)) - } - - log.Info(Fmt("Finalizing commit of block: %v", cs.ProposalBlock)) - // We have the block, so stage/save/commit-vote. - cs.saveBlock(cs.ProposalBlock, cs.ProposalBlockParts, cs.Votes.Precommits(cs.CommitRound)) - // Increment height. - cs.updateToState(cs.stagedState) - // cs.StartTime is already set. - // Schedule Round0 to start soon. - go cs.scheduleRound0(height + 1) - - // By here, - // * cs.Height has been increment to height+1 - // * cs.Step is now RoundStepNewHeight - // * cs.StartTime is set to when we will start round0. - return -} - -//----------------------------------------------------------------------------- - -func (cs *ConsensusState) SetProposal(proposal *types.Proposal) error { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - // Already have one - if cs.Proposal != nil { - return nil - } - - // Does not apply - if proposal.Height != cs.Height || proposal.Round != cs.Round { - return nil - } - - // We don't care about the proposal if we're already in RoundStepCommit. - if RoundStepCommit <= cs.Step { - return nil - } - - // Verify POLRound, which must be -1 or between 0 and proposal.Round exclusive. - if proposal.POLRound != -1 && - (proposal.POLRound < 0 || proposal.Round <= proposal.POLRound) { - return ErrInvalidProposalPOLRound - } - - // Verify signature - if !cs.Validators.Proposer().PubKey.VerifyBytes(types.SignBytes(cs.state.ChainID, proposal), proposal.Signature) { - return ErrInvalidProposalSignature - } - - cs.Proposal = proposal - cs.ProposalBlockParts = types.NewPartSetFromHeader(proposal.BlockPartsHeader) - return nil -} - -// NOTE: block is not necessarily valid. -// This can trigger us to go into EnterPrevote asynchronously (before we timeout of propose) or to attempt to commit -func (cs *ConsensusState) AddProposalBlockPart(height int, part *types.Part) (added bool, err error) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - // Blocks might be reused, so round mismatch is OK - if cs.Height != height { - return false, nil - } - - // We're not expecting a block part. - if cs.ProposalBlockParts == nil { - return false, nil // TODO: bad peer? Return error? - } - - added, err = cs.ProposalBlockParts.AddPart(part) - if err != nil { - return added, err - } - if added && cs.ProposalBlockParts.IsComplete() { - // Added and completed! - var n int - var err error - cs.ProposalBlock = wire.ReadBinary(&types.Block{}, cs.ProposalBlockParts.GetReader(), types.MaxBlockSize, &n, &err).(*types.Block) - log.Info("Received complete proposal", "hash", cs.ProposalBlock.Hash()) - if cs.Step == RoundStepPropose && cs.isProposalComplete() { - // Move onto the next step - go cs.EnterPrevote(height, cs.Round, false) - } else if cs.Step == RoundStepCommit { - // If we're waiting on the proposal block... - cs.tryFinalizeCommit(height) - } - return true, err - } - return added, nil -} - -// Attempt to add the vote. if its a duplicate signature, dupeout the validator -func (cs *ConsensusState) TryAddVote(valIndex int, vote *types.Vote, peerKey string) (bool, error) { - added, _, err := cs.AddVote(valIndex, vote, peerKey) - if err != nil { - // If the vote height is off, we'll just ignore it, - // But if it's a conflicting sig, broadcast evidence tx for slashing. - // If it's otherwise invalid, punish peer. - if err == ErrVoteHeightMismatch { - return added, err - } else if _, ok := err.(*types.ErrVoteConflictingSignature); ok { - log.Warn("Found conflicting vote. Publish evidence") - /* TODO - evidenceTx := &types.DupeoutTx{ - Address: address, - VoteA: *errDupe.VoteA, - VoteB: *errDupe.VoteB, - } - cs.mempool.BroadcastTx(evidenceTx) // shouldn't need to check returned err - */ - return added, err - } else { - // Probably an invalid signature. Bad peer. - log.Warn("Error attempting to add vote", "error", err) - return added, ErrAddingVote - } - } - return added, nil -} - -func (cs *ConsensusState) AddVote(valIndex int, vote *types.Vote, peerKey string) (added bool, address []byte, err error) { - cs.mtx.Lock() - defer cs.mtx.Unlock() - - return cs.addVote(valIndex, vote, peerKey) -} - -//----------------------------------------------------------------------------- - -func (cs *ConsensusState) addVote(valIndex int, vote *types.Vote, peerKey string) (added bool, address []byte, err error) { - log.Debug("addVote", "voteHeight", vote.Height, "voteType", vote.Type, "csHeight", cs.Height) - - defer func() { - if added { - cs.evsw.FireEvent(types.EventStringVote(), &types.EventDataVote{valIndex, address, vote}) - } - }() - - // A precommit for the previous height? - if vote.Height+1 == cs.Height { - if !(cs.Step == RoundStepNewHeight && vote.Type == types.VoteTypePrecommit) { - // TODO: give the reason .. - // fmt.Errorf("TryAddVote: Wrong height, not a LastCommit straggler commit.") - return added, nil, ErrVoteHeightMismatch - } - added, address, err = cs.LastCommit.AddByIndex(valIndex, vote) - if added { - log.Info(Fmt("Added to lastPrecommits: %v", cs.LastCommit.StringShort())) - } - return - } - - // A prevote/precommit for this height? - if vote.Height == cs.Height { - height := cs.Height - added, address, err = cs.Votes.AddByIndex(valIndex, vote, peerKey) - if added { - switch vote.Type { - case types.VoteTypePrevote: - prevotes := cs.Votes.Prevotes(vote.Round) - log.Info("Added to prevote", "vote", vote, "prevotes", prevotes.StringShort()) - // First, unlock if prevotes is a valid POL. - // >> lockRound < POLRound <= unlockOrChangeLockRound (see spec) - // NOTE: If (lockRound < POLRound) but !(POLRound <= unlockOrChangeLockRound), - // we'll still EnterNewRound(H,vote.R) and EnterPrecommit(H,vote.R) to process it - // there. - if (cs.LockedBlock != nil) && (cs.LockedRound < vote.Round) && (vote.Round <= cs.Round) { - hash, _, ok := prevotes.TwoThirdsMajority() - if ok && !cs.LockedBlock.HashesTo(hash) { - log.Notice("Unlocking because of POL.", "lockedRound", cs.LockedRound, "POLRound", vote.Round) - cs.LockedRound = 0 - cs.LockedBlock = nil - cs.LockedBlockParts = nil - cs.evsw.FireEvent(types.EventStringUnlock(), cs.RoundStateEvent()) - } - } - if cs.Round <= vote.Round && prevotes.HasTwoThirdsAny() { - // Round-skip over to PrevoteWait or goto Precommit. - go func() { - cs.EnterNewRound(height, vote.Round, false) - if prevotes.HasTwoThirdsMajority() { - cs.EnterPrecommit(height, vote.Round, false) - } else { - cs.EnterPrevote(height, vote.Round, false) - cs.EnterPrevoteWait(height, vote.Round) - } - }() - } else if cs.Proposal != nil && 0 <= cs.Proposal.POLRound && cs.Proposal.POLRound == vote.Round { - // If the proposal is now complete, enter prevote of cs.Round. - if cs.isProposalComplete() { - go cs.EnterPrevote(height, cs.Round, false) - } - } - case types.VoteTypePrecommit: - precommits := cs.Votes.Precommits(vote.Round) - log.Info("Added to precommit", "vote", vote, "precommits", precommits.StringShort()) - hash, _, ok := precommits.TwoThirdsMajority() - if ok { - go func() { - if len(hash) == 0 { - cs.EnterNewRound(height, vote.Round+1, false) - } else { - cs.EnterNewRound(height, vote.Round, false) - cs.EnterPrecommit(height, vote.Round, false) - cs.EnterCommit(height, vote.Round) - } - }() - } else if cs.Round <= vote.Round && precommits.HasTwoThirdsAny() { - go func() { - cs.EnterNewRound(height, vote.Round, false) - cs.EnterPrecommit(height, vote.Round, false) - cs.EnterPrecommitWait(height, vote.Round) - }() - } - default: - PanicSanity(Fmt("Unexpected vote type %X", vote.Type)) // Should not happen. - } - } - // Either duplicate, or error upon cs.Votes.AddByIndex() - return - } else { - err = ErrVoteHeightMismatch - } - - // Height mismatch, bad peer? - log.Info("Vote ignored and not added", "voteHeight", vote.Height, "csHeight", cs.Height) - return -} - -func (cs *ConsensusState) stageBlock(block *types.Block, blockParts *types.PartSet) error { - if block == nil { - PanicSanity("Cannot stage nil block") - } - - // Already staged? - blockHash := block.Hash() - if cs.stagedBlock != nil && len(blockHash) != 0 && bytes.Equal(cs.stagedBlock.Hash(), blockHash) { - return nil - } - - // Create a new event cache to cache all events. - cs.evc = events.NewEventCache(cs.evsw) - - // Create a copy of the state for staging - stateCopy := cs.state.Copy() - stateCopy.SetFireable(cs.evc) - - // Run the block on the State: - // + update validator sets - // + first rolls back proxyAppCtx - // + run txs on the proxyAppCtx or rollback - err := stateCopy.ExecBlock(cs.proxyAppCtx, block, blockParts.Header()) - if err != nil { - return err - } - - // Everything looks good! - cs.stagedBlock = block - cs.stagedState = stateCopy - return nil -} - -func (cs *ConsensusState) signVote(type_ byte, hash []byte, header types.PartSetHeader) (*types.Vote, error) { - vote := &types.Vote{ - Height: cs.Height, - Round: cs.Round, - Type: type_, - BlockHash: hash, - BlockPartsHeader: header, - } - err := cs.privValidator.SignVote(cs.state.ChainID, vote) - return vote, err -} - -func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.PartSetHeader) *types.Vote { - if cs.privValidator == nil || !cs.Validators.HasAddress(cs.privValidator.Address) { - return nil - } - vote, err := cs.signVote(type_, hash, header) - if err == nil { - // NOTE: store our index in the cs so we don't have to do this every time - valIndex, _ := cs.Validators.GetByAddress(cs.privValidator.Address) - _, _, err := cs.addVote(valIndex, vote, "") - log.Notice("Signed and added vote", "height", cs.Height, "round", cs.Round, "vote", vote, "error", err) - return vote - } else { - log.Warn("Error signing vote", "height", cs.Height, "round", cs.Round, "vote", vote, "error", err) - return nil - } -} - -// Save Block, save the +2/3 Commits we've seen -func (cs *ConsensusState) saveBlock(block *types.Block, blockParts *types.PartSet, commits *types.VoteSet) { - - // The proposal must be valid. - if err := cs.stageBlock(block, blockParts); err != nil { - PanicSanity(Fmt("saveBlock() an invalid block: %v", err)) - } - - // Save to blockStore. - if cs.blockStore.Height() < block.Height { - seenValidation := commits.MakeValidation() - cs.blockStore.SaveBlock(block, blockParts, seenValidation) - } - - // Commit to proxyAppCtx - err := cs.stagedState.Commit(cs.proxyAppCtx) - if err != nil { - // TODO: handle this gracefully. - PanicQ(Fmt("Commit failed for applicaiton")) - } - - // Save the state. - cs.stagedState.Save() - - // Update mempool. - cs.mempool.Update(block) - - // Fire off event - if cs.evsw != nil && cs.evc != nil { - cs.evsw.FireEvent(types.EventStringNewBlock(), types.EventDataNewBlock{block}) - go cs.evc.Flush() - } - -} - -// implements events.Eventable -func (cs *ConsensusState) SetFireable(evsw events.Fireable) { - cs.evsw = evsw -} - -func (cs *ConsensusState) String() string { - return Fmt("ConsensusState(H:%v R:%v S:%v", cs.Height, cs.Round, cs.Step) -} - -func CompareHRS(h1, r1 int, s1 RoundStepType, h2, r2 int, s2 RoundStepType) int { - if h1 < h2 { - return -1 - } else if h1 > h2 { - return 1 - } - if r1 < r2 { - return -1 - } else if r1 > r2 { - return 1 - } - if s1 < s2 { - return -1 - } else if s1 > s2 { - return 1 - } - return 0 -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state_test.go deleted file mode 100644 index 7ec75bb1ac94ef4667c166316e58cedcac38ecd9..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus/state_test.go +++ /dev/null @@ -1,1186 +0,0 @@ -package consensus - -import ( - "bytes" - "fmt" - "testing" - "time" - - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - //"github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -/* - -ProposeSuite -x * TestProposerSelection0 - round robin ordering, round 0 -x * TestProposerSelection2 - round robin ordering, round 2++ -x * TestEnterProposeNoValidator - timeout into prevote round -x * TestEnterPropose - finish propose without timing out (we have the proposal) -x * TestBadProposal - 2 vals, bad proposal (bad block state hash), should prevote and precommit nil -FullRoundSuite -x * TestFullRound1 - 1 val, full successful round -x * TestFullRoundNil - 1 val, full round of nil -x * TestFullRound2 - 2 vals, both required for fuill round -LockSuite -x * TestLockNoPOL - 2 vals, 4 rounds. one val locked, precommits nil every round except first. -x * TestLockPOLRelock - 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka -x * TestLockPOLUnlock - 4 vals, one precommits, other 3 polka nil at next round, so we unlock and precomit nil -x * TestLockPOLSafety1 - 4 vals. We shouldn't change lock based on polka at earlier round -x * TestLockPOLSafety2 - 4 vals. After unlocking, we shouldn't relock based on polka at earlier round - * TestNetworkLock - once +1/3 precommits, network should be locked - * TestNetworkLockPOL - once +1/3 precommits, the block with more recent polka is committed -SlashingSuite -x * TestSlashingPrevotes - a validator prevoting twice in a round gets slashed -x * TestSlashingPrecommits - a validator precomitting twice in a round gets slashed -CatchupSuite - * TestCatchup - if we might be behind and we've seen any 2/3 prevotes, round skip to new round, precommit, or prevote -HaltSuite -x * TestHalt1 - if we see +2/3 precommits after timing out into new round, we should still commit - -*/ - -//---------------------------------------------------------------------------------------------------- -// ProposeSuite - -func init() { - fmt.Println("") - timeoutPropose = 500 * time.Millisecond -} - -func TestProposerSelection0(t *testing.T) { - cs1, vss := simpleConsensusState(3) // test needs more work for more than 3 validators - cs1.newStepCh = make(chan *RoundState) // so it blocks - height, round := cs1.Height, cs1.Round - - cs1.EnterNewRound(height, round, false) - - // lets commit a block and ensure proposer for the next height is correct - prop := cs1.Validators.Proposer() - if !bytes.Equal(prop.Address, cs1.privValidator.Address) { - t.Fatalf("expected proposer to be validator %d. Got %X", 0, prop.Address) - } - - waitFor(t, cs1, height, round, RoundStepPrevote) - - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vss[1:]...) - - waitFor(t, cs1, height, round, RoundStepPrecommit) - - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vss[1:]...) - - waitFor(t, cs1, height, round, RoundStepPrecommit) - waitFor(t, cs1, height, round+1, RoundStepPropose) - - prop = cs1.Validators.Proposer() - if !bytes.Equal(prop.Address, vss[1].Address) { - t.Fatalf("expected proposer to be validator %d. Got %X", 1, prop.Address) - } -} - -// Now let's do it all again, but starting from round 2 instead of 0 -func TestProposerSelection2(t *testing.T) { - cs1, vss := simpleConsensusState(3) // test needs more work for more than 3 validators - cs1.newStepCh = make(chan *RoundState) // so it blocks - - // this time we jump in at round 2 - incrementRound(vss[1:]...) - incrementRound(vss[1:]...) - cs1.EnterNewRound(cs1.Height, 2, false) - - // everyone just votes nil. we get a new proposer each round - for i := 0; i < len(vss); i++ { - prop := cs1.Validators.Proposer() - if !bytes.Equal(prop.Address, vss[(i+2)%len(vss)].Address) { - t.Fatalf("expected proposer to be validator %d. Got %X", (i+2)%len(vss), prop.Address) - } - nilRound(t, 2, cs1, vss[1:]...) - incrementRound(vss[1:]...) - } - -} - -// a non-validator should timeout into the prevote round -func TestEnterProposeNoPrivValidator(t *testing.T) { - cs, _ := simpleConsensusState(1) - cs.SetPrivValidator(nil) - height, round := cs.Height, cs.Round - - // Listen for propose timeout event - timeoutEventReceived := false - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutEventReceived = true - }) - cs.SetFireable(evsw) - - // starts a go routine for EnterPropose - cs.EnterNewRound(height, round, false) - - // Wait until the prevote step - waitFor(t, cs, height, round, RoundStepPrevote) - - // if we're not a validator, EnterPropose should timeout - if timeoutEventReceived == false { - t.Fatal("Expected EnterPropose to timeout") - } - if cs.GetRoundState().Proposal != nil { - t.Error("Expected to make no proposal, since no privValidator") - } -} - -// a validator should not timeout of the prevote round (TODO: unless the block is really big!) -func TestEnterPropose(t *testing.T) { - cs, _ := simpleConsensusState(1) - height, round := cs.Height, cs.Round - - // Listen for propose timeout event - timeoutEventReceived := false - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutEventReceived = true - }) - cs.SetFireable(evsw) - - // starts a go routine for EnterPropose - cs.EnterNewRound(height, round, false) - - // Wait until the prevote step - waitFor(t, cs, height, round, RoundStepPrevote) - - // Check that Proposal, ProposalBlock, ProposalBlockParts are set. - rs := cs.GetRoundState() - if rs.Proposal == nil { - t.Error("rs.Proposal should be set") - } - if rs.ProposalBlock == nil { - t.Error("rs.ProposalBlock should be set") - } - if rs.ProposalBlockParts.Total() == 0 { - t.Error("rs.ProposalBlockParts should be set") - } - - // if we're not a validator, EnterPropose should timeout - if timeoutEventReceived == true { - t.Fatal("Expected EnterPropose not to timeout") - } -} - -func TestBadProposal(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs1.newStepCh = make(chan *RoundState) // so it blocks - height, round := cs1.Height, cs1.Round - cs2 := vss[1] - - timeoutChan := make(chan struct{}) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - cs1.SetFireable(evsw) - - // make the second validator the proposer - propBlock := changeProposer(t, cs1, cs2) - - // make the block bad by tampering with statehash - stateHash := propBlock.AppHash - if len(stateHash) == 0 { - stateHash = make([]byte, 32) - } - stateHash[0] = byte((stateHash[0] + 1) % 255) - propBlock.AppHash = stateHash - propBlockParts := propBlock.MakePartSet() - proposal := types.NewProposal(cs2.Height, cs2.Round, propBlockParts.Header(), -1) - if err := cs2.SignProposal(chainID, proposal); err != nil { - t.Fatal("failed to sign bad proposal", err) - } - - // start round - cs1.EnterNewRound(height, round, false) - - // now we're on a new round and not the proposer - waitFor(t, cs1, height, round, RoundStepPropose) - // so set the proposal block (and fix voting power) - cs1.mtx.Lock() - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = proposal, propBlock, propBlockParts - fixVotingPower(t, cs1, vss[1].Address) - cs1.mtx.Unlock() - // and wait for timeout - <-timeoutChan - - // go to prevote, prevote for nil (proposal is bad) - waitFor(t, cs1, height, round, RoundStepPrevote) - - validatePrevote(t, cs1, round, vss[0], nil) - - // add bad prevote from cs2. we should precommit nil - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header()) - - waitFor(t, cs1, height, round, RoundStepPrevoteWait) - <-timeoutChan - waitFor(t, cs1, height, round, RoundStepPrecommit) - - validatePrecommit(t, cs1, round, 0, vss[0], nil, nil) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header()) -} - -//---------------------------------------------------------------------------------------------------- -// FullRoundSuite - -// propose, prevote, and precommit a block -func TestFullRound1(t *testing.T) { - cs, vss := simpleConsensusState(1) - height, round := cs.Height, cs.Round - - // starts a go routine for EnterPropose - cs.EnterNewRound(height, round, false) - - // wait to finish propose and prevote - waitFor(t, cs, height, round, RoundStepPrevote) - - // we should now be in precommit - // verify our prevote is there - cs.mtx.Lock() - propBlockHash := cs.ProposalBlock.Hash() - cs.mtx.Unlock() - - // Wait until Precommit - waitFor(t, cs, height, round, RoundStepPrecommit) - - // the proposed block should be prevoted, precommitted, and locked - validatePrevoteAndPrecommit(t, cs, round, round, vss[0], propBlockHash, propBlockHash) -} - -// nil is proposed, so prevote and precommit nil -func TestFullRoundNil(t *testing.T) { - cs, vss := simpleConsensusState(1) - height, round := cs.Height, cs.Round - - // Skip the propose step - cs.EnterPrevote(height, round, true) - - // Wait until Precommit - waitFor(t, cs, height, round, RoundStepPrecommit) - - // should prevote and precommit nil - validatePrevoteAndPrecommit(t, cs, round, 0, vss[0], nil, nil) -} - -// run through propose, prevote, precommit commit with two validators -// where the first validator has to wait for votes from the second -func TestFullRound2(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs2 := vss[1] - cs1.newStepCh = make(chan *RoundState) // so it blocks - height, round := cs1.Height, cs1.Round - - // start round and wait for propose and prevote - cs1.EnterNewRound(height, round, false) - waitFor(t, cs1, height, round, RoundStepPrevote) - - // we should now be stuck in limbo forever, waiting for more prevotes - ensureNoNewStep(t, cs1) - - propBlockHash, propPartsHeader := cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header() - - // prevote arrives from cs2: - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, propBlockHash, propPartsHeader) - - // wait to finish precommit - waitFor(t, cs1, cs1.Height, 0, RoundStepPrecommit) - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], propBlockHash, propBlockHash) - - // we should now be stuck in limbo forever, waiting for more precommits - ensureNoNewStep(t, cs1) - - // precommit arrives from cs2: - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, propBlockHash, propPartsHeader) - - // wait to finish commit, propose in next height - waitFor(t, cs1, height+1, 0, RoundStepNewHeight) -} - -//------------------------------------------------------------------------------------------ -// LockSuite - -// two validators, 4 rounds. -// val1 proposes the first 2 rounds, and is locked in the first. -// val2 proposes the next two. val1 should precommit nil on all (except first where he locks) -func TestLockNoPOL(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs2 := vss[1] - cs1.newStepCh = make(chan *RoundState) // so it blocks - height := cs1.Height - - timeoutChan := make(chan struct{}) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - cs1.SetFireable(evsw) - - /* - Round1 (cs1, B) // B B // B B2 - */ - - // start round and wait for propose and prevote - cs1.EnterNewRound(height, 0, false) - waitFor(t, cs1, height, 0, RoundStepPrevote) - - // we should now be stuck in limbo forever, waiting for more prevotes - // prevote arrives from cs2: - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - - cs1.mtx.Lock() // XXX: sigh - theBlockHash := cs1.ProposalBlock.Hash() - cs1.mtx.Unlock() - - // wait to finish precommit - waitFor(t, cs1, height, 0, RoundStepPrecommit) - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - // we should now be stuck in limbo forever, waiting for more precommits - // lets add one for a different block - // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round - hash := cs1.ProposalBlock.Hash() - hash[0] = byte((hash[0] + 1) % 255) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // (note we're entering precommit for a second time this round) - // but with invalid args. then we EnterPrecommitWait, and the timeout to new round - waitFor(t, cs1, height, 0, RoundStepPrecommitWait) - <-timeoutChan - - log.Info("#### ONTO ROUND 2") - /* - Round2 (cs1, B) // B B2 - */ - - incrementRound(cs2) - - // now we're on a new round and not the proposer, so wait for timeout - waitFor(t, cs1, height, 1, RoundStepPropose) - <-timeoutChan - - if cs1.ProposalBlock != nil { - t.Fatal("Expected proposal block to be nil") - } - - // wait to finish prevote - waitFor(t, cs1, height, 1, RoundStepPrevote) - - // we should have prevoted our locked block - validatePrevote(t, cs1, 1, vss[0], cs1.LockedBlock.Hash()) - - // add a conflicting prevote from the other validator - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // now we're going to enter prevote again, but with invalid args - // and then prevote wait, which should timeout. then wait for precommit - waitFor(t, cs1, height, 1, RoundStepPrevoteWait) - <-timeoutChan - waitFor(t, cs1, height, 1, RoundStepPrecommit) - - // the proposed block should still be locked and our precommit added - // we should precommit nil and be locked on the proposal - validatePrecommit(t, cs1, 1, 0, vss[0], nil, theBlockHash) - - // add conflicting precommit from cs2 - // NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // (note we're entering precommit for a second time this round, but with invalid args - // then we EnterPrecommitWait and timeout into NewRound - waitFor(t, cs1, height, 1, RoundStepPrecommitWait) - <-timeoutChan - - log.Info("#### ONTO ROUND 3") - /* - Round3 (cs2, _) // B, B2 - */ - - incrementRound(cs2) - - waitFor(t, cs1, height, 2, RoundStepPropose) - - // now we're on a new round and are the proposer - if cs1.ProposalBlock != cs1.LockedBlock { - t.Fatalf("Expected proposal block to be locked block. Got %v, Expected %v", cs1.ProposalBlock, cs1.LockedBlock) - } - - // go to prevote, prevote for locked block - waitFor(t, cs1, height, 2, RoundStepPrevote) - - validatePrevote(t, cs1, 0, vss[0], cs1.LockedBlock.Hash()) - - // TODO: quick fastforward to new round, set proposer - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - waitFor(t, cs1, height, 2, RoundStepPrevoteWait) - <-timeoutChan - waitFor(t, cs1, height, 2, RoundStepPrecommit) - - validatePrecommit(t, cs1, 2, 0, vss[0], nil, theBlockHash) // precommit nil but be locked on proposal - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) // NOTE: conflicting precommits at same height - - waitFor(t, cs1, height, 2, RoundStepPrecommitWait) - - // before we time out into new round, set next proposal block - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - if prop == nil || propBlock == nil { - t.Fatal("Failed to create proposal block with cs2") - } - - incrementRound(cs2) - - <-timeoutChan - - log.Info("#### ONTO ROUND 4") - /* - Round4 (cs2, C) // B C // B C - */ - - // now we're on a new round and not the proposer - waitFor(t, cs1, height, 3, RoundStepPropose) - - // so set the proposal block - cs1.mtx.Lock() - cs1.Proposal, cs1.ProposalBlock = prop, propBlock - cs1.mtx.Unlock() - - // and wait for timeout - <-timeoutChan - // go to prevote, prevote for locked block (not proposal) - waitFor(t, cs1, height, 3, RoundStepPrevote) - - validatePrevote(t, cs1, 0, vss[0], cs1.LockedBlock.Hash()) - - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header()) - - waitFor(t, cs1, height, 3, RoundStepPrevoteWait) - <-timeoutChan - waitFor(t, cs1, height, 3, RoundStepPrecommit) - - validatePrecommit(t, cs1, 2, 0, vss[0], nil, theBlockHash) // precommit nil but locked on proposal - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, propBlock.Hash(), propBlock.MakePartSet().Header()) // NOTE: conflicting precommits at same height -} - -// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka -func TestLockPOLRelock(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan *types.EventDataRoundState) - voteChan := make(chan *types.EventDataVote) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) { - vote := data.(*types.EventDataVote) - // we only fire for our own votes - if bytes.Equal(cs1.privValidator.Address, vote.Address) { - voteChan <- vote - } - }) - cs1.SetFireable(evsw) - - // everything done from perspective of cs1 - - /* - Round1 (cs1, B) // B B B B// B nil B nil - - eg. cs2 and cs4 didn't see the 2/3 prevotes - */ - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh() - - theBlockHash := cs1.ProposalBlock.Hash() - - // wait to finish precommit after prevotes done - // we do this in a go routine with another channel since otherwise - // we may get deadlock with EnterPrecommit waiting to send on newStepCh and the final - // signAddVoteToFrom waiting for the cs.mtx.Lock - donePrecommit := make(chan struct{}) - go func() { - <-voteChan - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - donePrecommitWait := make(chan struct{}) - go func() { - // (note we're entering precommit for a second time this round) - // but with invalid args. then we EnterPrecommitWait, twice (?) - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - // add precommits from the rest - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - <-donePrecommitWait - - // before we time out into new round, set next proposer - // and next proposal block - _, v1 := cs1.Validators.GetByAddress(vss[0].Address) - v1.VotingPower = 1 - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - - incrementRound(cs2, cs3, cs4) - - // timeout to new round - te := <-timeoutChan - if te.Step != RoundStepPrecommitWait.String() { - t.Fatalf("expected to timeout of precommit into new round. got %v", te.Step) - } - - log.Info("### ONTO ROUND 2") - - /* - Round2 (cs2, C) // B C C C // C C C _) - - cs1 changes lock! - */ - - // now we're on a new round and not the proposer - <-cs1.NewStepCh() - cs1.mtx.Lock() - // so set the proposal block - propBlockHash, propBlockParts := propBlock.Hash(), propBlock.MakePartSet() - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlockParts - cs1.mtx.Unlock() - // and wait for timeout - te = <-timeoutChan - if te.Step != RoundStepPropose.String() { - t.Fatalf("expected to timeout of propose. got %v", te.Step) - } - // go to prevote, prevote for locked block (not proposal), move on - _, _ = <-voteChan, <-cs1.NewStepCh() - validatePrevote(t, cs1, 0, vss[0], theBlockHash) - - donePrecommit = make(chan struct{}) - go func() { - // we need this go routine because if we go into PrevoteWait it has to pull on newStepCh - // before the final vote will get added (because it holds the mutex). - select { - case <-cs1.NewStepCh(): // we're in PrevoteWait, go to Precommit - <-voteChan - case <-voteChan: // we went straight to Precommit - } - donePrecommit <- struct{}{} - }() - // now lets add prevotes from everyone else for the new block - signAddVoteToFromMany(types.VoteTypePrevote, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // we should have unlocked and locked on the new block - validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash) - - donePrecommitWait = make(chan struct{}) - go func() { - // (note we're entering precommit for a second time this round) - // but with invalid args. then we EnterPrecommitWait, - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3) - <-donePrecommitWait - - <-cs1.NewStepCh() - rs := <-cs1.NewStepCh() - if rs.Height != 2 { - t.Fatal("Expected height to increment") - } - - if hash, _, ok := rs.LastCommit.TwoThirdsMajority(); !ok || !bytes.Equal(hash, propBlockHash) { - t.Fatal("Expected block to get committed") - } -} - -// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka -func TestLockPOLUnlock(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan *types.EventDataRoundState) - voteChan := make(chan *types.EventDataVote) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) { - vote := data.(*types.EventDataVote) - // we only fire for our own votes - if bytes.Equal(cs1.privValidator.Address, vote.Address) { - voteChan <- vote - } - }) - cs1.SetFireable(evsw) - - // everything done from perspective of cs1 - - /* - Round1 (cs1, B) // B B B B // B nil B nil - - eg. didn't see the 2/3 prevotes - */ - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh() - - theBlockHash := cs1.ProposalBlock.Hash() - - donePrecommit := make(chan struct{}) - go func() { - <-voteChan - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - donePrecommitWait := make(chan struct{}) - go func() { - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - // add precommits from the rest - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - <-donePrecommitWait - - // before we time out into new round, set next proposer - // and next proposal block - _, v1 := cs1.Validators.GetByAddress(vss[0].Address) - v1.VotingPower = 1 - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - - incrementRound(cs2, cs3, cs4) - - // timeout to new round - <-timeoutChan - - log.Info("#### ONTO ROUND 2") - /* - Round2 (cs2, C) // B nil nil nil // nil nil nil _ - - cs1 unlocks! - */ - - // now we're on a new round and not the proposer, - <-cs1.NewStepCh() - cs1.mtx.Lock() - // so set the proposal block - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlock.MakePartSet() - lockedBlockHash := cs1.LockedBlock.Hash() - cs1.mtx.Unlock() - // and wait for timeout - <-timeoutChan - - // go to prevote, prevote for locked block (not proposal) - _, _ = <-voteChan, <-cs1.NewStepCh() - validatePrevote(t, cs1, 0, vss[0], lockedBlockHash) - - donePrecommit = make(chan struct{}) - go func() { - select { - case <-cs1.NewStepCh(): // we're in PrevoteWait, go to Precommit - <-voteChan - case <-voteChan: // we went straight to Precommit - } - donePrecommit <- struct{}{} - }() - // now lets add prevotes from everyone else for the new block - signAddVoteToFromMany(types.VoteTypePrevote, cs1, nil, types.PartSetHeader{}, cs2, cs3, cs4) - <-donePrecommit - - // we should have unlocked - // NOTE: we don't lock on nil, so LockedRound is still 0 - validatePrecommit(t, cs1, 1, 0, vss[0], nil, nil) - - donePrecommitWait = make(chan struct{}) - go func() { - // the votes will bring us to new round right away - // we should timeout of it - _, _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh(), <-timeoutChan - donePrecommitWait <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3) - <-donePrecommitWait -} - -// 4 vals -// a polka at round 1 but we miss it -// then a polka at round 2 that we lock on -// then we see the polka from round 1 but shouldn't unlock -func TestLockPOLSafety1(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan *types.EventDataRoundState) - voteChan := make(chan *types.EventDataVote) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) { - vote := data.(*types.EventDataVote) - // we only fire for our own votes - if bytes.Equal(cs1.privValidator.Address, vote.Address) { - voteChan <- vote - } - }) - cs1.SetFireable(evsw) - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh() - - propBlock := cs1.ProposalBlock - - validatePrevote(t, cs1, 0, vss[0], cs1.ProposalBlock.Hash()) - - // the others sign a polka but we don't see it - prevotes := signVoteMany(types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet().Header(), cs2, cs3, cs4) - - // before we time out into new round, set next proposer - // and next proposal block - _, v1 := cs1.Validators.GetByAddress(vss[0].Address) - v1.VotingPower = 1 - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - - log.Warn("old prop", "hash", fmt.Sprintf("%X", propBlock.Hash())) - - // we do see them precommit nil - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3, cs4) - - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - - incrementRound(cs2, cs3, cs4) - - log.Info("### ONTO ROUND 2") - /*Round2 - // we timeout and prevote our lock - // a polka happened but we didn't see it! - */ - - // now we're on a new round and not the proposer, - <-cs1.NewStepCh() - // so set proposal - cs1.mtx.Lock() - propBlockHash, propBlockParts := propBlock.Hash(), propBlock.MakePartSet() - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlockParts - cs1.mtx.Unlock() - // and wait for timeout - <-timeoutChan - if cs1.LockedBlock != nil { - t.Fatal("we should not be locked!") - } - log.Warn("new prop", "hash", fmt.Sprintf("%X", propBlockHash)) - // go to prevote, prevote for proposal block - _, _ = <-voteChan, <-cs1.NewStepCh() - validatePrevote(t, cs1, 1, vss[0], propBlockHash) - - // now we see the others prevote for it, so we should lock on it - donePrecommit := make(chan struct{}) - go func() { - select { - case <-cs1.NewStepCh(): // we're in PrevoteWait, go to Precommit - <-voteChan - case <-voteChan: // we went straight to Precommit - } - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - // now lets add prevotes from everyone else for nil - signAddVoteToFromMany(types.VoteTypePrevote, cs1, propBlockHash, propBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // we should have precommitted - validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash) - - // now we see precommits for nil - donePrecommitWait := make(chan struct{}) - go func() { - // the votes will bring us to new round - // we should timeut of it and go to prevote - <-cs1.NewStepCh() - <-timeoutChan - donePrecommitWait <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3) - <-donePrecommitWait - - incrementRound(cs2, cs3, cs4) - - log.Info("### ONTO ROUND 3") - /*Round3 - we see the polka from round 1 but we shouldn't unlock! - */ - - // timeout of propose - _, _ = <-cs1.NewStepCh(), <-timeoutChan - - // finish prevote - _, _ = <-voteChan, <-cs1.NewStepCh() - - // we should prevote what we're locked on - validatePrevote(t, cs1, 2, vss[0], propBlockHash) - - // add prevotes from the earlier round - addVoteToFromMany(cs1, prevotes, cs2, cs3, cs4) - - log.Warn("Done adding prevotes!") - - ensureNoNewStep(t, cs1) -} - -// 4 vals. -// polka P1 at R1, P2 at R2, and P3 at R3, -// we lock on P1 at R1, don't see P2, and unlock using P3 at R3 -// then we should make sure we don't lock using P2 -func TestLockPOLSafety2(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan *types.EventDataRoundState) - voteChan := make(chan *types.EventDataVote) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutPropose(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- data.(*types.EventDataRoundState) - }) - evsw.AddListenerForEvent("tester", types.EventStringVote(), func(data types.EventData) { - vote := data.(*types.EventDataVote) - // we only fire for our own votes - if bytes.Equal(cs1.privValidator.Address, vote.Address) { - voteChan <- vote - } - }) - cs1.SetFireable(evsw) - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _, _ = <-cs1.NewStepCh(), <-voteChan, <-cs1.NewStepCh() - - theBlockHash := cs1.ProposalBlock.Hash() - - donePrecommit := make(chan struct{}) - go func() { - <-voteChan - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs2, cs3, cs4) - <-donePrecommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - donePrecommitWait := make(chan struct{}) - go func() { - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - // add precommits from the rest - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs4) - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - <-donePrecommitWait - - // before we time out into new round, set next proposer - // and next proposal block - _, v1 := cs1.Validators.GetByAddress(vss[0].Address) - v1.VotingPower = 1 - if updated := cs1.Validators.Update(v1); !updated { - t.Fatal("failed to update validator") - } - - prop, propBlock := decideProposal(cs1, cs2, cs2.Height, cs2.Round+1) - - incrementRound(cs2, cs3, cs4) - - // timeout to new round - <-timeoutChan - - log.Info("### ONTO Round 2") - /*Round2 - // we timeout and prevote our lock - // a polka happened but we didn't see it! - */ - - // now we're on a new round and not the proposer, so wait for timeout - _, _ = <-cs1.NewStepCh(), <-timeoutChan - // go to prevote, prevote for locked block - _, _ = <-voteChan, <-cs1.NewStepCh() - validatePrevote(t, cs1, 0, vss[0], cs1.LockedBlock.Hash()) - - // the others sign a polka but we don't see it - prevotes := signVoteMany(types.VoteTypePrevote, propBlock.Hash(), propBlock.MakePartSet().Header(), cs2, cs3, cs4) - - // once we see prevotes for the next round we'll skip ahead - - incrementRound(cs2, cs3, cs4) - - log.Info("### ONTO Round 3") - /*Round3 - a polka for nil causes us to unlock - */ - - // these prevotes will send us straight to precommit at the higher round - donePrecommit = make(chan struct{}) - go func() { - select { - case <-cs1.NewStepCh(): // we're in PrevoteWait, go to Precommit - <-voteChan - case <-voteChan: // we went straight to Precommit - } - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - // now lets add prevotes from everyone else for nil - signAddVoteToFromMany(types.VoteTypePrevote, cs1, nil, types.PartSetHeader{}, cs2, cs3, cs4) - <-donePrecommit - - // we should have unlocked - // NOTE: we don't lock on nil, so LockedRound is still 0 - validatePrecommit(t, cs1, 2, 0, vss[0], nil, nil) - - donePrecommitWait = make(chan struct{}) - go func() { - // the votes will bring us to new round right away - // we should timeut of it and go to prevote - <-cs1.NewStepCh() - // set the proposal block to be that which got a polka in R2 - cs1.mtx.Lock() - cs1.Proposal, cs1.ProposalBlock, cs1.ProposalBlockParts = prop, propBlock, propBlock.MakePartSet() - cs1.mtx.Unlock() - // timeout into prevote, finish prevote - _, _, _ = <-timeoutChan, <-voteChan, <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrecommit, cs1, nil, types.PartSetHeader{}, cs2, cs3) - <-donePrecommitWait - - log.Info("### ONTO ROUND 4") - /*Round4 - we see the polka from R2 - make sure we don't lock because of it! - */ - // new round and not proposer - // (we already timed out and stepped into prevote) - - log.Warn("adding prevotes from round 2") - - addVoteToFromMany(cs1, prevotes, cs2, cs3, cs4) - - log.Warn("Done adding prevotes!") - - // we should prevote it now - validatePrevote(t, cs1, 3, vss[0], cs1.ProposalBlock.Hash()) - - // but we shouldn't precommit it - precommits := cs1.Votes.Precommits(3) - vote := precommits.GetByIndex(0) - if vote != nil { - t.Fatal("validator precommitted at round 4 based on an old polka") - } -} - -//------------------------------------------------------------------------------------------ -// SlashingSuite - -func TestSlashingPrevotes(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs2 := vss[1] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh() - - // we should now be stuck in limbo forever, waiting for more prevotes - // add one for a different block should cause us to go into prevote wait - hash := cs1.ProposalBlock.Hash() - hash[0] = byte(hash[0]+1) % 255 - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // pass prevote wait - <-cs1.NewStepCh() - - // NOTE: we have to send the vote for different block first so we don't just go into precommit round right - // away and ignore more prevotes (and thus fail to slash!) - - // add the conflicting vote - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - - // XXX: Check for existence of Dupeout info -} - -func TestSlashingPrecommits(t *testing.T) { - cs1, vss := simpleConsensusState(2) - cs2 := vss[1] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh() - - // add prevote from cs2 - signAddVoteToFrom(types.VoteTypePrevote, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - - // wait to finish precommit - <-cs1.NewStepCh() - - // we should now be stuck in limbo forever, waiting for more prevotes - // add one for a different block should cause us to go into prevote wait - hash := cs1.ProposalBlock.Hash() - hash[0] = byte(hash[0]+1) % 255 - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, hash, cs1.ProposalBlockParts.Header()) - - // pass prevote wait - <-cs1.NewStepCh() - - // NOTE: we have to send the vote for different block first so we don't just go into precommit round right - // away and ignore more prevotes (and thus fail to slash!) - - // add precommit from cs2 - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - - // XXX: Check for existence of Dupeout info -} - -//------------------------------------------------------------------------------------------ -// CatchupSuite - -//------------------------------------------------------------------------------------------ -// HaltSuite - -// 4 vals. -// we receive a final precommit after going into next round, but others might have gone to commit already! -func TestHalt1(t *testing.T) { - cs1, vss := simpleConsensusState(4) - cs2, cs3, cs4 := vss[1], vss[2], vss[3] - cs1.newStepCh = make(chan *RoundState) // so it blocks - - timeoutChan := make(chan struct{}) - evsw := events.NewEventSwitch() - evsw.OnStart() - evsw.AddListenerForEvent("tester", types.EventStringTimeoutWait(), func(data types.EventData) { - timeoutChan <- struct{}{} - }) - cs1.SetFireable(evsw) - - // start round and wait for propose and prevote - cs1.EnterNewRound(cs1.Height, 0, false) - _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh() - - theBlockHash := cs1.ProposalBlock.Hash() - - donePrecommit := make(chan struct{}) - go func() { - <-cs1.NewStepCh() - donePrecommit <- struct{}{} - }() - signAddVoteToFromMany(types.VoteTypePrevote, cs1, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), cs3, cs4) - <-donePrecommit - - // the proposed block should now be locked and our precommit added - validatePrecommit(t, cs1, 0, 0, vss[0], theBlockHash, theBlockHash) - - donePrecommitWait := make(chan struct{}) - go func() { - <-cs1.NewStepCh() - donePrecommitWait <- struct{}{} - }() - // add precommits from the rest - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs2, nil, types.PartSetHeader{}) // didnt receive proposal - signAddVoteToFrom(types.VoteTypePrecommit, cs1, cs3, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - // we receive this later, but cs3 might receive it earlier and with ours will go to commit! - precommit4 := signVote(cs4, types.VoteTypePrecommit, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header()) - <-donePrecommitWait - - incrementRound(cs2, cs3, cs4) - - // timeout to new round - <-timeoutChan - - log.Info("### ONTO ROUND 2") - /*Round2 - // we timeout and prevote our lock - // a polka happened but we didn't see it! - */ - - // go to prevote, prevote for locked block - _, _ = <-cs1.NewStepCh(), <-cs1.NewStepCh() - validatePrevote(t, cs1, 0, vss[0], cs1.LockedBlock.Hash()) - - // now we receive the precommit from the previous round - addVoteToFrom(cs1, cs4, precommit4) - - // receiving that precommit should take us straight to commit - ensureNewStep(t, cs1) - log.Warn("done enter commit!") - - // update to state - ensureNewStep(t, cs1) - - if cs1.Height != 2 { - t.Fatal("expected height to increment") - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/event_cache.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/event_cache.go deleted file mode 100644 index c37793f95a8a3796c00ccba2b0a7fc343cea5897..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/event_cache.go +++ /dev/null @@ -1,45 +0,0 @@ -package events - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - eventsBufferSize = 1000 -) - -// An EventCache buffers events for a Fireable -// All events are cached. Filtering happens on Flush -type EventCache struct { - evsw Fireable - events []eventInfo -} - -// Create a new EventCache with an EventSwitch as backend -func NewEventCache(evsw Fireable) *EventCache { - return &EventCache{ - evsw: evsw, - events: make([]eventInfo, eventsBufferSize), - } -} - -// a cached event -type eventInfo struct { - event string - data types.EventData -} - -// Cache an event to be fired upon finality. -func (evc *EventCache) FireEvent(event string, data types.EventData) { - // append to list - evc.events = append(evc.events, eventInfo{event, data}) -} - -// Fire events by running evsw.FireEvent on all cached events. Blocks. -// Clears cached events -func (evc *EventCache) Flush() { - for _, ei := range evc.events { - evc.evsw.FireEvent(ei.event, ei.data) - } - evc.events = make([]eventInfo, eventsBufferSize) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go deleted file mode 100644 index 0ee25b180b319d20bb348b3ecd09350a48ed99af..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/events.go +++ /dev/null @@ -1,205 +0,0 @@ -package events - -import ( - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -// reactors and other modules should export -// this interface to become eventable -type Eventable interface { - SetFireable(Fireable) -} - -// an event switch or cache implements fireable -type Fireable interface { - FireEvent(event string, data types.EventData) -} - -type EventSwitch struct { - BaseService - - mtx sync.RWMutex - eventCells map[string]*eventCell - listeners map[string]*eventListener -} - -func NewEventSwitch() *EventSwitch { - evsw := &EventSwitch{} - evsw.BaseService = *NewBaseService(log, "EventSwitch", evsw) - return evsw -} - -func (evsw *EventSwitch) OnStart() error { - evsw.BaseService.OnStart() - evsw.eventCells = make(map[string]*eventCell) - evsw.listeners = make(map[string]*eventListener) - return nil -} - -func (evsw *EventSwitch) OnStop() { - evsw.BaseService.OnStop() - evsw.eventCells = nil - evsw.listeners = nil -} - -func (evsw *EventSwitch) AddListenerForEvent(listenerID, event string, cb eventCallback) { - // Get/Create eventCell and listener - evsw.mtx.Lock() - eventCell := evsw.eventCells[event] - if eventCell == nil { - eventCell = newEventCell() - evsw.eventCells[event] = eventCell - } - listener := evsw.listeners[listenerID] - if listener == nil { - listener = newEventListener(listenerID) - evsw.listeners[listenerID] = listener - } - evsw.mtx.Unlock() - - // Add event and listener - eventCell.AddListener(listenerID, cb) - listener.AddEvent(event) -} - -func (evsw *EventSwitch) RemoveListener(listenerID string) { - // Get and remove listener - evsw.mtx.RLock() - listener := evsw.listeners[listenerID] - delete(evsw.listeners, listenerID) - evsw.mtx.RUnlock() - - if listener == nil { - return - } - - // Remove callback for each event. - listener.SetRemoved() - for _, event := range listener.GetEvents() { - evsw.RemoveListenerForEvent(event, listenerID) - } -} - -func (evsw *EventSwitch) RemoveListenerForEvent(event string, listenerID string) { - // Get eventCell - evsw.mtx.Lock() - eventCell := evsw.eventCells[event] - evsw.mtx.Unlock() - - if eventCell == nil { - return - } - - // Remove listenerID from eventCell - numListeners := eventCell.RemoveListener(listenerID) - - // Maybe garbage collect eventCell. - if numListeners == 0 { - // Lock again and double check. - evsw.mtx.Lock() // OUTER LOCK - eventCell.mtx.Lock() // INNER LOCK - if len(eventCell.listeners) == 0 { - delete(evsw.eventCells, event) - } - eventCell.mtx.Unlock() // INNER LOCK - evsw.mtx.Unlock() // OUTER LOCK - } -} - -func (evsw *EventSwitch) FireEvent(event string, data types.EventData) { - // Get the eventCell - evsw.mtx.RLock() - eventCell := evsw.eventCells[event] - evsw.mtx.RUnlock() - - if eventCell == nil { - return - } - - // Fire event for all listeners in eventCell - eventCell.FireEvent(data) -} - -//----------------------------------------------------------------------------- - -// eventCell handles keeping track of listener callbacks for a given event. -type eventCell struct { - mtx sync.RWMutex - listeners map[string]eventCallback -} - -func newEventCell() *eventCell { - return &eventCell{ - listeners: make(map[string]eventCallback), - } -} - -func (cell *eventCell) AddListener(listenerID string, cb eventCallback) { - cell.mtx.Lock() - cell.listeners[listenerID] = cb - cell.mtx.Unlock() -} - -func (cell *eventCell) RemoveListener(listenerID string) int { - cell.mtx.Lock() - delete(cell.listeners, listenerID) - numListeners := len(cell.listeners) - cell.mtx.Unlock() - return numListeners -} - -func (cell *eventCell) FireEvent(data types.EventData) { - cell.mtx.RLock() - for _, listener := range cell.listeners { - listener(data) - } - cell.mtx.RUnlock() -} - -//----------------------------------------------------------------------------- - -type eventCallback func(data types.EventData) - -type eventListener struct { - id string - - mtx sync.RWMutex - removed bool - events []string -} - -func newEventListener(id string) *eventListener { - return &eventListener{ - id: id, - removed: false, - events: nil, - } -} - -func (evl *eventListener) AddEvent(event string) { - evl.mtx.Lock() - defer evl.mtx.Unlock() - - if evl.removed { - return - } - evl.events = append(evl.events, event) -} - -func (evl *eventListener) GetEvents() []string { - evl.mtx.RLock() - defer evl.mtx.RUnlock() - - events := make([]string, len(evl.events)) - copy(events, evl.events) - return events -} - -func (evl *eventListener) SetRemoved() { - evl.mtx.Lock() - defer evl.mtx.Unlock() - evl.removed = true -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go deleted file mode 100644 index 8226fc661de41645a5a93aa4b17aa49dca799cc8..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/events/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package events - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "events") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go deleted file mode 100644 index e624899814f37f2cce63a4a2467e8fac6551a55e..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package mempool - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go deleted file mode 100644 index 8fdf5aa2b272763a6851b2d3c58a38235077e520..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package mempool - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "mempool") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool.go deleted file mode 100644 index 5a6d5cf775dc69aeeb60b5d85c38d21ff87b803d..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool.go +++ /dev/null @@ -1,226 +0,0 @@ -package mempool - -import ( - "bytes" - "sync" - "sync/atomic" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-clist" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -/* - -The mempool pushes new txs onto the proxyAppCtx. -It gets a stream of (req, res) tuples from the proxy. -The memool stores good txs in a concurrent linked-list. - -Multiple concurrent go-routines can traverse this linked-list -safely by calling .NextWait() on each element. - -So we have several go-routines: -1. Consensus calling Update() and Reap() synchronously -2. Many mempool reactor's peer routines calling AppendTx() -3. Many mempool reactor's peer routines traversing the txs linked list -4. Another goroutine calling GarbageCollectTxs() periodically - -To manage these goroutines, there are three methods of locking. -1. Mutations to the linked-list is protected by an internal mtx (CList is goroutine-safe) -2. Mutations to the linked-list elements are atomic -3. AppendTx() calls can be paused upon Update() and Reap(), protected by .proxyMtx - -Garbage collection of old elements from mempool.txs is handlde via -the DetachPrev() call, which makes old elements not reachable by -peer broadcastTxRoutine() automatically garbage collected. - - - -*/ - -type Mempool struct { - proxyMtx sync.Mutex - proxyAppCtx proxy.AppContext - txs *clist.CList // concurrent linked-list of good txs - counter int64 // simple incrementing counter - height int // the last block Update()'d to - expected *clist.CElement // pointer to .txs for next response -} - -func NewMempool(proxyAppCtx proxy.AppContext) *Mempool { - mempool := &Mempool{ - proxyAppCtx: proxyAppCtx, - txs: clist.New(), - counter: 0, - height: 0, - expected: nil, - } - proxyAppCtx.SetResponseCallback(mempool.resCb) - return mempool -} - -// Return the first element of mem.txs for peer goroutines to call .NextWait() on. -// Blocks until txs has elements. -func (mem *Mempool) TxsFrontWait() *clist.CElement { - return mem.txs.FrontWait() -} - -// Try a new transaction in the mempool. -// Potentially blocking if we're blocking on Update() or Reap(). -func (mem *Mempool) AppendTx(tx types.Tx) (err error) { - mem.proxyMtx.Lock() - defer mem.proxyMtx.Unlock() - - if err = mem.proxyAppCtx.Error(); err != nil { - return err - } - mem.proxyAppCtx.AppendTxAsync(tx) - return nil -} - -// TMSP callback function -// CONTRACT: No other goroutines mutate mem.expected concurrently. -func (mem *Mempool) resCb(req tmsp.Request, res tmsp.Response) { - switch res := res.(type) { - case tmsp.ResponseAppendTx: - reqAppendTx := req.(tmsp.RequestAppendTx) - if mem.expected == nil { // Normal operation - if res.RetCode == tmsp.RetCodeOK { - mem.counter++ - memTx := &mempoolTx{ - counter: mem.counter, - height: int64(mem.height), - tx: reqAppendTx.TxBytes, - } - mem.txs.PushBack(memTx) - } else { - // ignore bad transaction - // TODO: handle other retcodes - } - } else { // During Update() - // TODO Log sane warning if mem.expected is nil. - memTx := mem.expected.Value.(*mempoolTx) - if !bytes.Equal(reqAppendTx.TxBytes, memTx.tx) { - PanicSanity("Unexpected tx response from proxy") - } - if res.RetCode == tmsp.RetCodeOK { - // Good, nothing to do. - } else { - // TODO: handle other retcodes - // Tx became invalidated due to newly committed block. - // NOTE: Concurrent traversal of mem.txs via CElement.Next() still works. - mem.txs.Remove(mem.expected) - mem.expected.DetachPrev() - } - mem.expected = mem.expected.Next() - } - default: - // ignore other messages - } -} - -// Get the valid transactions run so far, and the hash of -// the application state that results from those transactions. -func (mem *Mempool) Reap() ([]types.Tx, []byte, error) { - mem.proxyMtx.Lock() - defer mem.proxyMtx.Unlock() - - // First, get the hash of txs run so far - hash, err := mem.proxyAppCtx.GetHashSync() - if err != nil { - return nil, nil, err - } - - // And collect all the transactions. - txs := mem.collectTxs() - - return txs, hash, nil -} - -func (mem *Mempool) collectTxs() []types.Tx { - txs := make([]types.Tx, 0, mem.txs.Len()) - for e := mem.txs.Front(); e != nil; e = e.Next() { - memTx := e.Value.(*mempoolTx) - txs = append(txs, memTx.tx) - } - return txs -} - -// "block" is the new block that was committed. -// Txs that are present in "block" are discarded from mempool. -// NOTE: this should be called *after* block is committed by consensus. -// CONTRACT: block is valid and next in sequence. -func (mem *Mempool) Update(block *types.Block) error { - mem.proxyMtx.Lock() - defer mem.proxyMtx.Unlock() - - // Rollback mempool synchronously - // TODO: test that proxyAppCtx's state matches the block's - err := mem.proxyAppCtx.RollbackSync() - if err != nil { - return err - } - - // First, create a lookup map of txns in new block. - blockTxsMap := make(map[string]struct{}) - for _, tx := range block.Data.Txs { - blockTxsMap[string(tx)] = struct{}{} - } - - // Remove transactions that are already in block. - // Return the remaining potentially good txs. - goodTxs := mem.filterTxs(block.Height, blockTxsMap) - - // Set height and expected - mem.height = block.Height - mem.expected = mem.txs.Front() - - // Push good txs to proxyAppCtx - // NOTE: resCb() may be called concurrently. - for _, tx := range goodTxs { - mem.proxyAppCtx.AppendTxAsync(tx) - if err := mem.proxyAppCtx.Error(); err != nil { - return err - } - } - - // NOTE: Even though we return immediately without e.g. - // calling mem.proxyAppCtx.FlushSync(), - // New mempool txs will still have to wait until - // all goodTxs are re-processed. - // So we could make synchronous calls here to proxyAppCtx. - - return nil -} - -func (mem *Mempool) filterTxs(height int, blockTxsMap map[string]struct{}) []types.Tx { - goodTxs := make([]types.Tx, 0, mem.txs.Len()) - for e := mem.txs.Front(); e != nil; e = e.Next() { - memTx := e.Value.(*mempoolTx) - if _, ok := blockTxsMap[string(memTx.tx)]; ok { - // Remove the tx since already in block. - mem.txs.Remove(e) - e.DetachPrev() - continue - } - // Good tx! - atomic.StoreInt64(&memTx.height, int64(height)) - goodTxs = append(goodTxs, memTx.tx) - } - return goodTxs -} - -//-------------------------------------------------------------------------------- - -// A transaction that successfully ran -type mempoolTx struct { - counter int64 // a simple incrementing counter - height int64 // height that this tx had been validated in - tx types.Tx // -} - -func (memTx *mempoolTx) Height() int { - return int(atomic.LoadInt64(&memTx.height)) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool_test.go deleted file mode 100644 index b01fd685a0a5fcd560e92dcdc7806c6471fc284d..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/mempool_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package mempool - -import ( - "encoding/binary" - "testing" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" - "github.com/tendermint/tmsp/example" -) - -func TestSerialReap(t *testing.T) { - - app := example.NewCounterApplication() - appCtxMempool := app.Open() - appCtxMempool.SetOption("serial", "on") - proxyAppCtx := proxy.NewLocalAppContext(appCtxMempool) - mempool := NewMempool(proxyAppCtx) - - // Create another AppContext for committing. - appCtxConsensus := app.Open() - appCtxConsensus.SetOption("serial", "on") - - appendTxsRange := func(start, end int) { - // Append some txs. - for i := start; i < end; i++ { - - // This will succeed - txBytes := make([]byte, 32) - _ = binary.PutVarint(txBytes, int64(i)) - err := mempool.AppendTx(txBytes) - if err != nil { - t.Fatal("Error after AppendTx: %v", err) - } - - // This will fail because not serial (incrementing) - // However, error should still be nil. - // It just won't show up on Reap(). - err = mempool.AppendTx(txBytes) - if err != nil { - t.Fatal("Error after AppendTx: %v", err) - } - - } - } - - reapCheck := func(exp int) { - txs, _, err := mempool.Reap() - if err != nil { - t.Error("Error in mempool.Reap()", err) - } - if len(txs) != exp { - t.Fatalf("Expected to reap %v txs but got %v", exp, len(txs)) - } - } - - updateRange := func(start, end int) { - txs := make([]types.Tx, 0) - for i := start; i < end; i++ { - txBytes := make([]byte, 32) - _ = binary.PutVarint(txBytes, int64(i)) - txs = append(txs, txBytes) - } - blockHeader := &types.Header{Height: 0} - blockData := &types.Data{Txs: txs} - block := &types.Block{Header: blockHeader, Data: blockData} - err := mempool.Update(block) - if err != nil { - t.Error("Error in mempool.Update()", err) - } - } - - commitRange := func(start, end int) { - // Append some txs. - for i := start; i < end; i++ { - txBytes := make([]byte, 32) - _ = binary.PutVarint(txBytes, int64(i)) - _, retCode := appCtxConsensus.AppendTx(txBytes) - if retCode != tmsp.RetCodeOK { - t.Error("Error committing tx", retCode) - } - } - retCode := appCtxConsensus.Commit() - if retCode != tmsp.RetCodeOK { - t.Error("Error committing range", retCode) - } - } - - //---------------------------------------- - - // Append some txs. - appendTxsRange(0, 100) - - // Reap the txs. - reapCheck(100) - - // Reap again. We should get the same amount - reapCheck(100) - - // Append 0 to 999, we should reap 900 txs - // because 100 were already counted. - appendTxsRange(0, 1000) - - // Reap the txs. - reapCheck(1000) - - // Reap again. We should get the same amount - reapCheck(1000) - - // Commit from the conensus AppContext - commitRange(0, 500) - updateRange(0, 500) - - // We should have 500 left. - reapCheck(500) - -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/reactor.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/reactor.go deleted file mode 100644 index 5b41c11759b308e4a14b8427687ad9cd38689c7e..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool/reactor.go +++ /dev/null @@ -1,172 +0,0 @@ -package mempool - -import ( - "bytes" - "fmt" - "reflect" - "time" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-clist" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -const ( - MempoolChannel = byte(0x30) - - maxMempoolMessageSize = 1048576 // 1MB TODO make it configurable - peerCatchupSleepIntervalMS = 100 // If peer is behind, sleep this amount -) - -// MempoolReactor handles mempool tx broadcasting amongst peers. -type MempoolReactor struct { - p2p.BaseReactor - Mempool *Mempool // TODO: un-expose - evsw events.Fireable -} - -func NewMempoolReactor(mempool *Mempool) *MempoolReactor { - memR := &MempoolReactor{ - Mempool: mempool, - } - memR.BaseReactor = *p2p.NewBaseReactor(log, "MempoolReactor", memR) - return memR -} - -// Implements Reactor -func (memR *MempoolReactor) GetChannels() []*p2p.ChannelDescriptor { - return []*p2p.ChannelDescriptor{ - &p2p.ChannelDescriptor{ - ID: MempoolChannel, - Priority: 5, - }, - } -} - -// Implements Reactor -func (memR *MempoolReactor) AddPeer(peer *p2p.Peer) { - go memR.broadcastTxRoutine(peer) -} - -// Implements Reactor -func (memR *MempoolReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { - // broadcast routine checks if peer is gone and returns -} - -// Implements Reactor -func (memR *MempoolReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { - _, msg, err := DecodeMessage(msgBytes) - if err != nil { - log.Warn("Error decoding message", "error", err) - return - } - log.Notice("MempoolReactor received message", "msg", msg) - - switch msg := msg.(type) { - case *TxMessage: - err := memR.Mempool.AppendTx(msg.Tx) - if err != nil { - // Bad, seen, or conflicting tx. - log.Info("Could not add tx", "tx", msg.Tx) - return - } else { - log.Info("Added valid tx", "tx", msg.Tx) - } - // broadcasting happens from go routines per peer - default: - log.Warn(Fmt("Unknown message type %v", reflect.TypeOf(msg))) - } -} - -// Just an alias for AppendTx since broadcasting happens in peer routines -func (memR *MempoolReactor) BroadcastTx(tx types.Tx) error { - return memR.Mempool.AppendTx(tx) -} - -type PeerState interface { - GetHeight() int -} - -type Peer interface { - IsRunning() bool - Send(byte, interface{}) bool - Get(string) interface{} -} - -// Send new mempool txs to peer. -// TODO: Handle mempool or reactor shutdown? -// As is this routine may block forever if no new txs come in. -func (memR *MempoolReactor) broadcastTxRoutine(peer Peer) { - var next *clist.CElement - for { - if !memR.IsRunning() { - return // Quit! - } - if next == nil { - // This happens because the CElement we were looking at got - // garbage collected (removed). That is, .NextWait() returned nil. - // Go ahead and start from the beginning. - next = memR.Mempool.TxsFrontWait() // Wait until a tx is available - } - memTx := next.Value.(*mempoolTx) - // make sure the peer is up to date - height := memTx.Height() - if peerState_i := peer.Get(types.PeerStateKey); peerState_i != nil { - peerState := peerState_i.(PeerState) - if peerState.GetHeight() < height-1 { // Allow for a lag of 1 block - time.Sleep(peerCatchupSleepIntervalMS * time.Millisecond) - continue - } - } - // send memTx - msg := &TxMessage{Tx: memTx.tx} - success := peer.Send(MempoolChannel, msg) - if !success { - time.Sleep(peerCatchupSleepIntervalMS * time.Millisecond) - continue - } - - next = next.NextWait() - continue - } -} - -// implements events.Eventable -func (memR *MempoolReactor) SetFireable(evsw events.Fireable) { - memR.evsw = evsw -} - -//----------------------------------------------------------------------------- -// Messages - -const ( - msgTypeTx = byte(0x01) -) - -type MempoolMessage interface{} - -var _ = wire.RegisterInterface( - struct{ MempoolMessage }{}, - wire.ConcreteType{&TxMessage{}, msgTypeTx}, -) - -func DecodeMessage(bz []byte) (msgType byte, msg MempoolMessage, err error) { - msgType = bz[0] - n := new(int) - r := bytes.NewReader(bz) - msg = wire.ReadBinary(struct{ MempoolMessage }{}, r, maxMempoolMessageSize, n, &err).(struct{ MempoolMessage }).MempoolMessage - return -} - -//------------------------------------- - -type TxMessage struct { - Tx types.Tx -} - -func (m *TxMessage) String() string { - return fmt.Sprintf("[TxMessage %v]", m.Tx) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go deleted file mode 100644 index b0d9fc60952175441a4849fc190489c91d125a6b..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package node - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go deleted file mode 100644 index 825117b42dc99d7b35dfa2e76671d14964b30025..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/id.go +++ /dev/null @@ -1,34 +0,0 @@ -package node - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "time" -) - -type NodeID struct { - Name string - PubKey crypto.PubKey -} - -type PrivNodeID struct { - NodeID - PrivKey crypto.PrivKey -} - -type NodeGreeting struct { - NodeID - Version string - ChainID string - Message string - Time time.Time -} - -type SignedNodeGreeting struct { - NodeGreeting - Signature crypto.Signature -} - -func (pnid *PrivNodeID) SignGreeting() *SignedNodeGreeting { - //greeting := NodeGreeting{} - return nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go deleted file mode 100644 index 768cd31584403f539c5dfd8c0214c94463ab76f3..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package node - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "node") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node.go deleted file mode 100644 index 4b04f16f274fac8bab95cdbb76bf754e557c4736..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node.go +++ /dev/null @@ -1,339 +0,0 @@ -package node - -import ( - "bytes" - "io/ioutil" - "math/rand" - "net" - "net/http" - "strings" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - mempl "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server" - sm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/state" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -import _ "net/http/pprof" - -type Node struct { - sw *p2p.Switch - evsw *events.EventSwitch - blockStore *bc.BlockStore - bcReactor *bc.BlockchainReactor - mempoolReactor *mempl.MempoolReactor - consensusState *consensus.ConsensusState - consensusReactor *consensus.ConsensusReactor - privValidator *types.PrivValidator - genesisDoc *types.GenesisDoc - privKey crypto.PrivKeyEd25519 -} - -func NewNode() *Node { - // Get BlockStore - blockStoreDB := dbm.GetDB("blockstore") - blockStore := bc.NewBlockStore(blockStoreDB) - - // Get State - state := getState() - - // Create two proxyAppCtx connections, - // one for the consensus and one for the mempool. - proxyAddr := config.GetString("proxy_app") - proxyAppCtxMempool := getProxyApp(proxyAddr, state.LastAppHash) - proxyAppCtxConsensus := getProxyApp(proxyAddr, state.LastAppHash) - - // add the chainid to the global config - config.Set("chain_id", state.ChainID) - - // Get PrivValidator - privValidatorFile := config.GetString("priv_validator_file") - privValidator := types.LoadOrGenPrivValidator(privValidatorFile) - - // Generate node PrivKey - privKey := crypto.GenPrivKeyEd25519() - - // Make event switch - eventSwitch := events.NewEventSwitch() - _, err := eventSwitch.Start() - if err != nil { - Exit(Fmt("Failed to start switch: %v", err)) - } - - // Make BlockchainReactor - bcReactor := bc.NewBlockchainReactor(state.Copy(), proxyAppCtxConsensus, blockStore, config.GetBool("fast_sync")) - - // Make MempoolReactor - mempool := mempl.NewMempool(proxyAppCtxMempool) - mempoolReactor := mempl.NewMempoolReactor(mempool) - - // Make ConsensusReactor - consensusState := consensus.NewConsensusState(state.Copy(), proxyAppCtxConsensus, blockStore, mempool) - consensusReactor := consensus.NewConsensusReactor(consensusState, blockStore, config.GetBool("fast_sync")) - if privValidator != nil { - consensusReactor.SetPrivValidator(privValidator) - } - - // Make p2p network switch - sw := p2p.NewSwitch() - sw.AddReactor("MEMPOOL", mempoolReactor) - sw.AddReactor("BLOCKCHAIN", bcReactor) - sw.AddReactor("CONSENSUS", consensusReactor) - - // add the event switch to all services - // they should all satisfy events.Eventable - SetFireable(eventSwitch, bcReactor, mempoolReactor, consensusReactor) - - // run the profile server - profileHost := config.GetString("prof_laddr") - if profileHost != "" { - go func() { - log.Warn("Profile server", "error", http.ListenAndServe(profileHost, nil)) - }() - } - - return &Node{ - sw: sw, - evsw: eventSwitch, - blockStore: blockStore, - bcReactor: bcReactor, - mempoolReactor: mempoolReactor, - consensusState: consensusState, - consensusReactor: consensusReactor, - privValidator: privValidator, - genesisDoc: state.GenesisDoc, - privKey: privKey, - } -} - -// Call Start() after adding the listeners. -func (n *Node) Start() error { - n.sw.SetNodeInfo(makeNodeInfo(n.sw, n.privKey)) - n.sw.SetNodePrivKey(n.privKey) - _, err := n.sw.Start() - return err -} - -func (n *Node) Stop() { - log.Notice("Stopping Node") - // TODO: gracefully disconnect from peers. - n.sw.Stop() -} - -// Add the event switch to reactors, mempool, etc. -func SetFireable(evsw *events.EventSwitch, eventables ...events.Eventable) { - for _, e := range eventables { - e.SetFireable(evsw) - } -} - -// Add a Listener to accept inbound peer connections. -// Add listeners before starting the Node. -// The first listener is the primary listener (in NodeInfo) -func (n *Node) AddListener(l p2p.Listener) { - log.Notice(Fmt("Added %v", l)) - n.sw.AddListener(l) -} - -// Dial a list of seeds in random order -// Spawns a go routine for each dial -func (n *Node) DialSeed() { - // permute the list, dial them in random order. - seeds := strings.Split(config.GetString("seeds"), ",") - perm := rand.Perm(len(seeds)) - for i := 0; i < len(perm); i++ { - go func(i int) { - time.Sleep(time.Duration(rand.Int63n(3000)) * time.Millisecond) - j := perm[i] - addr := p2p.NewNetAddressString(seeds[j]) - n.dialSeed(addr) - }(i) - } -} - -func (n *Node) dialSeed(addr *p2p.NetAddress) { - peer, err := n.sw.DialPeerWithAddress(addr) - if err != nil { - log.Error("Error dialing seed", "error", err) - return - } else { - log.Notice("Connected to seed", "peer", peer) - } -} - -func (n *Node) StartRPC() (net.Listener, error) { - core.SetBlockStore(n.blockStore) - core.SetConsensusState(n.consensusState) - core.SetConsensusReactor(n.consensusReactor) - core.SetMempoolReactor(n.mempoolReactor) - core.SetSwitch(n.sw) - core.SetPrivValidator(n.privValidator) - core.SetGenesisDoc(n.genesisDoc) - - listenAddr := config.GetString("rpc_laddr") - - mux := http.NewServeMux() - wm := rpcserver.NewWebsocketManager(core.Routes, n.evsw) - mux.HandleFunc("/websocket", wm.WebsocketHandler) - rpcserver.RegisterRPCFuncs(mux, core.Routes) - return rpcserver.StartHTTPServer(listenAddr, mux) -} - -func (n *Node) Switch() *p2p.Switch { - return n.sw -} - -func (n *Node) BlockStore() *bc.BlockStore { - return n.blockStore -} - -func (n *Node) ConsensusState() *consensus.ConsensusState { - return n.consensusState -} - -func (n *Node) MempoolReactor() *mempl.MempoolReactor { - return n.mempoolReactor -} - -func (n *Node) EventSwitch() *events.EventSwitch { - return n.evsw -} - -func makeNodeInfo(sw *p2p.Switch, privKey crypto.PrivKeyEd25519) *p2p.NodeInfo { - - nodeInfo := &p2p.NodeInfo{ - PubKey: privKey.PubKey().(crypto.PubKeyEd25519), - Moniker: config.GetString("moniker"), - Network: config.GetString("chain_id"), - Version: Version, - Other: []string{ - Fmt("p2p_version=%v", p2p.Version), - Fmt("rpc_version=%v", rpc.Version), - Fmt("wire_version=%v", wire.Version), - }, - } - - // include git hash in the nodeInfo if available - if rev, err := ReadFile(config.GetString("revision_file")); err == nil { - nodeInfo.Other = append(nodeInfo.Other, Fmt("revision=%v", string(rev))) - } - - if !sw.IsListening() { - return nodeInfo - } - - p2pListener := sw.Listeners()[0] - p2pHost := p2pListener.ExternalAddress().IP.String() - p2pPort := p2pListener.ExternalAddress().Port - rpcListenAddr := config.GetString("rpc_laddr") - - // We assume that the rpcListener has the same ExternalAddress. - // This is probably true because both P2P and RPC listeners use UPnP, - // except of course if the rpc is only bound to localhost - nodeInfo.ListenAddr = Fmt("%v:%v", p2pHost, p2pPort) - nodeInfo.Other = append(nodeInfo.Other, Fmt("rpc_addr=%v", rpcListenAddr)) - return nodeInfo -} - -//------------------------------------------------------------------------------ - -func RunNode() { - - // Wait until the genesis doc becomes available - genDocFile := config.GetString("genesis_file") - if !FileExists(genDocFile) { - log.Notice(Fmt("Waiting for genesis file %v...", genDocFile)) - for { - time.Sleep(time.Second) - if !FileExists(genDocFile) { - continue - } - jsonBlob, err := ioutil.ReadFile(genDocFile) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) - } - genDoc := types.GenesisDocFromJSON(jsonBlob) - if genDoc.ChainID == "" { - PanicSanity(Fmt("Genesis doc %v must include non-empty chain_id", genDocFile)) - } - config.Set("chain_id", genDoc.ChainID) - config.Set("genesis_doc", genDoc) - } - } - - // Create & start node - n := NewNode() - l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), config.GetBool("skip_upnp")) - n.AddListener(l) - err := n.Start() - if err != nil { - Exit(Fmt("Failed to start node: %v", err)) - } - - log.Notice("Started node", "nodeInfo", n.sw.NodeInfo()) - - // If seedNode is provided by config, dial out. - if config.GetString("seeds") != "" { - n.DialSeed() - } - - // Run the RPC server. - if config.GetString("rpc_laddr") != "" { - _, err := n.StartRPC() - if err != nil { - PanicCrisis(err) - } - } - - // Sleep forever and then... - TrapSignal(func() { - n.Stop() - }) -} - -// Load the most recent state from "state" db, -// or create a new one (and save) from genesis. -func getState() *sm.State { - stateDB := dbm.GetDB("state") - state := sm.LoadState(stateDB) - if state == nil { - state = sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file")) - state.Save() - } - return state -} - -// Get a connection to the proxyAppCtx addr. -// Check the current hash, and panic if it doesn't match. -func getProxyApp(addr string, hash []byte) proxy.AppContext { - proxyConn, err := Connect(addr) - if err != nil { - Exit(Fmt("Failed to connect to proxy for mempool: %v", err)) - } - proxyAppCtx := proxy.NewRemoteAppContext(proxyConn, 1024) - - proxyAppCtx.Start() - - // Check the hash - currentHash, err := proxyAppCtx.GetHashSync() - if err != nil { - PanicCrisis(Fmt("Error in getting proxyAppCtx hash: %v", err)) - } - if !bytes.Equal(hash, currentHash) { - PanicCrisis(Fmt("ProxyApp hash does not match. Expected %X, got %X", hash, currentHash)) - } - - return proxyAppCtx -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node_test.go deleted file mode 100644 index d523421507c2288333b41ac4953d2e199b5abdc7..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/node_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package node - -import ( - "testing" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/server" - "github.com/tendermint/tmsp/example" -) - -func TestNodeStartStop(t *testing.T) { - - // Start a dummy app - go func() { - _, err := server.StartListener(config.GetString("proxy_app"), example.NewDummyApplication()) - if err != nil { - Exit(err.Error()) - } - }() - // wait for the server - time.Sleep(time.Second * 2) - - // Create & start node - n := NewNode() - l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), config.GetBool("skip_upnp")) - n.AddListener(l) - n.Start() - log.Notice("Started node", "nodeInfo", n.sw.NodeInfo()) - time.Sleep(time.Second * 2) - ch := make(chan struct{}, 1) - go func() { - n.Stop() - ch <- struct{}{} - }() - ticker := time.NewTicker(time.Second * 5) - select { - case <-ch: - case <-ticker.C: - t.Fatal("timed out waiting for shutdown") - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/version.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/node/version.go deleted file mode 100644 index 6b981175a23d402253c111c6f7eb09f239eb23a2..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/node/version.go +++ /dev/null @@ -1,6 +0,0 @@ -package node - -// Major: alpha -// Minor: encrypted p2p! -// Patch: New block pool logic -const Version = "0.5.2" diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/app_context.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/app_context.go deleted file mode 100644 index 824599a0e3e95a7c14798637f6f3278e41ac6fc3..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/app_context.go +++ /dev/null @@ -1,28 +0,0 @@ -package proxy - -import ( - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -type Callback func(tmsp.Request, tmsp.Response) - -type AppContext interface { - SetResponseCallback(Callback) - Error() error - - EchoAsync(msg string) - FlushAsync() - AppendTxAsync(tx []byte) - GetHashAsync() - CommitAsync() - RollbackAsync() - SetOptionAsync(key string, value string) - AddListenerAsync(key string) - RemListenerAsync(key string) - - InfoSync() (info []string, err error) - FlushSync() error - GetHashSync() (hash []byte, err error) - CommitSync() error - RollbackSync() error -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/local_app_context.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/local_app_context.go deleted file mode 100644 index 049bec04240cccd805aefa167921a0798ec45696..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/local_app_context.go +++ /dev/null @@ -1,123 +0,0 @@ -package proxy - -import ( - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -type localAppContext struct { - tmsp.AppContext - Callback -} - -func NewLocalAppContext(app tmsp.AppContext) *localAppContext { - return &localAppContext{ - AppContext: app, - } -} - -func (app *localAppContext) SetResponseCallback(cb Callback) { - app.Callback = cb -} - -// TODO: change tmsp.AppContext to include Error()? -func (app *localAppContext) Error() error { - return nil -} - -func (app *localAppContext) EchoAsync(msg string) { - msg2 := app.AppContext.Echo(msg) - app.Callback( - tmsp.RequestEcho{msg}, - tmsp.ResponseEcho{msg2}, - ) -} - -func (app *localAppContext) FlushAsync() { - // Do nothing -} - -func (app *localAppContext) SetOptionAsync(key string, value string) { - retCode := app.AppContext.SetOption(key, value) - app.Callback( - tmsp.RequestSetOption{key, value}, - tmsp.ResponseSetOption{retCode}, - ) -} - -func (app *localAppContext) AppendTxAsync(tx []byte) { - events, retCode := app.AppContext.AppendTx(tx) - app.Callback( - tmsp.RequestAppendTx{tx}, - tmsp.ResponseAppendTx{retCode}, - ) - for _, event := range events { - app.Callback( - nil, - tmsp.ResponseEvent{event}, - ) - } -} - -func (app *localAppContext) GetHashAsync() { - hash, retCode := app.AppContext.GetHash() - app.Callback( - tmsp.RequestGetHash{}, - tmsp.ResponseGetHash{retCode, hash}, - ) -} - -func (app *localAppContext) CommitAsync() { - retCode := app.AppContext.Commit() - app.Callback( - tmsp.RequestCommit{}, - tmsp.ResponseCommit{retCode}, - ) -} - -func (app *localAppContext) RollbackAsync() { - retCode := app.AppContext.Rollback() - app.Callback( - tmsp.RequestRollback{}, - tmsp.ResponseRollback{retCode}, - ) -} - -func (app *localAppContext) AddListenerAsync(key string) { - retCode := app.AppContext.AddListener(key) - app.Callback( - tmsp.RequestAddListener{key}, - tmsp.ResponseAddListener{retCode}, - ) -} - -func (app *localAppContext) RemListenerAsync(key string) { - retCode := app.AppContext.RemListener(key) - app.Callback( - tmsp.RequestRemListener{key}, - tmsp.ResponseRemListener{retCode}, - ) -} - -func (app *localAppContext) InfoSync() (info []string, err error) { - info = app.AppContext.Info() - return info, nil -} - -func (app *localAppContext) FlushSync() error { - return nil -} - -func (app *localAppContext) GetHashSync() (hash []byte, err error) { - hash, retCode := app.AppContext.GetHash() - return hash, retCode.Error() -} - -func (app *localAppContext) CommitSync() (err error) { - retCode := app.AppContext.Commit() - return retCode.Error() -} - -func (app *localAppContext) RollbackSync() (err error) { - retCode := app.AppContext.Rollback() - return retCode.Error() -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/log.go deleted file mode 100644 index 5459d49b4eb130d5151beffdf9f4ea2e0420cf22..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package proxy - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "proxy") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context.go deleted file mode 100644 index e3a021bd51846c2c1c4bd03f2a210465291ba5cd..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context.go +++ /dev/null @@ -1,310 +0,0 @@ -package proxy - -import ( - "bufio" - "container/list" - "errors" - "fmt" - "net" - "reflect" - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -const maxResponseSize = 1048576 // 1MB - -// This is goroutine-safe, but users should beware that -// the application in general is not meant to be interfaced -// with concurrent callers. -type remoteAppContext struct { - QuitService - sync.Mutex // [EB]: is this even used? - - reqQueue chan *reqRes - - mtx sync.Mutex - conn net.Conn - bufWriter *bufio.Writer - err error - reqSent *list.List - resCb func(tmsp.Request, tmsp.Response) -} - -func NewRemoteAppContext(conn net.Conn, bufferSize int) *remoteAppContext { - app := &remoteAppContext{ - reqQueue: make(chan *reqRes, bufferSize), - conn: conn, - bufWriter: bufio.NewWriter(conn), - reqSent: list.New(), - resCb: nil, - } - app.QuitService = *NewQuitService(nil, "remoteAppContext", app) - return app -} - -func (app *remoteAppContext) OnStart() error { - app.QuitService.OnStart() - go app.sendRequestsRoutine() - go app.recvResponseRoutine() - return nil -} - -func (app *remoteAppContext) OnStop() { - app.QuitService.OnStop() - app.conn.Close() -} - -func (app *remoteAppContext) SetResponseCallback(resCb Callback) { - app.mtx.Lock() - defer app.mtx.Unlock() - app.resCb = resCb -} - -func (app *remoteAppContext) StopForError(err error) { - app.mtx.Lock() - log.Error("Stopping remoteAppContext for error.", "error", err) - if app.err == nil { - app.err = err - } - app.mtx.Unlock() - app.Stop() -} - -func (app *remoteAppContext) Error() error { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.err -} - -//---------------------------------------- - -func (app *remoteAppContext) sendRequestsRoutine() { - for { - var n int - var err error - select { - case <-app.QuitService.Quit: - return - case reqres := <-app.reqQueue: - - app.willSendReq(reqres) - - wire.WriteBinary(reqres.Request, app.bufWriter, &n, &err) - if err != nil { - app.StopForError(err) - return - } - log.Debug("Sent request", "requestType", reflect.TypeOf(reqres.Request), "request", reqres.Request) - if _, ok := reqres.Request.(tmsp.RequestFlush); ok { - err = app.bufWriter.Flush() - if err != nil { - app.StopForError(err) - return - } - } - } - } -} - -func (app *remoteAppContext) recvResponseRoutine() { - r := bufio.NewReader(app.conn) // Buffer reads - for { - var res tmsp.Response - var n int - var err error - wire.ReadBinaryPtr(&res, r, maxResponseSize, &n, &err) - if err != nil { - app.StopForError(err) - return - } - switch res := res.(type) { - case tmsp.ResponseException: - app.StopForError(errors.New(res.Error)) - default: - log.Debug("Received response", "responseType", reflect.TypeOf(res), "response", res) - err := app.didRecvResponse(res) - if err != nil { - app.StopForError(err) - } - } - } -} - -func (app *remoteAppContext) willSendReq(reqres *reqRes) { - app.mtx.Lock() - defer app.mtx.Unlock() - app.reqSent.PushBack(reqres) -} - -func (app *remoteAppContext) didRecvResponse(res tmsp.Response) error { - app.mtx.Lock() - defer app.mtx.Unlock() - - // Special logic for events which have no corresponding requests. - if _, ok := res.(tmsp.ResponseEvent); ok && app.resCb != nil { - app.resCb(nil, res) - return nil - } - - // Get the first reqRes - next := app.reqSent.Front() - if next == nil { - return fmt.Errorf("Unexpected result type %v when nothing expected", reflect.TypeOf(res)) - } - reqres := next.Value.(*reqRes) - if !resMatchesReq(reqres.Request, res) { - return fmt.Errorf("Unexpected result type %v when response to %v expected", - reflect.TypeOf(res), reflect.TypeOf(reqres.Request)) - } - - reqres.Response = res // Set response - reqres.Done() // Release waiters - app.reqSent.Remove(next) // Pop first item from linked list - - // Callback if there is a listener - if app.resCb != nil { - app.resCb(reqres.Request, res) - } - - return nil -} - -//---------------------------------------- - -func (app *remoteAppContext) EchoAsync(msg string) { - app.queueRequest(tmsp.RequestEcho{msg}) -} - -func (app *remoteAppContext) FlushAsync() { - app.queueRequest(tmsp.RequestFlush{}) -} - -func (app *remoteAppContext) SetOptionAsync(key string, value string) { - app.queueRequest(tmsp.RequestSetOption{key, value}) -} - -func (app *remoteAppContext) AppendTxAsync(tx []byte) { - app.queueRequest(tmsp.RequestAppendTx{tx}) -} - -func (app *remoteAppContext) GetHashAsync() { - app.queueRequest(tmsp.RequestGetHash{}) -} - -func (app *remoteAppContext) CommitAsync() { - app.queueRequest(tmsp.RequestCommit{}) -} - -func (app *remoteAppContext) RollbackAsync() { - app.queueRequest(tmsp.RequestRollback{}) -} - -func (app *remoteAppContext) AddListenerAsync(key string) { - app.queueRequest(tmsp.RequestAddListener{key}) -} - -func (app *remoteAppContext) RemListenerAsync(key string) { - app.queueRequest(tmsp.RequestRemListener{key}) -} - -//---------------------------------------- - -func (app *remoteAppContext) InfoSync() (info []string, err error) { - reqres := app.queueRequest(tmsp.RequestInfo{}) - app.FlushSync() - if app.err != nil { - return nil, app.err - } - return reqres.Response.(tmsp.ResponseInfo).Data, nil -} - -func (app *remoteAppContext) FlushSync() error { - app.queueRequest(tmsp.RequestFlush{}).Wait() - return app.err -} - -func (app *remoteAppContext) GetHashSync() (hash []byte, err error) { - reqres := app.queueRequest(tmsp.RequestGetHash{}) - app.FlushSync() - if app.err != nil { - return nil, app.err - } - return reqres.Response.(tmsp.ResponseGetHash).Hash, nil -} - -// Commits or error -func (app *remoteAppContext) CommitSync() (err error) { - app.queueRequest(tmsp.RequestCommit{}) - app.FlushSync() - return app.err -} - -// Rollback or error -// Clears internal buffers -func (app *remoteAppContext) RollbackSync() (err error) { - app.queueRequest(tmsp.RequestRollback{}) - app.FlushSync() - return app.err -} - -//---------------------------------------- - -func (app *remoteAppContext) queueRequest(req tmsp.Request) *reqRes { - reqres := NewreqRes(req) - // TODO: set app.err if reqQueue times out - app.reqQueue <- reqres - return reqres -} - -//---------------------------------------- - -func resMatchesReq(req tmsp.Request, res tmsp.Response) (ok bool) { - switch req.(type) { - case tmsp.RequestEcho: - _, ok = res.(tmsp.ResponseEcho) - case tmsp.RequestFlush: - _, ok = res.(tmsp.ResponseFlush) - case tmsp.RequestInfo: - _, ok = res.(tmsp.ResponseInfo) - case tmsp.RequestSetOption: - _, ok = res.(tmsp.ResponseSetOption) - case tmsp.RequestAppendTx: - _, ok = res.(tmsp.ResponseAppendTx) - case tmsp.RequestGetHash: - _, ok = res.(tmsp.ResponseGetHash) - case tmsp.RequestCommit: - _, ok = res.(tmsp.ResponseCommit) - case tmsp.RequestRollback: - _, ok = res.(tmsp.ResponseRollback) - case tmsp.RequestAddListener: - _, ok = res.(tmsp.ResponseAddListener) - case tmsp.RequestRemListener: - _, ok = res.(tmsp.ResponseRemListener) - default: - return false - } - return -} - -type reqRes struct { - tmsp.Request - *sync.WaitGroup - tmsp.Response // Not set atomically, so be sure to use WaitGroup. -} - -func NewreqRes(req tmsp.Request) *reqRes { - return &reqRes{ - Request: req, - WaitGroup: waitGroup1(), - Response: nil, - } -} - -func waitGroup1() (wg *sync.WaitGroup) { - wg = &sync.WaitGroup{} - wg.Add(1) - return -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context_test.go deleted file mode 100644 index 86d388e4cd5c639766b36b27d20146d2b82dd7dd..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy/remote_app_context_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package proxy - -import ( - "bytes" - "strings" - "testing" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/server" - "github.com/tendermint/go-logio" - example "github.com/tendermint/tmsp/example" -) - -func TestEcho(t *testing.T) { - sockPath := Fmt("unix:///tmp/echo_%v.sock", RandStr(6)) - _, err := server.StartListener(sockPath, example.NewDummyApplication()) - if err != nil { - Exit(err.Error()) - } - conn, err := Connect(sockPath) - if err != nil { - Exit(err.Error()) - } else { - t.Log("Connected") - } - - logBuffer := bytes.NewBuffer(nil) - logConn := logio.NewLoggedConn(conn, logBuffer) - proxy := NewRemoteAppContext(logConn, 10) - proxy.SetResponseCallback(nil) - proxy.Start() - - for i := 0; i < 1000; i++ { - proxy.EchoAsync(Fmt("echo-%v", i)) - } - proxy.FlushSync() - - /* - if t.Failed() { - logio.PrintReader(logBuffer) - } - */ -} - -func BenchmarkEcho(b *testing.B) { - b.StopTimer() // Initialize - sockPath := Fmt("unix:///tmp/echo_%v.sock", RandStr(6)) - _, err := server.StartListener(sockPath, example.NewDummyApplication()) - if err != nil { - Exit(err.Error()) - } - conn, err := Connect(sockPath) - if err != nil { - Exit(err.Error()) - } else { - b.Log("Connected") - } - - proxy := NewRemoteAppContext(conn, 10) - proxy.Start() - echoString := strings.Repeat(" ", 200) - b.StartTimer() // Start benchmarking tests - - for i := 0; i < b.N; i++ { - proxy.EchoAsync(echoString) - } - proxy.FlushSync() - - b.StopTimer() - // info := proxy.InfoSync() - //b.Log("N: ", b.N, info) -} - -func TestInfo(t *testing.T) { - sockPath := Fmt("unix:///tmp/echo_%v.sock", RandStr(6)) - _, err := server.StartListener(sockPath, example.NewDummyApplication()) - if err != nil { - Exit(err.Error()) - } - conn, err := Connect(sockPath) - if err != nil { - Exit(err.Error()) - } else { - t.Log("Connected") - } - - logBuffer := bytes.NewBuffer(nil) - logConn := logio.NewLoggedConn(conn, logBuffer) - proxy := NewRemoteAppContext(logConn, 10) - proxy.Start() - data, err := proxy.InfoSync() - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if data[0] != "size:0" { - t.Error("Expected ResponseInfo with one element 'size:0' but got something else") - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/client.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/client.go deleted file mode 100644 index 3e295549b5869cbff9370bf1384da36cddbc1e71..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/client.go +++ /dev/null @@ -1,51 +0,0 @@ -package rpcclient - -import ( - "bytes" - "encoding/json" - "errors" - "io/ioutil" - "net/http" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types" -) - -func Call(remote string, method string, params []interface{}, dest interface{}) (interface{}, error) { - // Make request and get responseBytes - request := RPCRequest{ - JSONRPC: "2.0", - Method: method, - Params: params, - ID: "", - } - requestBytes := wire.JSONBytes(request) - requestBuf := bytes.NewBuffer(requestBytes) - log.Info(Fmt("RPC request to %v: %v", remote, string(requestBytes))) - httpResponse, err := http.Post(remote, "text/json", requestBuf) - if err != nil { - return dest, err - } - defer httpResponse.Body.Close() - responseBytes, err := ioutil.ReadAll(httpResponse.Body) - if err != nil { - return dest, err - } - log.Info(Fmt("RPC response: %v", string(responseBytes))) - - // Parse response into JSONResponse - response := RPCResponse{} - err = json.Unmarshal(responseBytes, &response) - if err != nil { - return dest, err - } - // Parse response into dest - resultJSONObject := response.Result - errorStr := response.Error - if errorStr != "" { - return dest, errors.New(errorStr) - } - dest = wire.ReadJSONObject(dest, resultJSONObject, &err) - return dest, err -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/log.go deleted file mode 100644 index bfebc78dba1d3338bcb1ab663561822184cbd0ed..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/client/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package rpcclient - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" -) - -var log = log15.New("module", "rpcclient") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/blocks.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/blocks.go deleted file mode 100644 index ad61bac5d19c52bc31a135e7fa3f930379f2aa05..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/blocks.go +++ /dev/null @@ -1,45 +0,0 @@ -package core - -import ( - "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -//----------------------------------------------------------------------------- - -func BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResultBlockchainInfo, error) { - if maxHeight == 0 { - maxHeight = blockStore.Height() - } else { - maxHeight = MinInt(blockStore.Height(), maxHeight) - } - if minHeight == 0 { - minHeight = MaxInt(1, maxHeight-20) - } - log.Info("BlockchainInfoHandler", "maxHeight", maxHeight, "minHeight", minHeight) - - blockMetas := []*types.BlockMeta{} - for height := maxHeight; height >= minHeight; height-- { - blockMeta := blockStore.LoadBlockMeta(height) - blockMetas = append(blockMetas, blockMeta) - } - - return &ctypes.ResultBlockchainInfo{blockStore.Height(), blockMetas}, nil -} - -//----------------------------------------------------------------------------- - -func GetBlock(height int) (*ctypes.ResultGetBlock, error) { - if height == 0 { - return nil, fmt.Errorf("Height must be greater than 0") - } - if height > blockStore.Height() { - return nil, fmt.Errorf("Height must be less than the current blockchain height") - } - - blockMeta := blockStore.LoadBlockMeta(height) - block := blockStore.LoadBlock(height) - return &ctypes.ResultGetBlock{blockMeta, block}, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/config.go deleted file mode 100644 index bf269a70df482430d3212b6336d33a9a9a4b398b..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package core - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/consensus.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/consensus.go deleted file mode 100644 index ea621b135c09b70dbb096b4b1b60a890a427860b..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/consensus.go +++ /dev/null @@ -1,35 +0,0 @@ -package core - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - cm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -func ListValidators() (*ctypes.ResultListValidators, error) { - var blockHeight int - var validators []*types.Validator - - state := consensusState.GetState() - blockHeight = state.LastBlockHeight - state.Validators.Iterate(func(index int, val *types.Validator) bool { - validators = append(validators, val) - return false - }) - - return &ctypes.ResultListValidators{blockHeight, validators}, nil -} - -func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { - roundState := consensusState.GetRoundState() - peerRoundStates := []string{} - for _, peer := range p2pSwitch.Peers().List() { - // TODO: clean this up? - peerState := peer.Data.Get(types.PeerStateKey).(*cm.PeerState) - peerRoundState := peerState.GetRoundState() - peerRoundStateStr := peer.Key + ":" + string(wire.JSONBytes(peerRoundState)) - peerRoundStates = append(peerRoundStates, peerRoundStateStr) - } - return &ctypes.ResultDumpConsensusState{roundState.String(), peerRoundStates}, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/log.go deleted file mode 100644 index a0dfe3d8642abca18b02ca7e220b57da4840705d..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package core - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" -) - -var log = log15.New("module", "rpc") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/mempool.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/mempool.go deleted file mode 100644 index 00cbacf5a1957dc6b32fc2fff1bf876d5ad36ab3..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/mempool.go +++ /dev/null @@ -1,23 +0,0 @@ -package core - -import ( - "fmt" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -//----------------------------------------------------------------------------- - -// Note: tx must be signed -func BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - err := mempoolReactor.BroadcastTx(tx) - if err != nil { - return nil, fmt.Errorf("Error broadcasting transaction: %v", err) - } - return &ctypes.ResultBroadcastTx{}, nil -} - -func ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) { - txs, _, err := mempoolReactor.Mempool.Reap() - return &ctypes.ResultListUnconfirmedTxs{len(txs), txs}, err -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/net.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/net.go deleted file mode 100644 index 09f8555f0811309e45d8273a14fb39d1560b3fff..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/net.go +++ /dev/null @@ -1,58 +0,0 @@ -package core - -import ( - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -//----------------------------------------------------------------------------- - -// TODO Move to status.go or node.go -func Status() (*ctypes.ResultStatus, error) { - latestHeight := blockStore.Height() - var ( - latestBlockMeta *types.BlockMeta - latestBlockHash []byte - latestBlockTime int64 - ) - if latestHeight != 0 { - latestBlockMeta = blockStore.LoadBlockMeta(latestHeight) - latestBlockHash = latestBlockMeta.Hash - latestBlockTime = latestBlockMeta.Header.Time.UnixNano() - } - - return &ctypes.ResultStatus{ - NodeInfo: p2pSwitch.NodeInfo(), - PubKey: privValidator.PubKey, - LatestBlockHash: latestBlockHash, - LatestBlockHeight: latestHeight, - LatestBlockTime: latestBlockTime}, nil -} - -//----------------------------------------------------------------------------- - -func NetInfo() (*ctypes.ResultNetInfo, error) { - listening := p2pSwitch.IsListening() - listeners := []string{} - for _, listener := range p2pSwitch.Listeners() { - listeners = append(listeners, listener.String()) - } - peers := []ctypes.Peer{} - for _, peer := range p2pSwitch.Peers().List() { - peers = append(peers, ctypes.Peer{ - NodeInfo: *peer.NodeInfo, - IsOutbound: peer.IsOutbound(), - }) - } - return &ctypes.ResultNetInfo{ - Listening: listening, - Listeners: listeners, - Peers: peers, - }, nil -} - -//----------------------------------------------------------------------------- - -func Genesis() (*ctypes.ResultGenesis, error) { - return &ctypes.ResultGenesis{genDoc}, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/pipe.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/pipe.go deleted file mode 100644 index 98ec21ec948f38b7b156b94ad9c08dca833bd8ae..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/pipe.go +++ /dev/null @@ -1,45 +0,0 @@ -package core - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - bc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/blockchain" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus" - mempl "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/mempool" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -var blockStore *bc.BlockStore -var consensusState *consensus.ConsensusState -var consensusReactor *consensus.ConsensusReactor -var mempoolReactor *mempl.MempoolReactor -var p2pSwitch *p2p.Switch -var privValidator *types.PrivValidator -var genDoc *types.GenesisDoc // cache the genesis structure - -func SetBlockStore(bs *bc.BlockStore) { - blockStore = bs -} - -func SetConsensusState(cs *consensus.ConsensusState) { - consensusState = cs -} - -func SetConsensusReactor(cr *consensus.ConsensusReactor) { - consensusReactor = cr -} - -func SetMempoolReactor(mr *mempl.MempoolReactor) { - mempoolReactor = mr -} - -func SetSwitch(sw *p2p.Switch) { - p2pSwitch = sw -} - -func SetPrivValidator(pv *types.PrivValidator) { - privValidator = pv -} - -func SetGenesisDoc(doc *types.GenesisDoc) { - genDoc = doc -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/routes.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/routes.go deleted file mode 100644 index dcbde19281e0ebd0ecbddc870608ff8f39b05e46..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/routes.go +++ /dev/null @@ -1,19 +0,0 @@ -package core - -import ( - rpc "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server" -) - -// TODO: eliminate redundancy between here and reading code from core/ -var Routes = map[string]*rpc.RPCFunc{ - "status": rpc.NewRPCFunc(Status, []string{}), - "net_info": rpc.NewRPCFunc(NetInfo, []string{}), - "blockchain": rpc.NewRPCFunc(BlockchainInfo, []string{"minHeight", "maxHeight"}), - "genesis": rpc.NewRPCFunc(Genesis, []string{}), - "get_block": rpc.NewRPCFunc(GetBlock, []string{"height"}), - "list_validators": rpc.NewRPCFunc(ListValidators, []string{}), - "dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, []string{}), - "broadcast_tx": rpc.NewRPCFunc(BroadcastTx, []string{"tx"}), - "list_unconfirmed_txs": rpc.NewRPCFunc(ListUnconfirmedTxs, []string{}), - // subscribe/unsubscribe are reserved for websocket events. -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types/responses.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types/responses.go deleted file mode 100644 index 702b9eca62b6a93dda9847b9404d0e3d4393865b..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types/responses.go +++ /dev/null @@ -1,104 +0,0 @@ -package core_types - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -type ResultBlockchainInfo struct { - LastHeight int `json:"last_height"` - BlockMetas []*types.BlockMeta `json:"block_metas"` -} - -type ResultGetBlock struct { - BlockMeta *types.BlockMeta `json:"block_meta"` - Block *types.Block `json:"block"` -} - -type ResultStatus struct { - NodeInfo *p2p.NodeInfo `json:"node_info"` - PubKey crypto.PubKey `json:"pub_key"` - LatestBlockHash []byte `json:"latest_block_hash"` - LatestBlockHeight int `json:"latest_block_height"` - LatestBlockTime int64 `json:"latest_block_time"` // nano -} - -type ResultNetInfo struct { - Listening bool `json:"listening"` - Listeners []string `json:"listeners"` - Peers []Peer `json:"peers"` -} - -type Peer struct { - p2p.NodeInfo `json:"node_info"` - IsOutbound bool `json:"is_outbound"` -} - -type ResultListValidators struct { - BlockHeight int `json:"block_height"` - Validators []*types.Validator `json:"validators"` -} - -type ResultDumpConsensusState struct { - RoundState string `json:"round_state"` - PeerRoundStates []string `json:"peer_round_states"` -} - -type ResultBroadcastTx struct { -} - -type ResultListUnconfirmedTxs struct { - N int `json:"n_txs"` - Txs []types.Tx `json:"txs"` -} - -type ResultGenesis struct { - Genesis *types.GenesisDoc `json:"genesis"` -} - -type ResultEvent struct { - Event string `json:"event"` - Data types.EventData `json:"data"` -} - -//---------------------------------------- -// response & result types - -type Response struct { - JSONRPC string `json:"jsonrpc"` - ID string `json:"id"` - Result Result `json:"result"` - Error string `json:"error"` -} - -const ( - ResultTypeBlockchainInfo = byte(0x05) - ResultTypeGetBlock = byte(0x06) - ResultTypeStatus = byte(0x07) - ResultTypeNetInfo = byte(0x08) - ResultTypeListValidators = byte(0x09) - ResultTypeDumpConsensusState = byte(0x0A) - ResultTypeBroadcastTx = byte(0x0E) - ResultTypeListUnconfirmedTxs = byte(0x0F) - ResultTypeGenesis = byte(0x11) - ResultTypeEvent = byte(0x13) // so websockets can respond to rpc functions -) - -type Result interface{} - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ Result }{}, - wire.ConcreteType{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo}, - wire.ConcreteType{&ResultGetBlock{}, ResultTypeGetBlock}, - wire.ConcreteType{&ResultStatus{}, ResultTypeStatus}, - wire.ConcreteType{&ResultNetInfo{}, ResultTypeNetInfo}, - wire.ConcreteType{&ResultListValidators{}, ResultTypeListValidators}, - wire.ConcreteType{&ResultDumpConsensusState{}, ResultTypeDumpConsensusState}, - wire.ConcreteType{&ResultBroadcastTx{}, ResultTypeBroadcastTx}, - wire.ConcreteType{&ResultListUnconfirmedTxs{}, ResultTypeListUnconfirmedTxs}, - wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis}, - wire.ConcreteType{&ResultEvent{}, ResultTypeEvent}, -) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/handlers.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/handlers.go deleted file mode 100644 index 42e592856a30781ede116085101320e4d35eda27..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/handlers.go +++ /dev/null @@ -1,516 +0,0 @@ -package rpcserver - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "net/http" - "reflect" - "sort" - "time" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gorilla/websocket" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -func RegisterRPCFuncs(mux *http.ServeMux, funcMap map[string]*RPCFunc) { - // HTTP endpoints - for funcName, rpcFunc := range funcMap { - mux.HandleFunc("/"+funcName, makeHTTPHandler(rpcFunc)) - } - - // JSONRPC endpoints - mux.HandleFunc("/", makeJSONRPCHandler(funcMap)) -} - -//------------------------------------- -// function introspection - -// holds all type information for each function -type RPCFunc struct { - f reflect.Value // underlying rpc function - args []reflect.Type // type of each function arg - returns []reflect.Type // type of each return arg - argNames []string // name of each argument -} - -// wraps a function for quicker introspection -func NewRPCFunc(f interface{}, args []string) *RPCFunc { - return &RPCFunc{ - f: reflect.ValueOf(f), - args: funcArgTypes(f), - returns: funcReturnTypes(f), - argNames: args, - } -} - -// return a function's argument types -func funcArgTypes(f interface{}) []reflect.Type { - t := reflect.TypeOf(f) - n := t.NumIn() - typez := make([]reflect.Type, n) - for i := 0; i < n; i++ { - typez[i] = t.In(i) - } - return typez -} - -// return a function's return types -func funcReturnTypes(f interface{}) []reflect.Type { - t := reflect.TypeOf(f) - n := t.NumOut() - typez := make([]reflect.Type, n) - for i := 0; i < n; i++ { - typez[i] = t.Out(i) - } - return typez -} - -// function introspection -//----------------------------------------------------------------------------- -// rpc.json - -// jsonrpc calls grab the given method's function info and runs reflect.Call -func makeJSONRPCHandler(funcMap map[string]*RPCFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - b, _ := ioutil.ReadAll(r.Body) - // if its an empty request (like from a browser), - // just display a list of functions - if len(b) == 0 { - writeListOfEndpoints(w, r, funcMap) - return - } - - var request RPCRequest - err := json.Unmarshal(b, &request) - if err != nil { - WriteRPCResponse(w, NewRPCResponse("", nil, err.Error())) - return - } - if len(r.URL.Path) > 1 { - WriteRPCResponse(w, NewRPCResponse(request.ID, nil, fmt.Sprintf("Invalid JSONRPC endpoint %s", r.URL.Path))) - return - } - rpcFunc := funcMap[request.Method] - if rpcFunc == nil { - WriteRPCResponse(w, NewRPCResponse(request.ID, nil, "RPC method unknown: "+request.Method)) - return - } - args, err := jsonParamsToArgs(rpcFunc, request.Params) - if err != nil { - WriteRPCResponse(w, NewRPCResponse(request.ID, nil, err.Error())) - return - } - returns := rpcFunc.f.Call(args) - log.Info("HTTPJSONRPC", "method", request.Method, "args", args, "returns", returns) - result, err := unreflectResult(returns) - if err != nil { - WriteRPCResponse(w, NewRPCResponse(request.ID, nil, err.Error())) - return - } - WriteRPCResponse(w, NewRPCResponse(request.ID, result, "")) - } -} - -// covert a list of interfaces to properly typed values -func jsonParamsToArgs(rpcFunc *RPCFunc, params []interface{}) ([]reflect.Value, error) { - if len(rpcFunc.argNames) != len(params) { - return nil, errors.New(fmt.Sprintf("Expected %v parameters (%v), got %v (%v)", - len(rpcFunc.argNames), rpcFunc.argNames, len(params), params)) - } - values := make([]reflect.Value, len(params)) - for i, p := range params { - ty := rpcFunc.args[i] - v, err := _jsonObjectToArg(ty, p) - if err != nil { - return nil, err - } - values[i] = v - } - return values, nil -} - -func _jsonObjectToArg(ty reflect.Type, object interface{}) (reflect.Value, error) { - var err error - v := reflect.New(ty) - wire.ReadJSONObjectPtr(v.Interface(), object, &err) - if err != nil { - return v, err - } - v = v.Elem() - return v, nil -} - -// rpc.json -//----------------------------------------------------------------------------- -// rpc.http - -// convert from a function name to the http handler -func makeHTTPHandler(rpcFunc *RPCFunc) func(http.ResponseWriter, *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - args, err := httpParamsToArgs(rpcFunc, r) - if err != nil { - WriteRPCResponse(w, NewRPCResponse("", nil, err.Error())) - return - } - returns := rpcFunc.f.Call(args) - log.Info("HTTPRestRPC", "method", r.URL.Path, "args", args, "returns", returns) - result, err := unreflectResult(returns) - if err != nil { - WriteRPCResponse(w, NewRPCResponse("", nil, err.Error())) - return - } - WriteRPCResponse(w, NewRPCResponse("", result, "")) - } -} - -// Covert an http query to a list of properly typed values. -// To be properly decoded the arg must be a concrete type from tendermint (if its an interface). -func httpParamsToArgs(rpcFunc *RPCFunc, r *http.Request) ([]reflect.Value, error) { - argTypes := rpcFunc.args - argNames := rpcFunc.argNames - - var err error - values := make([]reflect.Value, len(argNames)) - for i, name := range argNames { - ty := argTypes[i] - arg := GetParam(r, name) - values[i], err = _jsonStringToArg(ty, arg) - if err != nil { - return nil, err - } - } - return values, nil -} - -func _jsonStringToArg(ty reflect.Type, arg string) (reflect.Value, error) { - var err error - v := reflect.New(ty) - wire.ReadJSONPtr(v.Interface(), []byte(arg), &err) - if err != nil { - return v, err - } - v = v.Elem() - return v, nil -} - -// rpc.http -//----------------------------------------------------------------------------- -// rpc.websocket - -const ( - writeChanCapacity = 20 - wsWriteTimeoutSeconds = 30 // each write times out after this - wsReadTimeoutSeconds = 30 // connection times out if we haven't received *anything* in this long, not even pings. - wsPingTickerSeconds = 10 // send a ping every PingTickerSeconds. -) - -// a single websocket connection -// contains listener id, underlying ws connection, -// and the event switch for subscribing to events -type WSConnection struct { - QuitService - - id string - baseConn *websocket.Conn - writeChan chan RPCResponse - readTimeout *time.Timer - pingTicker *time.Ticker - - funcMap map[string]*RPCFunc - evsw *events.EventSwitch -} - -// new websocket connection wrapper -func NewWSConnection(baseConn *websocket.Conn, funcMap map[string]*RPCFunc, evsw *events.EventSwitch) *WSConnection { - wsc := &WSConnection{ - id: baseConn.RemoteAddr().String(), - baseConn: baseConn, - writeChan: make(chan RPCResponse, writeChanCapacity), // error when full. - funcMap: funcMap, - evsw: evsw, - } - wsc.QuitService = *NewQuitService(log, "WSConnection", wsc) - return wsc -} - -// wsc.Start() blocks until the connection closes. -func (wsc *WSConnection) OnStart() error { - wsc.QuitService.OnStart() - - // Read subscriptions/unsubscriptions to events - go wsc.readRoutine() - - // Custom Ping handler to touch readTimeout - wsc.readTimeout = time.NewTimer(time.Second * wsReadTimeoutSeconds) - wsc.pingTicker = time.NewTicker(time.Second * wsPingTickerSeconds) - wsc.baseConn.SetPingHandler(func(m string) error { - wsc.baseConn.WriteControl(websocket.PongMessage, []byte(m), time.Now().Add(time.Second*wsWriteTimeoutSeconds)) - wsc.readTimeout.Reset(time.Second * wsReadTimeoutSeconds) - return nil - }) - wsc.baseConn.SetPongHandler(func(m string) error { - wsc.readTimeout.Reset(time.Second * wsReadTimeoutSeconds) - return nil - }) - go wsc.readTimeoutRoutine() - - // Write responses, BLOCKING. - wsc.writeRoutine() - return nil -} - -func (wsc *WSConnection) OnStop() { - wsc.QuitService.OnStop() - wsc.evsw.RemoveListener(wsc.id) - wsc.readTimeout.Stop() - wsc.pingTicker.Stop() - // The write loop closes the websocket connection - // when it exits its loop, and the read loop - // closes the writeChan -} - -func (wsc *WSConnection) readTimeoutRoutine() { - select { - case <-wsc.readTimeout.C: - log.Notice("Stopping connection due to read timeout") - wsc.Stop() - case <-wsc.Quit: - return - } -} - -// Attempt to write response to writeChan and record failures -func (wsc *WSConnection) writeRPCResponse(resp RPCResponse) { - select { - case wsc.writeChan <- resp: - default: - log.Notice("Stopping connection due to writeChan overflow", "id", wsc.id) - wsc.Stop() // writeChan capacity exceeded, error. - } -} - -// Read from the socket and subscribe to or unsubscribe from events -func (wsc *WSConnection) readRoutine() { - // Do not close writeChan, to allow writeRPCResponse() to fail. - // defer close(wsc.writeChan) - - for { - select { - case <-wsc.Quit: - return - default: - var in []byte - // Do not set a deadline here like below: - // wsc.baseConn.SetReadDeadline(time.Now().Add(time.Second * wsReadTimeoutSeconds)) - // The client may not send anything for a while. - // We use `readTimeout` to handle read timeouts. - _, in, err := wsc.baseConn.ReadMessage() - if err != nil { - log.Notice("Failed to read from connection", "id", wsc.id) - // an error reading the connection, - // kill the connection - wsc.Stop() - return - } - var request RPCRequest - err = json.Unmarshal(in, &request) - if err != nil { - errStr := fmt.Sprintf("Error unmarshaling data: %s", err.Error()) - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, errStr)) - continue - } - switch request.Method { - case "subscribe": - if len(request.Params) != 1 { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "subscribe takes 1 event parameter string")) - continue - } - if event, ok := request.Params[0].(string); !ok { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "subscribe takes 1 event parameter string")) - continue - } else { - log.Notice("Subscribe to event", "id", wsc.id, "event", event) - wsc.evsw.AddListenerForEvent(wsc.id, event, func(msg types.EventData) { - // NOTE: RPCResponses of subscribed events have id suffix "#event" - wsc.writeRPCResponse(NewRPCResponse(request.ID+"#event", ctypes.ResultEvent{event, msg}, "")) - }) - continue - } - case "unsubscribe": - if len(request.Params) == 0 { - log.Notice("Unsubscribe from all events", "id", wsc.id) - wsc.evsw.RemoveListener(wsc.id) - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "")) - continue - } else if len(request.Params) == 1 { - if event, ok := request.Params[0].(string); !ok { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "unsubscribe takes 0 or 1 event parameter strings")) - continue - } else { - log.Notice("Unsubscribe from event", "id", wsc.id, "event", event) - wsc.evsw.RemoveListenerForEvent(event, wsc.id) - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "")) - continue - } - } else { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "unsubscribe takes 0 or 1 event parameter strings")) - continue - } - default: - rpcFunc := wsc.funcMap[request.Method] - if rpcFunc == nil { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, "RPC method unknown: "+request.Method)) - continue - } - args, err := jsonParamsToArgs(rpcFunc, request.Params) - if err != nil { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, err.Error())) - continue - } - returns := rpcFunc.f.Call(args) - log.Info("WSJSONRPC", "method", request.Method, "args", args, "returns", returns) - result, err := unreflectResult(returns) - if err != nil { - wsc.writeRPCResponse(NewRPCResponse(request.ID, nil, err.Error())) - continue - } else { - wsc.writeRPCResponse(NewRPCResponse(request.ID, result, "")) - continue - } - } - } - } -} - -// receives on a write channel and writes out on the socket -func (wsc *WSConnection) writeRoutine() { - defer wsc.baseConn.Close() - var n, err = int(0), error(nil) - for { - select { - case <-wsc.Quit: - return - case <-wsc.pingTicker.C: - err := wsc.baseConn.WriteMessage(websocket.PingMessage, []byte{}) - if err != nil { - log.Error("Failed to write ping message on websocket", "error", err) - wsc.Stop() - return - } - case msg := <-wsc.writeChan: - buf := new(bytes.Buffer) - wire.WriteJSON(msg, buf, &n, &err) - if err != nil { - log.Error("Failed to marshal RPCResponse to JSON", "error", err) - } else { - wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds)) - if err = wsc.baseConn.WriteMessage(websocket.TextMessage, buf.Bytes()); err != nil { - log.Warn("Failed to write response on websocket", "error", err) - wsc.Stop() - return - } - } - } - } -} - -//---------------------------------------- - -// Main manager for all websocket connections -// Holds the event switch -// NOTE: The websocket path is defined externally, e.g. in node/node.go -type WebsocketManager struct { - websocket.Upgrader - funcMap map[string]*RPCFunc - evsw *events.EventSwitch -} - -func NewWebsocketManager(funcMap map[string]*RPCFunc, evsw *events.EventSwitch) *WebsocketManager { - return &WebsocketManager{ - funcMap: funcMap, - evsw: evsw, - Upgrader: websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - CheckOrigin: func(r *http.Request) bool { - // TODO - return true - }, - }, - } -} - -// Upgrade the request/response (via http.Hijack) and starts the WSConnection. -func (wm *WebsocketManager) WebsocketHandler(w http.ResponseWriter, r *http.Request) { - wsConn, err := wm.Upgrade(w, r, nil) - if err != nil { - // TODO - return http error - log.Error("Failed to upgrade to websocket connection", "error", err) - return - } - - // register connection - con := NewWSConnection(wsConn, wm.funcMap, wm.evsw) - log.Notice("New websocket connection", "origin", con.id) - con.Start() // Blocking -} - -// rpc.websocket -//----------------------------------------------------------------------------- - -// returns is result struct and error. If error is not nil, return it -func unreflectResult(returns []reflect.Value) (interface{}, error) { - errV := returns[1] - if errV.Interface() != nil { - return nil, fmt.Errorf("%v", errV.Interface()) - } - return returns[0].Interface(), nil -} - -// writes a list of available rpc endpoints as an html page -func writeListOfEndpoints(w http.ResponseWriter, r *http.Request, funcMap map[string]*RPCFunc) { - noArgNames := []string{} - argNames := []string{} - for name, funcData := range funcMap { - if len(funcData.args) == 0 { - noArgNames = append(noArgNames, name) - } else { - argNames = append(argNames, name) - } - } - sort.Strings(noArgNames) - sort.Strings(argNames) - buf := new(bytes.Buffer) - buf.WriteString("<html><body>") - buf.WriteString("<br>Available endpoints:<br>") - - for _, name := range noArgNames { - link := fmt.Sprintf("http://%s/%s", r.Host, name) - buf.WriteString(fmt.Sprintf("<a href=\"%s\">%s</a></br>", link, link)) - } - - buf.WriteString("<br>Endpoints that require arguments:<br>") - for _, name := range argNames { - link := fmt.Sprintf("http://%s/%s?", r.Host, name) - funcData := funcMap[name] - for i, argName := range funcData.argNames { - link += argName + "=_" - if i < len(funcData.argNames)-1 { - link += "&" - } - } - buf.WriteString(fmt.Sprintf("<a href=\"%s\">%s</a></br>", link, link)) - } - buf.WriteString("</body></html>") - w.Header().Set("Content-Type", "text/html") - w.WriteHeader(200) - w.Write(buf.Bytes()) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_params.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_params.go deleted file mode 100644 index acf5b4c8ca6203752172f80af105e18f9c75853e..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_params.go +++ /dev/null @@ -1,89 +0,0 @@ -package rpcserver - -import ( - "encoding/hex" - "fmt" - "net/http" - "regexp" - "strconv" -) - -var ( - // Parts of regular expressions - atom = "[A-Z0-9!#$%&'*+\\-/=?^_`{|}~]+" - dotAtom = atom + `(?:\.` + atom + `)*` - domain = `[A-Z0-9.-]+\.[A-Z]{2,4}` - - RE_HEX = regexp.MustCompile(`^(?i)[a-f0-9]+$`) - RE_EMAIL = regexp.MustCompile(`^(?i)(` + dotAtom + `)@(` + dotAtom + `)$`) - RE_ADDRESS = regexp.MustCompile(`^(?i)[a-z0-9]{25,34}$`) - RE_HOST = regexp.MustCompile(`^(?i)(` + domain + `)$`) - - //RE_ID12 = regexp.MustCompile(`^[a-zA-Z0-9]{12}$`) -) - -func GetParam(r *http.Request, param string) string { - s := r.URL.Query().Get(param) - if s == "" { - s = r.FormValue(param) - } - return s -} - -func GetParamByteSlice(r *http.Request, param string) ([]byte, error) { - s := GetParam(r, param) - return hex.DecodeString(s) -} - -func GetParamInt64(r *http.Request, param string) (int64, error) { - s := GetParam(r, param) - i, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return i, nil -} - -func GetParamInt32(r *http.Request, param string) (int32, error) { - s := GetParam(r, param) - i, err := strconv.ParseInt(s, 10, 32) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return int32(i), nil -} - -func GetParamUint64(r *http.Request, param string) (uint64, error) { - s := GetParam(r, param) - i, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return i, nil -} - -func GetParamUint(r *http.Request, param string) (uint, error) { - s := GetParam(r, param) - i, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return uint(i), nil -} - -func GetParamRegexp(r *http.Request, param string, re *regexp.Regexp) (string, error) { - s := GetParam(r, param) - if !re.MatchString(s) { - return "", fmt.Errorf(param, "Did not match regular expression %v", re.String()) - } - return s, nil -} - -func GetParamFloat64(r *http.Request, param string) (float64, error) { - s := GetParam(r, param) - f, err := strconv.ParseFloat(s, 64) - if err != nil { - return 0, fmt.Errorf(param, err.Error()) - } - return f, nil -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_server.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_server.go deleted file mode 100644 index f3e4b2ce8fb040677c92f575304f8ffbe8fc1fc3..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/http_server.go +++ /dev/null @@ -1,121 +0,0 @@ -// Commons for HTTP handling -package rpcserver - -import ( - "bufio" - "bytes" - "fmt" - "net" - "net/http" - "runtime/debug" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/alert" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types" -) - -func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, error) { - log.Notice(Fmt("Starting RPC HTTP server on %v", listenAddr)) - listener, err := net.Listen("tcp", listenAddr) - if err != nil { - return nil, fmt.Errorf("Failed to listen to %v", listenAddr) - } - go func() { - res := http.Serve( - listener, - RecoverAndLogHandler(handler), - ) - log.Crit("RPC HTTP server stopped", "result", res) - }() - return listener, nil -} - -func WriteRPCResponse(w http.ResponseWriter, res RPCResponse) { - buf, n, err := new(bytes.Buffer), int(0), error(nil) - wire.WriteJSON(res, buf, &n, &err) - if err != nil { - log.Error("Failed to write RPC response", "error", err, "res", res) - } - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - w.Write(buf.Bytes()) -} - -//----------------------------------------------------------------------------- - -// Wraps an HTTP handler, adding error logging. -// If the inner function panics, the outer function recovers, logs, sends an -// HTTP 500 error response. -func RecoverAndLogHandler(handler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Wrap the ResponseWriter to remember the status - rww := &ResponseWriterWrapper{-1, w} - begin := time.Now() - - // Common headers - origin := r.Header.Get("Origin") - rww.Header().Set("Access-Control-Allow-Origin", origin) - rww.Header().Set("Access-Control-Allow-Credentials", "true") - rww.Header().Set("Access-Control-Expose-Headers", "X-Server-Time") - rww.Header().Set("X-Server-Time", fmt.Sprintf("%v", begin.Unix())) - - defer func() { - // Send a 500 error if a panic happens during a handler. - // Without this, Chrome & Firefox were retrying aborted ajax requests, - // at least to my localhost. - if e := recover(); e != nil { - - // If RPCResponse - if res, ok := e.(RPCResponse); ok { - WriteRPCResponse(rww, res) - } else { - // For the rest, - log.Error("Panic in RPC HTTP handler", "error", e, "stack", string(debug.Stack())) - rww.WriteHeader(http.StatusInternalServerError) - WriteRPCResponse(rww, NewRPCResponse("", nil, Fmt("Internal Server Error: %v", e))) - } - } - - // Finally, log. - durationMS := time.Since(begin).Nanoseconds() / 1000000 - if rww.Status == -1 { - rww.Status = 200 - } - log.Info("Served RPC HTTP response", - "method", r.Method, "url", r.URL, - "status", rww.Status, "duration", durationMS, - "remoteAddr", r.RemoteAddr, - ) - }() - - handler.ServeHTTP(rww, r) - }) -} - -// Remember the status for logging -type ResponseWriterWrapper struct { - Status int - http.ResponseWriter -} - -func (w *ResponseWriterWrapper) WriteHeader(status int) { - w.Status = status - w.ResponseWriter.WriteHeader(status) -} - -// implements http.Hijacker -func (w *ResponseWriterWrapper) Hijack() (net.Conn, *bufio.ReadWriter, error) { - return w.ResponseWriter.(http.Hijacker).Hijack() -} - -// Stick it as a deferred statement in gouroutines to prevent the program from crashing. -func Recover(daemonName string) { - if e := recover(); e != nil { - stack := string(debug.Stack()) - errorString := fmt.Sprintf("[%s] %s\n%s", daemonName, e, stack) - alert.Alert(errorString) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/log.go deleted file mode 100644 index aab9721fd941db6ddd8080281ef57372b8f4d17e..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/server/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package rpcserver - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" -) - -var log = log15.New("module", "rpcserver") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types/types.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types/types.go deleted file mode 100644 index c93e6735babf6137032a1dfad8fe0d2e2e8fe19b..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/types/types.go +++ /dev/null @@ -1,24 +0,0 @@ -package rpctypes - -type RPCRequest struct { - JSONRPC string `json:"jsonrpc"` - ID string `json:"id"` - Method string `json:"method"` - Params []interface{} `json:"params"` -} - -type RPCResponse struct { - JSONRPC string `json:"jsonrpc"` - ID string `json:"id"` - Result interface{} `json:"result"` - Error string `json:"error"` -} - -func NewRPCResponse(id string, res interface{}, err string) RPCResponse { - return RPCResponse{ - JSONRPC: "2.0", - ID: id, - Result: res, - Error: err, - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/version.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/version.go deleted file mode 100644 index 2982824dd963c5f1af0083f7990bf8af471d2588..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/version.go +++ /dev/null @@ -1,3 +0,0 @@ -package rpc - -const Version = "0.4.0" diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go deleted file mode 100644 index f323c19b3af44e0e8d86e17af78f69cf65fd8773..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/execution.go +++ /dev/null @@ -1,181 +0,0 @@ -package state - -import ( - "bytes" - "errors" - "fmt" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/proxy" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" -) - -// Execute the block to mutate State. -// Also, execute txs on the proxyAppCtx and validate apphash -// Rolls back before executing transactions. -// Rolls back if invalid, but never commits. -func (s *State) ExecBlock(proxyAppCtx proxy.AppContext, block *types.Block, blockPartsHeader types.PartSetHeader) error { - - // Validate the block. - err := s.validateBlock(block) - if err != nil { - return err - } - - // Update the validator set - valSet := s.Validators.Copy() - // Update valSet with signatures from block. - updateValidatorsWithBlock(s.LastValidators, valSet, block) - // TODO: Update the validator set (e.g. block.Data.ValidatorUpdates?) - nextValSet := valSet.Copy() - - // First, rollback. - if err != nil { - proxyAppCtx.RollbackSync() - return err - } - - // Execute, or rollback. (Does not commit) - err = s.execBlockOnProxyApp(proxyAppCtx, block) - if err != nil { - proxyAppCtx.RollbackSync() - return err - } - - // All good! - nextValSet.IncrementAccum(1) - s.Validators = nextValSet - s.LastValidators = valSet - s.LastAppHash = block.AppHash - s.LastBlockHeight = block.Height - s.LastBlockHash = block.Hash() - s.LastBlockParts = blockPartsHeader - s.LastBlockTime = block.Time - - return nil -} - -// Commits block on proxyAppCtx. -func (s *State) Commit(proxyAppCtx proxy.AppContext) error { - err := proxyAppCtx.CommitSync() - return err -} - -// Executes transactions on proxyAppCtx. -func (s *State) execBlockOnProxyApp(proxyAppCtx proxy.AppContext, block *types.Block) error { - // Execute transactions and get hash - var invalidTxErr error - proxyCb := func(req tmsp.Request, res tmsp.Response) { - switch res := res.(type) { - case tmsp.ResponseAppendTx: - reqAppendTx := req.(tmsp.RequestAppendTx) - if res.RetCode != tmsp.RetCodeOK { - if invalidTxErr == nil { - invalidTxErr = InvalidTxError{reqAppendTx.TxBytes, res.RetCode} - } - } - case tmsp.ResponseEvent: - s.evc.FireEvent(types.EventStringApp(), types.EventDataApp{res.Key, res.Data}) - } - } - proxyAppCtx.SetResponseCallback(proxyCb) - for _, tx := range block.Data.Txs { - proxyAppCtx.AppendTxAsync(tx) - if err := proxyAppCtx.Error(); err != nil { - return err - } - } - hash, err := proxyAppCtx.GetHashSync() - if err != nil { - log.Warn("Error computing proxyAppCtx hash", "error", err) - return err - } - if invalidTxErr != nil { - log.Warn("Invalid transaction in block") - return invalidTxErr - } - - // Check that appHash matches - if !bytes.Equal(block.AppHash, hash) { - log.Warn(Fmt("App hash in proposal was %X, computed %X instead", block.AppHash, hash)) - return InvalidAppHashError{block.AppHash, hash} - } - - return nil -} - -func (s *State) validateBlock(block *types.Block) error { - // Basic block validation. - err := block.ValidateBasic(s.ChainID, s.LastBlockHeight, s.LastBlockHash, s.LastBlockParts, s.LastBlockTime) - if err != nil { - return err - } - - // Validate block LastValidation. - if block.Height == 1 { - if len(block.LastValidation.Precommits) != 0 { - return errors.New("Block at height 1 (first block) should have no LastValidation precommits") - } - } else { - if len(block.LastValidation.Precommits) != s.LastValidators.Size() { - return fmt.Errorf("Invalid block validation size. Expected %v, got %v", - s.LastValidators.Size(), len(block.LastValidation.Precommits)) - } - err := s.LastValidators.VerifyValidation( - s.ChainID, s.LastBlockHash, s.LastBlockParts, block.Height-1, block.LastValidation) - if err != nil { - return err - } - } - - return nil -} - -// Updates the LastCommitHeight of the validators in valSet, in place. -// Assumes that lastValSet matches the valset of block.LastValidators -// CONTRACT: lastValSet is not mutated. -func updateValidatorsWithBlock(lastValSet *types.ValidatorSet, valSet *types.ValidatorSet, block *types.Block) { - - for i, precommit := range block.LastValidation.Precommits { - if precommit == nil { - continue - } - _, val := lastValSet.GetByIndex(i) - if val == nil { - PanicCrisis(Fmt("Failed to fetch validator at index %v", i)) - } - if _, val_ := valSet.GetByAddress(val.Address); val_ != nil { - val_.LastCommitHeight = block.Height - 1 - updated := valSet.Update(val_) - if !updated { - PanicCrisis("Failed to update validator LastCommitHeight") - } - } else { - // XXX This is not an error if validator was removed. - // But, we don't mutate validators yet so go ahead and panic. - PanicCrisis("Could not find validator") - } - } - -} - -//----------------------------------------------------------------------------- - -type InvalidTxError struct { - Tx types.Tx - tmsp.RetCode -} - -func (txErr InvalidTxError) Error() string { - return Fmt("Invalid tx: [%v] code: [%v]", txErr.Tx, txErr.RetCode) -} - -type InvalidAppHashError struct { - Expected []byte - Got []byte -} - -func (hashErr InvalidAppHashError) Error() string { - return Fmt("Invalid hash: [%X] got: [%X]", hashErr.Expected, hashErr.Got) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go deleted file mode 100644 index 316471eac6339438fca259c340423dea26e2f131..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package state - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "state") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go deleted file mode 100644 index e890ea8cd6b389115598194377faf1b1a84514df..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/state.go +++ /dev/null @@ -1,139 +0,0 @@ -package state - -import ( - "bytes" - "io/ioutil" - "sync" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" -) - -var ( - stateKey = []byte("stateKey") -) - -//----------------------------------------------------------------------------- - -// NOTE: not goroutine-safe. -type State struct { - mtx sync.Mutex - db dbm.DB - GenesisDoc *types.GenesisDoc - ChainID string - LastBlockHeight int - LastBlockHash []byte - LastBlockParts types.PartSetHeader - LastBlockTime time.Time - Validators *types.ValidatorSet - LastValidators *types.ValidatorSet - LastAppHash []byte - - evc events.Fireable // typically an events.EventCache -} - -func LoadState(db dbm.DB) *State { - s := &State{db: db} - buf := db.Get(stateKey) - if len(buf) == 0 { - return nil - } else { - r, n, err := bytes.NewReader(buf), new(int), new(error) - wire.ReadBinaryPtr(&s, r, 0, n, err) - if *err != nil { - // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED - Exit(Fmt("Data has been corrupted or its spec has changed: %v\n", *err)) - } - // TODO: ensure that buf is completely read. - } - return s -} - -func (s *State) Copy() *State { - return &State{ - db: s.db, - GenesisDoc: s.GenesisDoc, - ChainID: s.ChainID, - LastBlockHeight: s.LastBlockHeight, - LastBlockHash: s.LastBlockHash, - LastBlockParts: s.LastBlockParts, - LastBlockTime: s.LastBlockTime, - Validators: s.Validators.Copy(), - LastValidators: s.LastValidators.Copy(), - LastAppHash: s.LastAppHash, - evc: nil, - } -} - -func (s *State) Save() { - s.mtx.Lock() - defer s.mtx.Unlock() - - buf, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(s, buf, n, err) - if *err != nil { - PanicCrisis(*err) - } - s.db.Set(stateKey, buf.Bytes()) -} - -// Implements events.Eventable. Typically uses events.EventCache -func (s *State) SetFireable(evc events.Fireable) { - s.mtx.Lock() - defer s.mtx.Unlock() - - s.evc = evc -} - -//----------------------------------------------------------------------------- -// Genesis - -func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) *State { - genDocJSON, err := ioutil.ReadFile(genDocFile) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) - } - genDoc := types.GenesisDocFromJSON(genDocJSON) - return MakeGenesisState(db, genDoc) -} - -func MakeGenesisState(db dbm.DB, genDoc *types.GenesisDoc) *State { - if len(genDoc.Validators) == 0 { - Exit(Fmt("The genesis file has no validators")) - } - - if genDoc.GenesisTime.IsZero() { - genDoc.GenesisTime = time.Now() - } - - // Make validators slice - validators := make([]*types.Validator, len(genDoc.Validators)) - for i, val := range genDoc.Validators { - pubKey := val.PubKey - address := pubKey.Address() - - // Make validator - validators[i] = &types.Validator{ - Address: address, - PubKey: pubKey, - VotingPower: val.Amount, - } - } - - return &State{ - db: db, - GenesisDoc: genDoc, - ChainID: genDoc.ChainID, - LastBlockHeight: 0, - LastBlockHash: nil, - LastBlockParts: types.PartSetHeader{}, - LastBlockTime: genDoc.GenesisTime, - Validators: types.NewValidatorSet(validators), - LastValidators: types.NewValidatorSet(nil), - LastAppHash: genDoc.AppHash, - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf b/Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf deleted file mode 100644 index 0e10d8a5e714545eb97c2ae22cbf433a2eaaf7eb..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/state/wtf +++ /dev/null @@ -1,68 +0,0 @@ -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=send -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=call -[34mINFO[0m[07-22|18:13:12] Out account: Account{DFF89D4BE8CDDC7A1993C91A1C7FFE32D3778570:<nil> B:1536646667 C:120 S: P:{Base: 100011111110; Set: 11111111111111 []}} [34mmodule[0m=state -[34mINFO[0m[07-22|18:13:12] Calling contract 000000000000000000000000DFF89D4BE8CDDC7A1993C91A1C7FFE32D3778570 with code 60606040526000357C0100000000000000000000000000000000000000000000000000000000900480632FEE78D7146037576035565B005B6040600450606C565B604051808273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16815260200191505060405180910390F35B60003390506075565B9056 [34mmodule[0m=state -[34mINFO[0m[07-22|18:13:12] Code for this contract: 60606040526000357C0100000000000000000000000000000000000000000000000000000000900480632FEE78D7146037576035565B005B6040600450606C565B604051808273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16815260200191505060405180910390F35B60003390506075565B9056 [34mmodule[0m=state -(1) (00000000) 000000000000000000000000DFF89D4BE8CDDC7A1993C91A1C7FFE32D3778570 (code=120) gas: 1000 (d) 2FEE78D7 -(pc) 0 (op) PUSH1 (st) 0 => 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 2 (op) PUSH1 (st) 1 => 0x0000000000000000000000000000000000000000000000000000000000000040 -(pc) 4 (op) MSTORE (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 5 (op) PUSH1 (st) 0 => 0x0000000000000000000000000000000000000000000000000000000000000000 -(pc) 7 (op) CALLDATALOAD (st) 1 => 0x2FEE78D700000000000000000000000000000000000000000000000000000000 -(pc) 8 (op) PUSH29 (st) 1 => 0x0000000100000000000000000000000000000000000000000000000000000000 -(pc) 38 (op) SWAP1 (st) 2 => [2] 2FEE78D700000000000000000000000000000000000000000000000000000000 -(pc) 39 (op) DIV (st) 2 21680047490780924029029108358227327141478116379726555908761811030043504148480 / 26959946667150639794667015087019630673637144422540572481103610249216 = 804157655 (000000000000000000000000000000000000000000000000000000002FEE78D7) -(pc) 40 (op) DUP1 (st) 1 => [1] 0x000000000000000000000000000000000000000000000000000000002FEE78D7 -(pc) 41 (op) PUSH4 (st) 2 => 0x000000000000000000000000000000000000000000000000000000002FEE78D7 -(pc) 46 (op) EQ (st) 3 000000000000000000000000000000000000000000000000000000002FEE78D7 == 000000000000000000000000000000000000000000000000000000002FEE78D7 = 1 -(pc) 47 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000037 -(pc) 49 (op) JUMPI (st) 3 ~> 55 -(pc) 55 (op) JUMPDEST (st) 1 -(pc) 56 (op) PUSH1 (st) 1 => 0x0000000000000000000000000000000000000000000000000000000000000040 -(pc) 58 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000004 -(pc) 60 (op) POP (st) 3 => 10000000 -(pc) 61 (op) PUSH1 (st) 2 => 0x000000000000000000000000000000000000000000000000000000000000006C -(pc) 63 (op) JUMP (st) 3 ~> 108 -(pc) 108 (op) JUMPDEST (st) 2 -(pc) 109 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000000 -(pc) 111 (op) CALLER (st) 3 => 000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 112 (op) SWAP1 (st) 4 => [2] 0000000000000000000000000000000000000000000000000000000000000000 -(pc) 113 (op) POP (st) 4 => 10000000 -(pc) 114 (op) PUSH1 (st) 3 => 0x0000000000000000000000000000000000000000000000000000000000000075 -(pc) 116 (op) JUMP (st) 4 ~> 117 -(pc) 117 (op) JUMPDEST (st) 3 -(pc) 118 (op) SWAP1 (st) 3 => [2] 0000000000000000000000000000000000000000000000000000000000000040 -(pc) 119 (op) JUMP (st) 3 ~> 64 -(pc) 64 (op) JUMPDEST (st) 2 -(pc) 65 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000040 -(pc) 67 (op) MLOAD (st) 3 => 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 68 (op) DUP1 (st) 3 => [1] 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 69 (op) DUP3 (st) 4 => [3] 0x000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 70 (op) PUSH20 (st) 5 => 0x000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -(pc) 91 (op) AND (st) 6 000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF & 000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 = 000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 92 (op) DUP2 (st) 5 => [2] 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 93 (op) MSTORE (st) 6 => 0x000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 94 (op) PUSH1 (st) 4 => 0x0000000000000000000000000000000000000000000000000000000000000020 -(pc) 96 (op) ADD (st) 5 32 + 96 = 128 (0000000000000000000000000000000000000000000000000000000000000080) -(pc) 97 (op) SWAP2 (st) 4 => [3] 000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -(pc) 98 (op) POP (st) 4 => 10000000 -(pc) 99 (op) POP (st) 3 => 10000000 -(pc) 100 (op) PUSH1 (st) 2 => 0x0000000000000000000000000000000000000000000000000000000000000040 -(pc) 102 (op) MLOAD (st) 3 => 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 103 (op) DUP1 (st) 3 => [1] 0x0000000000000000000000000000000000000000000000000000000000000060 -(pc) 104 (op) SWAP2 (st) 4 => [3] 0000000000000000000000000000000000000000000000000000000000000080 -(pc) 105 (op) SUB (st) 4 128 - 96 = 32 (0000000000000000000000000000000000000000000000000000000000000020) -(pc) 106 (op) SWAP1 (st) 3 => [2] 0000000000000000000000000000000000000000000000000000000000000060 -(pc) 107 (op) RETURN (st) 3 => [96, 32] (32) 0x000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 -[34mINFO[0m[07-22|18:13:12] Successful execution [34mmodule[0m=state -[32mNOTE[0m[07-22|18:13:12] VM call complete [32mmodule[0m=state [32mcaller[0m="VMAccount{000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 B:1529024268 C: N:1 S:0000000000000000000000000000000000000000000000000000000000000000}" [32mcallee[0m="VMAccount{000000000000000000000000DFF89D4BE8CDDC7A1993C91A1C7FFE32D3778570 B:1536646668 C:60606040526000357C0100000000000000000000000000000000000000000000000000000000900480632FEE78D7146037576035565B005B6040600450606C565B604051808273FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16815260200191505060405180910390F35B60003390506075565B9056 N:0 S:0000000000000000000000000000000000000000000000000000000000000000}" [32mreturn[0m=000000000000000000000000C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [32merr[0m=nil -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=name -[34mINFO[0m[07-22|18:13:12] New NameTx [34mmodule[0m=state [34mvalue[0m=10000 [34mcostPerBlock[0m=1237 [34mexpiresIn[0m=8 [34mlastBlock[0m=0 -[34mINFO[0m[07-22|18:13:12] Creating namereg entry [34mmodule[0m=state [34mname[0m=satoshi [34mexpiresIn[0m=8 -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=name -[34mINFO[0m[07-22|18:13:12] Invalid characters found in NameTx.Data (�€Èû). Only the kind of things found in a JSON file are allowed [34mmodule[0m=state -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=create_account -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=bond -[34mINFO[0m[07-22|18:13:12] Account has permission [34mmodule[0m=state [34maddress[0m=C91B248EFBD6841FF1A5E1615E4661C6293A84F6 [34mperm[0m=bond -PASS -ok github.com/tendermint/tendermint/state 0.311s diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/README.md b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/README.md deleted file mode 100644 index f99294b007dd8ac4b3a453f0256d9c0aeb43d247..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# `tendermint/block` - -## Block - -TODO: document - -### Header - -### Validation - -### Data - -## PartSet - -PartSet is used to split a byteslice of data into parts (pieces) for transmission. -By splitting data into smaller parts and computing a Merkle root hash on the list, -you can verify that a part is legitimately part of the complete data, and the -part can be forwarded to other peers before all the parts are known. In short, -it's a fast way to propagate a large file over a gossip network. - -PartSet was inspired by the LibSwift project. - -Usage: - -```Go -data := RandBytes(2 << 20) // Something large - -partSet := NewPartSetFromData(data) -partSet.Total() // Total number of 4KB parts -partSet.Count() // Equal to the Total, since we already have all the parts -partSet.Hash() // The Merkle root hash -partSet.BitArray() // A BitArray of partSet.Total() 1's - -header := partSet.Header() // Send this to the peer -header.Total // Total number of parts -header.Hash // The merkle root hash - -// Now we'll reconstruct the data from the parts -partSet2 := NewPartSetFromHeader(header) -partSet2.Total() // Same total as partSet.Total() -partSet2.Count() // Zero, since this PartSet doesn't have any parts yet. -partSet2.Hash() // Same hash as in partSet.Hash() -partSet2.BitArray() // A BitArray of partSet.Total() 0's - -// In a gossip network the parts would arrive in arbitrary order, perhaps -// in response to explicit requests for parts, or optimistically in response -// to the receiving peer's partSet.BitArray(). -for !partSet2.IsComplete() { - part := receivePartFromGossipNetwork() - added, err := partSet2.AddPart(part) - if err != nil { - // A wrong part, - // the merkle trail does not hash to partSet2.Hash() - } else if !added { - // A duplicate part already received - } -} - -data2, _ := ioutil.ReadAll(partSet2.GetReader()) -bytes.Equal(data, data2) // true -``` diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go deleted file mode 100644 index 8b68b96f79e97b9d0939c4e8b2e2b930da6deef7..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block.go +++ /dev/null @@ -1,355 +0,0 @@ -package types - -import ( - "bytes" - "errors" - "fmt" - "strings" - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -const MaxBlockSize = 22020096 // 21MB TODO make it configurable - -type Block struct { - *Header `json:"header"` - *Data `json:"data"` - LastValidation *Validation `json:"last_validation"` -} - -// Basic validation that doesn't involve state data. -func (b *Block) ValidateBasic(chainID string, lastBlockHeight int, lastBlockHash []byte, - lastBlockParts PartSetHeader, lastBlockTime time.Time) error { - if b.ChainID != chainID { - return errors.New(Fmt("Wrong Block.Header.ChainID. Expected %v, got %v", chainID, b.ChainID)) - } - if b.Height != lastBlockHeight+1 { - return errors.New(Fmt("Wrong Block.Header.Height. Expected %v, got %v", lastBlockHeight+1, b.Height)) - } - /* TODO: Determine bounds for Time - See blockchain/reactor "stopSyncingDurationMinutes" - - if !b.Time.After(lastBlockTime) { - return errors.New("Invalid Block.Header.Time") - } - */ - // TODO: validate Fees - if b.NumTxs != len(b.Data.Txs) { - return errors.New(Fmt("Wrong Block.Header.NumTxs. Expected %v, got %v", len(b.Data.Txs), b.NumTxs)) - } - if !bytes.Equal(b.LastBlockHash, lastBlockHash) { - return errors.New(Fmt("Wrong Block.Header.LastBlockHash. Expected %X, got %X", lastBlockHash, b.LastBlockHash)) - } - if !b.LastBlockParts.Equals(lastBlockParts) { - return errors.New(Fmt("Wrong Block.Header.LastBlockParts. Expected %v, got %v", lastBlockParts, b.LastBlockParts)) - } - if !bytes.Equal(b.LastValidationHash, b.LastValidation.Hash()) { - return errors.New(Fmt("Wrong Block.Header.LastValidationHash. Expected %X, got %X", b.LastValidationHash, b.LastValidation.Hash())) - } - if b.Header.Height != 1 { - if err := b.LastValidation.ValidateBasic(); err != nil { - return err - } - } - if !bytes.Equal(b.DataHash, b.Data.Hash()) { - return errors.New(Fmt("Wrong Block.Header.DataHash. Expected %X, got %X", b.DataHash, b.Data.Hash())) - } - // NOTE: the AppHash and ValidatorsHash are validated later. - return nil -} - -func (b *Block) FillHeader() { - b.LastValidationHash = b.LastValidation.Hash() - b.DataHash = b.Data.Hash() -} - -// Computes and returns the block hash. -// If the block is incomplete, block hash is nil for safety. -func (b *Block) Hash() []byte { - if b.Header == nil || b.Data == nil || b.LastValidation == nil { - return nil - } - b.FillHeader() - return b.Header.Hash() -} - -func (b *Block) MakePartSet() *PartSet { - return NewPartSetFromData(wire.BinaryBytes(b)) -} - -// Convenience. -// A nil block never hashes to anything. -// Nothing hashes to a nil hash. -func (b *Block) HashesTo(hash []byte) bool { - if len(hash) == 0 { - return false - } - if b == nil { - return false - } - return bytes.Equal(b.Hash(), hash) -} - -func (b *Block) String() string { - return b.StringIndented("") -} - -func (b *Block) StringIndented(indent string) string { - if b == nil { - return "nil-Block" - } - return fmt.Sprintf(`Block{ -%s %v -%s %v -%s %v -%s}#%X`, - indent, b.Header.StringIndented(indent+" "), - indent, b.Data.StringIndented(indent+" "), - indent, b.LastValidation.StringIndented(indent+" "), - indent, b.Hash()) -} - -func (b *Block) StringShort() string { - if b == nil { - return "nil-Block" - } else { - return fmt.Sprintf("Block#%X", b.Hash()) - } -} - -//----------------------------------------------------------------------------- - -type Header struct { - ChainID string `json:"chain_id"` - Height int `json:"height"` - Time time.Time `json:"time"` - Fees int64 `json:"fees"` - NumTxs int `json:"num_txs"` - LastBlockHash []byte `json:"last_block_hash"` - LastBlockParts PartSetHeader `json:"last_block_parts"` - LastValidationHash []byte `json:"last_validation_hash"` - DataHash []byte `json:"data_hash"` - ValidatorsHash []byte `json:"validators_hash"` - AppHash []byte `json:"app_hash"` -} - -// NOTE: hash is nil if required fields are missing. -func (h *Header) Hash() []byte { - if len(h.ValidatorsHash) == 0 { - return nil - } - return merkle.SimpleHashFromMap(map[string]interface{}{ - "ChainID": h.ChainID, - "Height": h.Height, - "Time": h.Time, - "Fees": h.Fees, - "NumTxs": h.NumTxs, - "LastBlock": h.LastBlockHash, - "LastBlockParts": h.LastBlockParts, - "LastValidation": h.LastValidationHash, - "Data": h.DataHash, - "Validators": h.ValidatorsHash, - "App": h.AppHash, - }) -} - -func (h *Header) StringIndented(indent string) string { - if h == nil { - return "nil-Header" - } - return fmt.Sprintf(`Header{ -%s ChainID: %v -%s Height: %v -%s Time: %v -%s Fees: %v -%s NumTxs: %v -%s LastBlock: %X -%s LastBlockParts: %v -%s LastValidation: %X -%s Data: %X -%s Validators: %X -%s App: %X -%s}#%X`, - indent, h.ChainID, - indent, h.Height, - indent, h.Time, - indent, h.Fees, - indent, h.NumTxs, - indent, h.LastBlockHash, - indent, h.LastBlockParts, - indent, h.LastValidationHash, - indent, h.DataHash, - indent, h.ValidatorsHash, - indent, h.AppHash, - indent, h.Hash()) -} - -//------------------------------------- - -// NOTE: Validation is empty for height 1, but never nil. -type Validation struct { - // NOTE: The Precommits are in order of address to preserve the bonded ValidatorSet order. - // Any peer with a block can gossip precommits by index with a peer without recalculating the - // active ValidatorSet. - Precommits []*Vote `json:"precommits"` - - // Volatile - firstPrecommit *Vote - hash []byte - bitArray *BitArray -} - -func (v *Validation) FirstPrecommit() *Vote { - if len(v.Precommits) == 0 { - return nil - } - if v.firstPrecommit != nil { - return v.firstPrecommit - } - for _, precommit := range v.Precommits { - if precommit != nil { - v.firstPrecommit = precommit - return precommit - } - } - return nil -} - -func (v *Validation) Height() int { - if len(v.Precommits) == 0 { - return 0 - } - return v.FirstPrecommit().Height -} - -func (v *Validation) Round() int { - if len(v.Precommits) == 0 { - return 0 - } - return v.FirstPrecommit().Round -} - -func (v *Validation) Type() byte { - return VoteTypePrecommit -} - -func (v *Validation) Size() int { - if v == nil { - return 0 - } - return len(v.Precommits) -} - -func (v *Validation) BitArray() *BitArray { - if v.bitArray == nil { - v.bitArray = NewBitArray(len(v.Precommits)) - for i, precommit := range v.Precommits { - v.bitArray.SetIndex(i, precommit != nil) - } - } - return v.bitArray -} - -func (v *Validation) GetByIndex(index int) *Vote { - return v.Precommits[index] -} - -func (v *Validation) IsCommit() bool { - if len(v.Precommits) == 0 { - return false - } - return true -} - -func (v *Validation) ValidateBasic() error { - if len(v.Precommits) == 0 { - return errors.New("No precommits in validation") - } - height, round := v.Height(), v.Round() - for _, precommit := range v.Precommits { - // It's OK for precommits to be missing. - if precommit == nil { - continue - } - // Ensure that all votes are precommits - if precommit.Type != VoteTypePrecommit { - return fmt.Errorf("Invalid validation vote. Expected precommit, got %v", - precommit.Type) - } - // Ensure that all heights are the same - if precommit.Height != height { - return fmt.Errorf("Invalid validation precommit height. Expected %v, got %v", - height, precommit.Height) - } - // Ensure that all rounds are the same - if precommit.Round != round { - return fmt.Errorf("Invalid validation precommit round. Expected %v, got %v", - round, precommit.Round) - } - } - return nil -} - -func (v *Validation) Hash() []byte { - if v.hash == nil { - bs := make([]interface{}, len(v.Precommits)) - for i, precommit := range v.Precommits { - bs[i] = precommit - } - v.hash = merkle.SimpleHashFromBinaries(bs) - } - return v.hash -} - -func (v *Validation) StringIndented(indent string) string { - if v == nil { - return "nil-Validation" - } - precommitStrings := make([]string, len(v.Precommits)) - for i, precommit := range v.Precommits { - precommitStrings[i] = precommit.String() - } - return fmt.Sprintf(`Validation{ -%s Precommits: %v -%s}#%X`, - indent, strings.Join(precommitStrings, "\n"+indent+" "), - indent, v.hash) -} - -//----------------------------------------------------------------------------- - -type Data struct { - Txs []Tx `json:"txs"` - - // Volatile - hash []byte -} - -func (data *Data) Hash() []byte { - if data.hash == nil { - txs := make([]interface{}, len(data.Txs)) - for i, tx := range data.Txs { - txs[i] = tx - } - data.hash = merkle.SimpleHashFromBinaries(txs) // NOTE: leaves are TxIDs. - } - return data.hash -} - -func (data *Data) StringIndented(indent string) string { - if data == nil { - return "nil-Data" - } - txStrings := make([]string, len(data.Txs)) - for i, tx := range data.Txs { - txStrings[i] = fmt.Sprintf("Tx:%v", tx) - } - return fmt.Sprintf(`Data{ -%s %v -%s}#%X`, - indent, strings.Join(txStrings, "\n"+indent+" "), - indent, data.hash) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block_meta.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block_meta.go deleted file mode 100644 index b72c0c860fa4c47946ee4c7a3f0ff126e70905d1..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/block_meta.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -type BlockMeta struct { - Hash []byte `json:"hash"` // The block hash - Header *Header `json:"header"` // The block's Header - PartsHeader PartSetHeader `json:"parts_header"` // The PartSetHeader, for transfer -} - -func NewBlockMeta(block *Block, blockParts *PartSet) *BlockMeta { - return &BlockMeta{ - Hash: block.Hash(), - Header: block.Header, - PartsHeader: blockParts.Header(), - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go deleted file mode 100644 index e8f96401a51ce5577a08ce232b3a295fa336f63a..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" -) - -var config cfg.Config = nil - -func init() { - cfg.OnConfig(func(newConfig cfg.Config) { - config = newConfig - }) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go deleted file mode 100644 index 67510baacf7f3f6d1f9ff2afd81678e59f1156b0..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/events.go +++ /dev/null @@ -1,102 +0,0 @@ -package types - -import ( - "time" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// Functions to generate eventId strings - -// Reserved -func EventStringBond() string { return "Bond" } -func EventStringUnbond() string { return "Unbond" } -func EventStringRebond() string { return "Rebond" } -func EventStringDupeout() string { return "Dupeout" } -func EventStringFork() string { return "Fork" } - -func EventStringNewBlock() string { return "NewBlock" } -func EventStringNewRound() string { return "NewRound" } -func EventStringTimeoutPropose() string { return "TimeoutPropose" } -func EventStringCompleteProposal() string { return "CompleteProposal" } -func EventStringPolka() string { return "Polka" } -func EventStringUnlock() string { return "Unlock" } -func EventStringLock() string { return "Lock" } -func EventStringRelock() string { return "Relock" } -func EventStringTimeoutWait() string { return "TimeoutWait" } -func EventStringVote() string { return "Vote" } -func EventStringApp() string { return "App" } - -//---------------------------------------- - -const ( - EventDataTypeNewBlock = byte(0x01) - EventDataTypeFork = byte(0x02) - EventDataTypeTx = byte(0x03) - EventDataTypeApp = byte(0x04) // Custom app event - - EventDataTypeRoundState = byte(0x11) - EventDataTypeVote = byte(0x12) -) - -type EventData interface { - AssertIsEventData() -} - -var _ = wire.RegisterInterface( - struct{ EventData }{}, - wire.ConcreteType{EventDataNewBlock{}, EventDataTypeNewBlock}, - // wire.ConcreteType{EventDataFork{}, EventDataTypeFork }, - wire.ConcreteType{EventDataTx{}, EventDataTypeTx}, - wire.ConcreteType{EventDataApp{}, EventDataTypeApp}, - wire.ConcreteType{EventDataRoundState{}, EventDataTypeRoundState}, - wire.ConcreteType{EventDataVote{}, EventDataTypeVote}, -) - -// Most event messages are basic types (a block, a transaction) -// but some (an input to a call tx or a receive) are more exotic - -type EventDataNewBlock struct { - Block *Block `json:"block"` -} - -// All txs fire EventDataTx -type EventDataTx struct { - Tx Tx `json:"tx"` - Return []byte `json:"return"` - Exception string `json:"exception"` -} - -type EventDataApp struct { - Key string `json:"key"` - Data []byte `json:"bytes"` -} - -// We fire the most recent round state that led to the event -// (ie. NewRound will have the previous rounds state) -type EventDataRoundState struct { - CurrentTime time.Time `json:"current_time"` - - Height int `json:"height"` - Round int `json:"round"` - Step string `json:"step"` - StartTime time.Time `json:"start_time"` - CommitTime time.Time `json:"commit_time"` - Proposal *Proposal `json:"proposal"` - ProposalBlock *Block `json:"proposal_block"` - LockedRound int `json:"locked_round"` - LockedBlock *Block `json:"locked_block"` - POLRound int `json:"pol_round"` -} - -type EventDataVote struct { - Index int - Address []byte - Vote *Vote -} - -func (_ EventDataNewBlock) AssertIsEventData() {} -func (_ EventDataTx) AssertIsEventData() {} -func (_ EventDataApp) AssertIsEventData() {} -func (_ EventDataRoundState) AssertIsEventData() {} -func (_ EventDataVote) AssertIsEventData() {} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/genesis.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/genesis.go deleted file mode 100644 index 0966cf2387d39336aba33fe5ea98942f957923fd..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/genesis.go +++ /dev/null @@ -1,48 +0,0 @@ -package types - -import ( - "time" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -//------------------------------------------------------------ -// we store the gendoc in the db - -var GenDocKey = []byte("GenDocKey") - -//------------------------------------------------------------ -// core types for a genesis definition - -type GenesisValidator struct { - PubKey crypto.PubKeyEd25519 `json:"pub_key"` - Amount int64 `json:"amount"` - Name string `json:"name"` -} - -type GenesisDoc struct { - GenesisTime time.Time `json:"genesis_time"` - ChainID string `json:"chain_id"` - Validators []GenesisValidator `json:"validators"` - AppHash []byte `json:"app_hash"` -} - -// Utility method for saving GenensisDoc as JSON file. -func (genDoc *GenesisDoc) SaveAs(file string) error { - genDocBytes := wire.JSONBytes(genDoc) - return WriteFile(file, genDocBytes, 0644) -} - -//------------------------------------------------------------ -// Make genesis state from file - -func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) { - var err error - wire.ReadJSONPtr(&genState, jsonBlob, &err) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc: %v", err)) - } - return -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/keys.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/keys.go deleted file mode 100644 index 90591b95936e5dc6af8d616a099169f95c9ceca0..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/keys.go +++ /dev/null @@ -1,6 +0,0 @@ -package types - -var ( - PeerStateKey = "ConsensusReactor.peerState" - PeerMempoolChKey = "MempoolReactor.peerMempoolCh" -) diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/log.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/log.go deleted file mode 100644 index 1f22008fda5edddd2366b1bb2a1d8b8794459b5a..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package types - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" -) - -var log = logger.New("module", "types") diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/myfile b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/myfile deleted file mode 100644 index d4401eddd73a489b7f045232f80c08e4c7f2dc41..0000000000000000000000000000000000000000 Binary files a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/myfile and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set.go deleted file mode 100644 index 8bf2b3cfb6cd33ace17942ea84a4cee33ff6701b..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set.go +++ /dev/null @@ -1,241 +0,0 @@ -package types - -import ( - "bytes" - "errors" - "fmt" - "io" - "sync" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -const ( - partSize = 4096 // 4KB -) - -var ( - ErrPartSetUnexpectedIndex = errors.New("Error part set unexpected index") - ErrPartSetInvalidProof = errors.New("Error part set invalid proof") -) - -type Part struct { - Proof merkle.SimpleProof `json:"proof"` - Bytes []byte `json:"bytes"` - - // Cache - hash []byte -} - -func (part *Part) Hash() []byte { - if part.hash != nil { - return part.hash - } else { - hasher := ripemd160.New() - hasher.Write(part.Bytes) // doesn't err - part.hash = hasher.Sum(nil) - return part.hash - } -} - -func (part *Part) String() string { - return part.StringIndented("") -} - -func (part *Part) StringIndented(indent string) string { - return fmt.Sprintf(`Part{ -%s Proof: %v -%s Bytes: %X -%s}`, - indent, part.Proof.StringIndented(indent+" "), - indent, part.Bytes, - indent) -} - -//------------------------------------- - -type PartSetHeader struct { - Total int `json:"total"` - Hash []byte `json:"hash"` -} - -func (psh PartSetHeader) String() string { - return fmt.Sprintf("PartSet{T:%v %X}", psh.Total, Fingerprint(psh.Hash)) -} - -func (psh PartSetHeader) IsZero() bool { - return psh.Total == 0 -} - -func (psh PartSetHeader) Equals(other PartSetHeader) bool { - return psh.Total == other.Total && bytes.Equal(psh.Hash, other.Hash) -} - -func (psh PartSetHeader) WriteSignBytes(w io.Writer, n *int, err *error) { - wire.WriteTo([]byte(Fmt(`{"hash":"%X","total":%v}`, psh.Hash, psh.Total)), w, n, err) -} - -//------------------------------------- - -type PartSet struct { - total int - hash []byte - - mtx sync.Mutex - parts []*Part - partsBitArray *BitArray - count int -} - -// Returns an immutable, full PartSet from the data bytes. -// The data bytes are split into "partSize" chunks, and merkle tree computed. -func NewPartSetFromData(data []byte) *PartSet { - // divide data into 4kb parts. - total := (len(data) + partSize - 1) / partSize - parts := make([]*Part, total) - parts_ := make([]merkle.Hashable, total) - partsBitArray := NewBitArray(total) - for i := 0; i < total; i++ { - part := &Part{ - Bytes: data[i*partSize : MinInt(len(data), (i+1)*partSize)], - } - parts[i] = part - parts_[i] = part - partsBitArray.SetIndex(i, true) - } - // Compute merkle proofs - proofs := merkle.SimpleProofsFromHashables(parts_) - for i := 0; i < total; i++ { - parts[i].Proof = *proofs[i] - } - return &PartSet{ - total: total, - hash: proofs[0].RootHash, - parts: parts, - partsBitArray: partsBitArray, - count: total, - } -} - -// Returns an empty PartSet ready to be populated. -func NewPartSetFromHeader(header PartSetHeader) *PartSet { - return &PartSet{ - total: header.Total, - hash: header.Hash, - parts: make([]*Part, header.Total), - partsBitArray: NewBitArray(header.Total), - count: 0, - } -} - -func (ps *PartSet) Header() PartSetHeader { - if ps == nil { - return PartSetHeader{} - } else { - return PartSetHeader{ - Total: ps.total, - Hash: ps.hash, - } - } -} - -func (ps *PartSet) HasHeader(header PartSetHeader) bool { - if ps == nil { - return false - } else { - return ps.Header().Equals(header) - } -} - -func (ps *PartSet) BitArray() *BitArray { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return ps.partsBitArray.Copy() -} - -func (ps *PartSet) Hash() []byte { - if ps == nil { - return nil - } - return ps.hash -} - -func (ps *PartSet) HashesTo(hash []byte) bool { - if ps == nil { - return false - } - return bytes.Equal(ps.hash, hash) -} - -func (ps *PartSet) Count() int { - if ps == nil { - return 0 - } - return ps.count -} - -func (ps *PartSet) Total() int { - if ps == nil { - return 0 - } - return ps.total -} - -func (ps *PartSet) AddPart(part *Part) (bool, error) { - ps.mtx.Lock() - defer ps.mtx.Unlock() - - // Invalid part index - if part.Proof.Index >= ps.total { - return false, ErrPartSetUnexpectedIndex - } - - // If part already exists, return false. - if ps.parts[part.Proof.Index] != nil { - return false, nil - } - - // Check hash proof - if !part.Proof.Verify(part.Hash(), ps.Hash()) { - return false, ErrPartSetInvalidProof - } - - // Add part - ps.parts[part.Proof.Index] = part - ps.partsBitArray.SetIndex(part.Proof.Index, true) - ps.count++ - return true, nil -} - -func (ps *PartSet) GetPart(index int) *Part { - ps.mtx.Lock() - defer ps.mtx.Unlock() - return ps.parts[index] -} - -func (ps *PartSet) IsComplete() bool { - return ps.count == ps.total -} - -func (ps *PartSet) GetReader() io.Reader { - if !ps.IsComplete() { - PanicSanity("Cannot GetReader() on incomplete PartSet") - } - buf := []byte{} - for _, part := range ps.parts { - buf = append(buf, part.Bytes...) - } - return bytes.NewReader(buf) -} - -func (ps *PartSet) StringShort() string { - if ps == nil { - return "nil-PartSet" - } else { - return fmt.Sprintf("(%v of %v)", ps.Count(), ps.Total()) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set_test.go deleted file mode 100644 index 565a3b5193b3f1fac8cb3fbc051cde44d3b39dc3..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/part_set_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package types - -import ( - "bytes" - "io/ioutil" - "testing" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" -) - -func TestBasicPartSet(t *testing.T) { - - // Construct random data of size partSize * 100 - data := RandBytes(partSize * 100) - - partSet := NewPartSetFromData(data) - if len(partSet.Hash()) == 0 { - t.Error("Expected to get hash") - } - if partSet.Total() != 100 { - t.Errorf("Expected to get 100 parts, but got %v", partSet.Total()) - } - if !partSet.IsComplete() { - t.Errorf("PartSet should be complete") - } - - // Test adding parts to a new partSet. - partSet2 := NewPartSetFromHeader(partSet.Header()) - - for i := 0; i < partSet.Total(); i++ { - part := partSet.GetPart(i) - //t.Logf("\n%v", part) - added, err := partSet2.AddPart(part) - if !added || err != nil { - t.Errorf("Failed to add part %v, error: %v", i, err) - } - } - - if !bytes.Equal(partSet.Hash(), partSet2.Hash()) { - t.Error("Expected to get same hash") - } - if partSet2.Total() != 100 { - t.Errorf("Expected to get 100 parts, but got %v", partSet2.Total()) - } - if !partSet2.IsComplete() { - t.Errorf("Reconstructed PartSet should be complete") - } - - // Reconstruct data, assert that they are equal. - data2Reader := partSet2.GetReader() - data2, err := ioutil.ReadAll(data2Reader) - if err != nil { - t.Errorf("Error reading data2Reader: %v", err) - } - if !bytes.Equal(data, data2) { - t.Errorf("Got wrong data.") - } - -} - -func TestWrongProof(t *testing.T) { - - // Construct random data of size partSize * 100 - data := RandBytes(partSize * 100) - partSet := NewPartSetFromData(data) - - // Test adding a part with wrong data. - partSet2 := NewPartSetFromHeader(partSet.Header()) - - // Test adding a part with wrong trail. - part := partSet.GetPart(0) - part.Proof.InnerHashes[0][0] += byte(0x01) - added, err := partSet2.AddPart(part) - if added || err == nil { - t.Errorf("Expected to fail adding a part with bad trail.") - } - - // Test adding a part with wrong bytes. - part = partSet.GetPart(1) - part.Bytes[0] += byte(0x01) - added, err = partSet2.AddPart(part) - if added || err == nil { - t.Errorf("Expected to fail adding a part with bad bytes.") - } - -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/priv_validator.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/priv_validator.go deleted file mode 100644 index c4d624070cc6d8d70edc0ac5606140ac0e7f9e85..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/priv_validator.go +++ /dev/null @@ -1,197 +0,0 @@ -package types - -import ( - "bytes" - "errors" - "fmt" - "io/ioutil" - "os" - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" -) - -const ( - stepNone = 0 // Used to distinguish the initial state - stepPropose = 1 - stepPrevote = 2 - stepPrecommit = 3 -) - -func voteToStep(vote *Vote) int8 { - switch vote.Type { - case VoteTypePrevote: - return stepPrevote - case VoteTypePrecommit: - return stepPrecommit - default: - PanicSanity("Unknown vote type") - return 0 - } -} - -type PrivValidator struct { - Address []byte `json:"address"` - PubKey crypto.PubKeyEd25519 `json:"pub_key"` - PrivKey crypto.PrivKeyEd25519 `json:"priv_key"` - LastHeight int `json:"last_height"` - LastRound int `json:"last_round"` - LastStep int8 `json:"last_step"` - - // For persistence. - // Overloaded for testing. - filePath string - mtx sync.Mutex -} - -// Generates a new validator with private key. -func GenPrivValidator() *PrivValidator { - privKeyBytes := new([64]byte) - copy(privKeyBytes[:32], CRandBytes(32)) - pubKeyBytes := ed25519.MakePublicKey(privKeyBytes) - pubKey := crypto.PubKeyEd25519(*pubKeyBytes) - privKey := crypto.PrivKeyEd25519(*privKeyBytes) - return &PrivValidator{ - Address: pubKey.Address(), - PubKey: pubKey, - PrivKey: privKey, - LastHeight: 0, - LastRound: 0, - LastStep: stepNone, - filePath: "", - } -} - -func LoadPrivValidator(filePath string) *PrivValidator { - privValJSONBytes, err := ioutil.ReadFile(filePath) - if err != nil { - Exit(err.Error()) - } - privVal := wire.ReadJSON(&PrivValidator{}, privValJSONBytes, &err).(*PrivValidator) - if err != nil { - Exit(Fmt("Error reading PrivValidator from %v: %v\n", filePath, err)) - } - privVal.filePath = filePath - return privVal -} - -func LoadOrGenPrivValidator(filePath string) *PrivValidator { - var privValidator *PrivValidator - if _, err := os.Stat(filePath); err == nil { - privValidator = LoadPrivValidator(filePath) - log.Notice("Loaded PrivValidator", - "file", filePath, "privValidator", privValidator) - } else { - privValidator = GenPrivValidator() - privValidator.SetFile(filePath) - privValidator.Save() - log.Notice("Generated PrivValidator", "file", filePath) - } - return privValidator -} - -func (privVal *PrivValidator) SetFile(filePath string) { - privVal.mtx.Lock() - defer privVal.mtx.Unlock() - privVal.filePath = filePath -} - -func (privVal *PrivValidator) Save() { - privVal.mtx.Lock() - defer privVal.mtx.Unlock() - privVal.save() -} - -func (privVal *PrivValidator) save() { - if privVal.filePath == "" { - PanicSanity("Cannot save PrivValidator: filePath not set") - } - jsonBytes := wire.JSONBytes(privVal) - err := WriteFileAtomic(privVal.filePath, jsonBytes, 0600) - if err != nil { - // `@; BOOM!!! - PanicCrisis(err) - } -} - -func (privVal *PrivValidator) SignVote(chainID string, vote *Vote) error { - privVal.mtx.Lock() - defer privVal.mtx.Unlock() - - // If height regression, panic - if privVal.LastHeight > vote.Height { - return errors.New("Height regression in SignVote") - } - // More cases for when the height matches - if privVal.LastHeight == vote.Height { - // If round regression, panic - if privVal.LastRound > vote.Round { - return errors.New("Round regression in SignVote") - } - // If step regression, panic - if privVal.LastRound == vote.Round && privVal.LastStep > voteToStep(vote) { - return errors.New("Step regression in SignVote") - } - } - - // Persist height/round/step - privVal.LastHeight = vote.Height - privVal.LastRound = vote.Round - privVal.LastStep = voteToStep(vote) - privVal.save() - - // Sign - privVal.SignVoteUnsafe(chainID, vote) - return nil -} - -func (privVal *PrivValidator) SignVoteUnsafe(chainID string, vote *Vote) { - vote.Signature = privVal.PrivKey.Sign(SignBytes(chainID, vote)).(crypto.SignatureEd25519) -} - -func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) error { - privVal.mtx.Lock() - defer privVal.mtx.Unlock() - if privVal.LastHeight < proposal.Height || - privVal.LastHeight == proposal.Height && privVal.LastRound < proposal.Round || - privVal.LastHeight == 0 && privVal.LastRound == 0 && privVal.LastStep == stepNone { - - // Persist height/round/step - privVal.LastHeight = proposal.Height - privVal.LastRound = proposal.Round - privVal.LastStep = stepPropose - privVal.save() - - // Sign - proposal.Signature = privVal.PrivKey.Sign(SignBytes(chainID, proposal)).(crypto.SignatureEd25519) - return nil - } else { - return errors.New(fmt.Sprintf("Attempt of duplicate signing of proposal: Height %v, Round %v", proposal.Height, proposal.Round)) - } -} - -func (privVal *PrivValidator) String() string { - return fmt.Sprintf("PrivValidator{%X LH:%v, LR:%v, LS:%v}", privVal.Address, privVal.LastHeight, privVal.LastRound, privVal.LastStep) -} - -//------------------------------------- - -type PrivValidatorsByAddress []*PrivValidator - -func (pvs PrivValidatorsByAddress) Len() int { - return len(pvs) -} - -func (pvs PrivValidatorsByAddress) Less(i, j int) bool { - return bytes.Compare(pvs[i].Address, pvs[j].Address) == -1 -} - -func (pvs PrivValidatorsByAddress) Swap(i, j int) { - it := pvs[i] - pvs[i] = pvs[j] - pvs[j] = it -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go deleted file mode 100644 index e67db26ad48f0bd46899adc7dad36df87777a763..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal.go +++ /dev/null @@ -1,47 +0,0 @@ -package types - -import ( - "errors" - "fmt" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -var ( - ErrInvalidBlockPartSignature = errors.New("Error invalid block part signature") - ErrInvalidBlockPartHash = errors.New("Error invalid block part hash") -) - -type Proposal struct { - Height int `json:"height"` - Round int `json:"round"` - BlockPartsHeader PartSetHeader `json:"block_parts_header"` - POLRound int `json:"pol_round"` // -1 if null. - Signature crypto.SignatureEd25519 `json:"signature"` -} - -// polRound: -1 if no polRound. -func NewProposal(height int, round int, blockPartsHeader PartSetHeader, polRound int) *Proposal { - return &Proposal{ - Height: height, - Round: round, - BlockPartsHeader: blockPartsHeader, - POLRound: polRound, - } -} - -func (p *Proposal) String() string { - return fmt.Sprintf("Proposal{%v/%v %v %v %v}", p.Height, p.Round, - p.BlockPartsHeader, p.POLRound, p.Signature) -} - -func (p *Proposal) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":"%s"`, chainID)), w, n, err) - wire.WriteTo([]byte(`,"proposal":{"block_parts_header":`), w, n, err) - p.BlockPartsHeader.WriteSignBytes(w, n, err) - wire.WriteTo([]byte(Fmt(`,"height":%v,"pol_round":%v`, p.Height, p.POLRound)), w, n, err) - wire.WriteTo([]byte(Fmt(`,"round":%v}}`, p.Round)), w, n, err) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal_test.go deleted file mode 100644 index a0024828c5ca76afbb346fea40115a865b22c865..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/proposal_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package types - -import ( - "testing" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" -) - -func TestProposalSignable(t *testing.T) { - proposal := &Proposal{ - Height: 12345, - Round: 23456, - BlockPartsHeader: PartSetHeader{111, []byte("blockparts")}, - POLRound: -1, - } - signBytes := SignBytes(config.GetString("chain_id"), proposal) - signStr := string(signBytes) - - expected := Fmt(`{"chain_id":"%s","proposal":{"block_parts_header":{"hash":"626C6F636B7061727473","total":111},"height":12345,"pol_round":-1,"round":23456}}`, - config.GetString("chain_id")) - if signStr != expected { - t.Errorf("Got unexpected sign string for SendTx. Expected:\n%v\nGot:\n%v", expected, signStr) - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go deleted file mode 100644 index 041f3bc4ef5e418b7a0610df2f71aa90b9415354..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/signable.go +++ /dev/null @@ -1,30 +0,0 @@ -package types - -import ( - "bytes" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" -) - -// Signable is an interface for all signable things. -// It typically removes signatures before serializing. -type Signable interface { - WriteSignBytes(chainID string, w io.Writer, n *int, err *error) -} - -// SignBytes is a convenience method for getting the bytes to sign of a Signable. -func SignBytes(chainID string, o Signable) []byte { - buf, n, err := new(bytes.Buffer), new(int), new(error) - o.WriteSignBytes(chainID, buf, n, err) - if *err != nil { - PanicCrisis(err) - } - return buf.Bytes() -} - -// HashSignBytes is a convenience method for getting the hash of the bytes of a signable -func HashSignBytes(chainID string, o Signable) []byte { - return merkle.SimpleHashFromBinary(SignBytes(chainID, o)) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/stats.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/stats.go deleted file mode 100644 index 29e005355a1ff681d4eca36e21eea0a625707ef1..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/stats.go +++ /dev/null @@ -1,46 +0,0 @@ -package types - -import ( - "time" -) - -type Stats struct { - Blocks int64 `json:"blocks"` - TotalTime int64 `json:"total_time"` - LastCommitTime time.Time `json:"last_commit_time"` - - MinCommitTime int64 `json:"min_commit_time"` - MaxCommitTime int64 `json:"max_commit_time"` - MeanCommitTime int64 `json:"mean_commit_time"` -} - -func NewStats() *Stats { - return &Stats{ - LastCommitTime: time.Now(), - MinCommitTime: 100000000, - MaxCommitTime: 0, - } -} - -func (s *Stats) Update() { - newCommitTime := time.Now() - since := newCommitTime.Sub(s.LastCommitTime).Nanoseconds() - - var newS Stats - - newS.Blocks += 1 - newS.LastCommitTime = newCommitTime - - // update min and max - if since < s.MinCommitTime { - newS.MinCommitTime = since - } - if since > s.MaxCommitTime { - newS.MaxCommitTime = since - } - - // update total and average - newS.TotalTime += since - newS.MeanCommitTime = int64(float64(newS.TotalTime) / float64(newS.Blocks)) - *s = newS -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx.go deleted file mode 100644 index a3cb9fc04fb114d270bf71ec067e10407be50587..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/tx.go +++ /dev/null @@ -1,3 +0,0 @@ -package types - -type Tx []byte diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go deleted file mode 100644 index e78070085912ebac2928437e06b4ac3e5f8a2d95..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator.go +++ /dev/null @@ -1,85 +0,0 @@ -package types - -import ( - "bytes" - "fmt" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// Volatile state for each Validator -// Also persisted with the state, but fields change -// every height|round so they don't go in merkle.Tree -type Validator struct { - Address []byte `json:"address"` - PubKey crypto.PubKeyEd25519 `json:"pub_key"` - LastCommitHeight int `json:"last_commit_height"` - VotingPower int64 `json:"voting_power"` - Accum int64 `json:"accum"` -} - -// Creates a new copy of the validator so we can mutate accum. -// Panics if the validator is nil. -func (v *Validator) Copy() *Validator { - vCopy := *v - return &vCopy -} - -// Returns the one with higher Accum. -func (v *Validator) CompareAccum(other *Validator) *Validator { - if v == nil { - return other - } - if v.Accum > other.Accum { - return v - } else if v.Accum < other.Accum { - return other - } else { - if bytes.Compare(v.Address, other.Address) < 0 { - return v - } else if bytes.Compare(v.Address, other.Address) > 0 { - return other - } else { - PanicSanity("Cannot compare identical validators") - return nil - } - } -} - -func (v *Validator) String() string { - if v == nil { - return "nil-Validator" - } - return fmt.Sprintf("Validator{%X %v %v-%v-%v VP:%v A:%v}", - v.Address, - v.PubKey, - v.LastCommitHeight, - v.VotingPower, - v.Accum) -} - -func (v *Validator) Hash() []byte { - return wire.BinaryRipemd160(v) -} - -//------------------------------------- - -var ValidatorCodec = validatorCodec{} - -type validatorCodec struct{} - -func (vc validatorCodec) Encode(o interface{}, w io.Writer, n *int, err *error) { - wire.WriteBinary(o.(*Validator), w, n, err) -} - -func (vc validatorCodec) Decode(r io.Reader, n *int, err *error) interface{} { - return wire.ReadBinary(&Validator{}, r, 0, n, err) -} - -func (vc validatorCodec) Compare(o1 interface{}, o2 interface{}) int { - PanicSanity("ValidatorCodec.Compare not implemented") - return 0 -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set.go deleted file mode 100644 index d156adc84505c882e1b4561c4f7884be33cd9d81..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set.go +++ /dev/null @@ -1,311 +0,0 @@ -package types - -import ( - "bytes" - "fmt" - "sort" - "strings" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" -) - -// ValidatorSet represent a set of *Validator at a given height. -// The validators can be fetched by address or index. -// The index is in order of .Address, so the indices are fixed -// for all rounds of a given blockchain height. -// On the other hand, the .AccumPower of each validator and -// the designated .Proposer() of a set changes every round, -// upon calling .IncrementAccum(). -// NOTE: Not goroutine-safe. -// NOTE: All get/set to validators should copy the value for safety. -// TODO: consider validator Accum overflow -// TODO: replace validators []*Validator with github.com/jaekwon/go-ibbs? -type ValidatorSet struct { - Validators []*Validator // NOTE: persisted via reflect, must be exported. - - // cached (unexported) - proposer *Validator - totalVotingPower int64 -} - -func NewValidatorSet(vals []*Validator) *ValidatorSet { - validators := make([]*Validator, len(vals)) - for i, val := range vals { - validators[i] = val.Copy() - } - sort.Sort(ValidatorsByAddress(validators)) - vs := &ValidatorSet{ - Validators: validators, - } - - if vals != nil { - vs.IncrementAccum(1) - } - return vs -} - -// TODO: mind the overflow when times and votingPower shares too large. -func (valSet *ValidatorSet) IncrementAccum(times int) { - // Add VotingPower * times to each validator and order into heap. - validatorsHeap := NewHeap() - for _, val := range valSet.Validators { - val.Accum += int64(val.VotingPower) * int64(times) // TODO: mind overflow - validatorsHeap.Push(val, accumComparable(val.Accum)) - } - - // Decrement the validator with most accum, times times. - for i := 0; i < times; i++ { - mostest := validatorsHeap.Peek().(*Validator) - if i == times-1 { - valSet.proposer = mostest - } - mostest.Accum -= int64(valSet.TotalVotingPower()) - validatorsHeap.Update(mostest, accumComparable(mostest.Accum)) - } -} - -func (valSet *ValidatorSet) Copy() *ValidatorSet { - validators := make([]*Validator, len(valSet.Validators)) - for i, val := range valSet.Validators { - // NOTE: must copy, since IncrementAccum updates in place. - validators[i] = val.Copy() - } - return &ValidatorSet{ - Validators: validators, - proposer: valSet.proposer, - totalVotingPower: valSet.totalVotingPower, - } -} - -func (valSet *ValidatorSet) HasAddress(address []byte) bool { - idx := sort.Search(len(valSet.Validators), func(i int) bool { - return bytes.Compare(address, valSet.Validators[i].Address) <= 0 - }) - return idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0 -} - -func (valSet *ValidatorSet) GetByAddress(address []byte) (index int, val *Validator) { - idx := sort.Search(len(valSet.Validators), func(i int) bool { - return bytes.Compare(address, valSet.Validators[i].Address) <= 0 - }) - if idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0 { - return idx, valSet.Validators[idx].Copy() - } else { - return 0, nil - } -} - -func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) { - val = valSet.Validators[index] - return val.Address, val.Copy() -} - -func (valSet *ValidatorSet) Size() int { - return len(valSet.Validators) -} - -func (valSet *ValidatorSet) TotalVotingPower() int64 { - if valSet.totalVotingPower == 0 { - for _, val := range valSet.Validators { - valSet.totalVotingPower += val.VotingPower - } - } - return valSet.totalVotingPower -} - -func (valSet *ValidatorSet) Proposer() (proposer *Validator) { - if len(valSet.Validators) == 0 { - return nil - } - if valSet.proposer == nil { - for _, val := range valSet.Validators { - valSet.proposer = valSet.proposer.CompareAccum(val) - } - } - return valSet.proposer.Copy() -} - -func (valSet *ValidatorSet) Hash() []byte { - if len(valSet.Validators) == 0 { - return nil - } - hashables := make([]merkle.Hashable, len(valSet.Validators)) - for i, val := range valSet.Validators { - hashables[i] = val - } - return merkle.SimpleHashFromHashables(hashables) -} - -func (valSet *ValidatorSet) Add(val *Validator) (added bool) { - val = val.Copy() - idx := sort.Search(len(valSet.Validators), func(i int) bool { - return bytes.Compare(val.Address, valSet.Validators[i].Address) <= 0 - }) - if idx == len(valSet.Validators) { - valSet.Validators = append(valSet.Validators, val) - // Invalidate cache - valSet.proposer = nil - valSet.totalVotingPower = 0 - return true - } else if bytes.Compare(valSet.Validators[idx].Address, val.Address) == 0 { - return false - } else { - newValidators := make([]*Validator, len(valSet.Validators)+1) - copy(newValidators[:idx], valSet.Validators[:idx]) - newValidators[idx] = val - copy(newValidators[idx+1:], valSet.Validators[idx:]) - valSet.Validators = newValidators - // Invalidate cache - valSet.proposer = nil - valSet.totalVotingPower = 0 - return true - } -} - -func (valSet *ValidatorSet) Update(val *Validator) (updated bool) { - index, sameVal := valSet.GetByAddress(val.Address) - if sameVal == nil { - return false - } else { - valSet.Validators[index] = val.Copy() - // Invalidate cache - valSet.proposer = nil - valSet.totalVotingPower = 0 - return true - } -} - -func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) { - idx := sort.Search(len(valSet.Validators), func(i int) bool { - return bytes.Compare(address, valSet.Validators[i].Address) <= 0 - }) - if idx == len(valSet.Validators) || bytes.Compare(valSet.Validators[idx].Address, address) != 0 { - return nil, false - } else { - removedVal := valSet.Validators[idx] - newValidators := valSet.Validators[:idx] - if idx+1 < len(valSet.Validators) { - newValidators = append(newValidators, valSet.Validators[idx+1:]...) - } - valSet.Validators = newValidators - // Invalidate cache - valSet.proposer = nil - valSet.totalVotingPower = 0 - return removedVal, true - } -} - -func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) { - for i, val := range valSet.Validators { - stop := fn(i, val.Copy()) - if stop { - break - } - } -} - -// Verify that +2/3 of the set had signed the given signBytes -func (valSet *ValidatorSet) VerifyValidation(chainID string, - hash []byte, parts PartSetHeader, height int, v *Validation) error { - if valSet.Size() != len(v.Precommits) { - return fmt.Errorf("Invalid validation -- wrong set size: %v vs %v", valSet.Size(), len(v.Precommits)) - } - if height != v.Height() { - return fmt.Errorf("Invalid validation -- wrong height: %v vs %v", height, v.Height()) - } - - talliedVotingPower := int64(0) - round := v.Round() - - for idx, precommit := range v.Precommits { - // may be nil if validator skipped. - if precommit == nil { - continue - } - if precommit.Height != height { - return fmt.Errorf("Invalid validation -- wrong height: %v vs %v", height, precommit.Height) - } - if precommit.Round != round { - return fmt.Errorf("Invalid validation -- wrong round: %v vs %v", round, precommit.Round) - } - if precommit.Type != VoteTypePrecommit { - return fmt.Errorf("Invalid validation -- not precommit @ index %v", idx) - } - _, val := valSet.GetByIndex(idx) - // Validate signature - precommitSignBytes := SignBytes(chainID, precommit) - if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) { - return fmt.Errorf("Invalid validation -- invalid signature: %v", precommit) - } - if !bytes.Equal(precommit.BlockHash, hash) { - continue // Not an error, but doesn't count - } - if !parts.Equals(precommit.BlockPartsHeader) { - continue // Not an error, but doesn't count - } - // Good precommit! - talliedVotingPower += val.VotingPower - } - - if talliedVotingPower > valSet.TotalVotingPower()*2/3 { - return nil - } else { - return fmt.Errorf("Invalid validation -- insufficient voting power: got %v, needed %v", - talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1)) - } -} - -func (valSet *ValidatorSet) String() string { - return valSet.StringIndented("") -} - -func (valSet *ValidatorSet) StringIndented(indent string) string { - if valSet == nil { - return "nil-ValidatorSet" - } - valStrings := []string{} - valSet.Iterate(func(index int, val *Validator) bool { - valStrings = append(valStrings, val.String()) - return false - }) - return fmt.Sprintf(`ValidatorSet{ -%s Proposer: %v -%s Validators: -%s %v -%s}`, - indent, valSet.Proposer().String(), - indent, - indent, strings.Join(valStrings, "\n"+indent+" "), - indent) - -} - -//------------------------------------- -// Implements sort for sorting validators by address. - -type ValidatorsByAddress []*Validator - -func (vs ValidatorsByAddress) Len() int { - return len(vs) -} - -func (vs ValidatorsByAddress) Less(i, j int) bool { - return bytes.Compare(vs[i].Address, vs[j].Address) == -1 -} - -func (vs ValidatorsByAddress) Swap(i, j int) { - it := vs[i] - vs[i] = vs[j] - vs[j] = it -} - -//------------------------------------- -// Use with Heap for sorting validators by accum - -type accumComparable int64 - -// We want to find the validator with the greatest accum. -func (ac accumComparable) Less(o interface{}) bool { - return int64(ac) > int64(o.(accumComparable)) -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set_test.go deleted file mode 100644 index 5064e7967b2d49c067480ca3c74c5c64789354e8..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/validator_set_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package types - -import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - - "bytes" - "strings" - "testing" -) - -func randPubKey() crypto.PubKeyEd25519 { - var pubKey [32]byte - copy(pubKey[:], RandBytes(32)) - return crypto.PubKeyEd25519(pubKey) -} - -func randValidator_() *Validator { - return &Validator{ - Address: RandBytes(20), - PubKey: randPubKey(), - VotingPower: RandInt64(), - Accum: RandInt64(), - } -} - -func randValidatorSet(numValidators int) *ValidatorSet { - validators := make([]*Validator, numValidators) - for i := 0; i < numValidators; i++ { - validators[i] = randValidator_() - } - return NewValidatorSet(validators) -} - -func TestCopy(t *testing.T) { - vset := randValidatorSet(10) - vsetHash := vset.Hash() - if len(vsetHash) == 0 { - t.Fatalf("ValidatorSet had unexpected zero hash") - } - - vsetCopy := vset.Copy() - vsetCopyHash := vsetCopy.Hash() - - if !bytes.Equal(vsetHash, vsetCopyHash) { - t.Fatalf("ValidatorSet copy had wrong hash. Orig: %X, Copy: %X", vsetHash, vsetCopyHash) - } -} - -func TestProposerSelection(t *testing.T) { - vset := NewValidatorSet([]*Validator{ - newValidator([]byte("foo"), 1000), - newValidator([]byte("bar"), 300), - newValidator([]byte("baz"), 330), - }) - proposers := []string{} - for i := 0; i < 99; i++ { - val := vset.Proposer() - proposers = append(proposers, string(val.Address)) - vset.IncrementAccum(1) - } - expected := `foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo foo baz bar foo foo foo baz foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo bar foo foo baz foo foo bar foo baz foo foo bar foo baz foo foo bar foo baz foo foo` - if expected != strings.Join(proposers, " ") { - t.Errorf("Expected sequence of proposers was\n%v\nbut got \n%v", expected, strings.Join(proposers, " ")) - } -} - -func newValidator(address []byte, power int64) *Validator { - return &Validator{Address: address, VotingPower: power} -} - -func TestProposerSelection2(t *testing.T) { - addr1 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - addr2 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} - addr3 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2} - - // when all voting power is same, we go in order of addresses - val1, val2, val3 := newValidator(addr1, 100), newValidator(addr2, 100), newValidator(addr3, 100) - valList := []*Validator{val1, val2, val3} - vals := NewValidatorSet(valList) - for i := 0; i < len(valList)*5; i++ { - ii := i % len(valList) - prop := vals.Proposer() - if !bytes.Equal(prop.Address, valList[ii].Address) { - t.Fatalf("Expected %X. Got %X", valList[ii].Address, prop.Address) - } - vals.IncrementAccum(1) - } - - // One validator has more than the others, but not enough to propose twice in a row - *val3 = *newValidator(addr3, 400) - vals = NewValidatorSet(valList) - prop := vals.Proposer() - if !bytes.Equal(prop.Address, addr3) { - t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address) - } - vals.IncrementAccum(1) - prop = vals.Proposer() - if !bytes.Equal(prop.Address, addr1) { - t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address) - } - - // One validator has more than the others, and enough to be proposer twice in a row - *val3 = *newValidator(addr3, 401) - vals = NewValidatorSet(valList) - prop = vals.Proposer() - if !bytes.Equal(prop.Address, addr3) { - t.Fatalf("Expected address with highest voting power to be first proposer. Got %X", prop.Address) - } - vals.IncrementAccum(1) - prop = vals.Proposer() - if !bytes.Equal(prop.Address, addr3) { - t.Fatalf("Expected address with highest voting power to be second proposer. Got %X", prop.Address) - } - vals.IncrementAccum(1) - prop = vals.Proposer() - if !bytes.Equal(prop.Address, addr1) { - t.Fatalf("Expected smallest address to be validator. Got %X", prop.Address) - } - - // each validator should be the proposer a proportional number of times - val1, val2, val3 = newValidator(addr1, 4), newValidator(addr2, 5), newValidator(addr3, 3) - valList = []*Validator{val1, val2, val3} - propCount := make([]int, 3) - vals = NewValidatorSet(valList) - for i := 0; i < 120; i++ { - prop := vals.Proposer() - ii := prop.Address[19] - propCount[ii] += 1 - vals.IncrementAccum(1) - } - - if propCount[0] != 40 { - t.Fatalf("Expected prop count for validator with 4/12 of voting power to be 40/120. Got %d/120", propCount[0]) - } - if propCount[1] != 50 { - t.Fatalf("Expected prop count for validator with 5/12 of voting power to be 50/120. Got %d/120", propCount[1]) - } - if propCount[2] != 30 { - t.Fatalf("Expected prop count for validator with 3/12 of voting power to be 30/120. Got %d/120", propCount[2]) - } -} - -func BenchmarkValidatorSetCopy(b *testing.B) { - b.StopTimer() - vset := NewValidatorSet([]*Validator{}) - for i := 0; i < 1000; i++ { - privKey := crypto.GenPrivKeyEd25519() - pubKey := privKey.PubKey().(crypto.PubKeyEd25519) - val := &Validator{ - Address: pubKey.Address(), - PubKey: pubKey, - } - if !vset.Add(val) { - panic("Failed to add validator") - } - } - b.StartTimer() - - for i := 0; i < b.N; i++ { - vset.Copy() - } -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go deleted file mode 100644 index d1ecfe653b301cb959a2496a3cd5205a8cecf3bc..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote.go +++ /dev/null @@ -1,85 +0,0 @@ -package types - -import ( - "errors" - "fmt" - "io" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -var ( - ErrVoteUnexpectedStep = errors.New("Unexpected step") - ErrVoteInvalidAccount = errors.New("Invalid round vote account") - ErrVoteInvalidSignature = errors.New("Invalid round vote signature") - ErrVoteInvalidBlockHash = errors.New("Invalid block hash") -) - -type ErrVoteConflictingSignature struct { - VoteA *Vote - VoteB *Vote -} - -func (err *ErrVoteConflictingSignature) Error() string { - return "Conflicting round vote signature" -} - -// Represents a prevote, precommit, or commit vote from validators for consensus. -type Vote struct { - Height int `json:"height"` - Round int `json:"round"` - Type byte `json:"type"` - BlockHash []byte `json:"block_hash"` // empty if vote is nil. - BlockPartsHeader PartSetHeader `json:"block_parts_header"` // zero if vote is nil. - Signature crypto.SignatureEd25519 `json:"signature"` -} - -// Types of votes -const ( - VoteTypePrevote = byte(0x01) - VoteTypePrecommit = byte(0x02) -) - -func (vote *Vote) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { - wire.WriteTo([]byte(Fmt(`{"chain_id":"%s"`, chainID)), w, n, err) - wire.WriteTo([]byte(Fmt(`,"vote":{"block_hash":"%X","block_parts_header":%v`, vote.BlockHash, vote.BlockPartsHeader)), w, n, err) - wire.WriteTo([]byte(Fmt(`,"height":%v,"round":%v,"type":%v}}`, vote.Height, vote.Round, vote.Type)), w, n, err) -} - -func (vote *Vote) Copy() *Vote { - voteCopy := *vote - return &voteCopy -} - -func (vote *Vote) String() string { - if vote == nil { - return "nil-Vote" - } - var typeString string - switch vote.Type { - case VoteTypePrevote: - typeString = "Prevote" - case VoteTypePrecommit: - typeString = "Precommit" - default: - PanicSanity("Unknown vote type") - } - - return fmt.Sprintf("Vote{%v/%02d/%v(%v) %X#%v %v}", vote.Height, vote.Round, vote.Type, typeString, Fingerprint(vote.BlockHash), vote.BlockPartsHeader, vote.Signature) -} - -//-------------------------------------------------------------------------------- -// TODO: Move blocks/Validation to here? - -// Common interface between *consensus.VoteSet and types.Validation -type VoteSetReader interface { - Height() int - Round() int - Type() byte - Size() int - BitArray() *BitArray - GetByIndex(int) *Vote - IsCommit() bool -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set.go deleted file mode 100644 index 55c24b14dd4f1783a26f40b269a45c17ad98ceef..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set.go +++ /dev/null @@ -1,323 +0,0 @@ -package types - -import ( - "bytes" - "fmt" - "strings" - "sync" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// VoteSet helps collect signatures from validators at each height+round -// for a predefined vote type. -// Note that there three kinds of votes: prevotes, precommits, and commits. -// A commit of prior rounds can be added added in lieu of votes/precommits. -// NOTE: Assumes that the sum total of voting power does not exceed MaxUInt64. -type VoteSet struct { - height int - round int - type_ byte - - mtx sync.Mutex - valSet *ValidatorSet - votes []*Vote // validator index -> vote - votesBitArray *BitArray // validator index -> has vote? - votesByBlock map[string]int64 // string(blockHash)+string(blockParts) -> vote sum. - totalVotes int64 - maj23Hash []byte - maj23PartsHeader PartSetHeader - maj23Exists bool -} - -// Constructs a new VoteSet struct used to accumulate votes for given height/round. -func NewVoteSet(height int, round int, type_ byte, valSet *ValidatorSet) *VoteSet { - if height == 0 { - PanicSanity("Cannot make VoteSet for height == 0, doesn't make sense.") - } - return &VoteSet{ - height: height, - round: round, - type_: type_, - valSet: valSet, - votes: make([]*Vote, valSet.Size()), - votesBitArray: NewBitArray(valSet.Size()), - votesByBlock: make(map[string]int64), - totalVotes: 0, - } -} - -func (voteSet *VoteSet) Height() int { - if voteSet == nil { - return 0 - } else { - return voteSet.height - } -} - -func (voteSet *VoteSet) Round() int { - if voteSet == nil { - return -1 - } else { - return voteSet.round - } -} - -func (voteSet *VoteSet) Type() byte { - if voteSet == nil { - return 0x00 - } else { - return voteSet.type_ - } -} - -func (voteSet *VoteSet) Size() int { - if voteSet == nil { - return 0 - } else { - return voteSet.valSet.Size() - } -} - -// Returns added=true, index if vote was added -// Otherwise returns err=ErrVote[UnexpectedStep|InvalidAccount|InvalidSignature|InvalidBlockHash|ConflictingSignature] -// Duplicate votes return added=false, err=nil. -// NOTE: vote should not be mutated after adding. -func (voteSet *VoteSet) AddByIndex(valIndex int, vote *Vote) (added bool, address []byte, err error) { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - - return voteSet.addByIndex(valIndex, vote) -} - -// Returns added=true, index if vote was added -// Otherwise returns err=ErrVote[UnexpectedStep|InvalidAccount|InvalidSignature|InvalidBlockHash|ConflictingSignature] -// Duplicate votes return added=false, err=nil. -// NOTE: vote should not be mutated after adding. -func (voteSet *VoteSet) AddByAddress(address []byte, vote *Vote) (added bool, index int, err error) { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - - // Ensure that signer is a validator. - valIndex, val := voteSet.valSet.GetByAddress(address) - if val == nil { - return false, 0, ErrVoteInvalidAccount - } - - return voteSet.addVote(val, valIndex, vote) -} - -func (voteSet *VoteSet) addByIndex(valIndex int, vote *Vote) (added bool, address []byte, err error) { - // Ensure that signer is a validator. - address, val := voteSet.valSet.GetByIndex(valIndex) - if val == nil { - return false, nil, ErrVoteInvalidAccount - } - - added, _, err = voteSet.addVote(val, valIndex, vote) - return -} - -func (voteSet *VoteSet) addVote(val *Validator, valIndex int, vote *Vote) (bool, int, error) { - - // Make sure the step matches. (or that vote is commit && round < voteSet.round) - if (vote.Height != voteSet.height) || - (vote.Round != voteSet.round) || - (vote.Type != voteSet.type_) { - return false, 0, ErrVoteUnexpectedStep - } - - // Check signature. - if !val.PubKey.VerifyBytes(SignBytes(config.GetString("chain_id"), vote), vote.Signature) { - // Bad signature. - return false, 0, ErrVoteInvalidSignature - } - - // If vote already exists, return false. - if existingVote := voteSet.votes[valIndex]; existingVote != nil { - if bytes.Equal(existingVote.BlockHash, vote.BlockHash) { - return false, valIndex, nil - } else { - return false, valIndex, &ErrVoteConflictingSignature{ - VoteA: existingVote, - VoteB: vote, - } - } - } - - // Add vote. - voteSet.votes[valIndex] = vote - voteSet.votesBitArray.SetIndex(valIndex, true) - blockKey := string(vote.BlockHash) + string(wire.BinaryBytes(vote.BlockPartsHeader)) - totalBlockHashVotes := voteSet.votesByBlock[blockKey] + val.VotingPower - voteSet.votesByBlock[blockKey] = totalBlockHashVotes - voteSet.totalVotes += val.VotingPower - - // If we just nudged it up to two thirds majority, add it. - if totalBlockHashVotes > voteSet.valSet.TotalVotingPower()*2/3 && - (totalBlockHashVotes-val.VotingPower) <= voteSet.valSet.TotalVotingPower()*2/3 { - voteSet.maj23Hash = vote.BlockHash - voteSet.maj23PartsHeader = vote.BlockPartsHeader - voteSet.maj23Exists = true - } - - return true, valIndex, nil -} - -func (voteSet *VoteSet) BitArray() *BitArray { - if voteSet == nil { - return nil - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return voteSet.votesBitArray.Copy() -} - -func (voteSet *VoteSet) GetByIndex(valIndex int) *Vote { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return voteSet.votes[valIndex] -} - -func (voteSet *VoteSet) GetByAddress(address []byte) *Vote { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - valIndex, val := voteSet.valSet.GetByAddress(address) - if val == nil { - PanicSanity("GetByAddress(address) returned nil") - } - return voteSet.votes[valIndex] -} - -func (voteSet *VoteSet) HasTwoThirdsMajority() bool { - if voteSet == nil { - return false - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return voteSet.maj23Exists -} - -func (voteSet *VoteSet) IsCommit() bool { - if voteSet == nil { - return false - } - if voteSet.type_ != VoteTypePrecommit { - return false - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return len(voteSet.maj23Hash) > 0 -} - -func (voteSet *VoteSet) HasTwoThirdsAny() bool { - if voteSet == nil { - return false - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return voteSet.totalVotes > voteSet.valSet.TotalVotingPower()*2/3 -} - -// Returns either a blockhash (or nil) that received +2/3 majority. -// If there exists no such majority, returns (nil, false). -func (voteSet *VoteSet) TwoThirdsMajority() (hash []byte, parts PartSetHeader, ok bool) { - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - if voteSet.maj23Exists { - return voteSet.maj23Hash, voteSet.maj23PartsHeader, true - } else { - return nil, PartSetHeader{}, false - } -} - -func (voteSet *VoteSet) String() string { - if voteSet == nil { - return "nil-VoteSet" - } - return voteSet.StringIndented("") -} - -func (voteSet *VoteSet) StringIndented(indent string) string { - voteStrings := make([]string, len(voteSet.votes)) - for i, vote := range voteSet.votes { - if vote == nil { - voteStrings[i] = "nil-Vote" - } else { - voteStrings[i] = vote.String() - } - } - return fmt.Sprintf(`VoteSet{ -%s H:%v R:%v T:%v -%s %v -%s %v -%s}`, - indent, voteSet.height, voteSet.round, voteSet.type_, - indent, strings.Join(voteStrings, "\n"+indent+" "), - indent, voteSet.votesBitArray, - indent) -} - -func (voteSet *VoteSet) StringShort() string { - if voteSet == nil { - return "nil-VoteSet" - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - return fmt.Sprintf(`VoteSet{H:%v R:%v T:%v +2/3:%v %v}`, - voteSet.height, voteSet.round, voteSet.type_, voteSet.maj23Exists, voteSet.votesBitArray) -} - -//-------------------------------------------------------------------------------- -// Validation - -func (voteSet *VoteSet) MakeValidation() *Validation { - if voteSet.type_ != VoteTypePrecommit { - PanicSanity("Cannot MakeValidation() unless VoteSet.Type is VoteTypePrecommit") - } - voteSet.mtx.Lock() - defer voteSet.mtx.Unlock() - if len(voteSet.maj23Hash) == 0 { - PanicSanity("Cannot MakeValidation() unless a blockhash has +2/3") - } - precommits := make([]*Vote, voteSet.valSet.Size()) - voteSet.valSet.Iterate(func(valIndex int, val *Validator) bool { - vote := voteSet.votes[valIndex] - if vote == nil { - return false - } - if !bytes.Equal(vote.BlockHash, voteSet.maj23Hash) { - return false - } - if !vote.BlockPartsHeader.Equals(voteSet.maj23PartsHeader) { - return false - } - precommits[valIndex] = vote - return false - }) - return &Validation{ - Precommits: precommits, - } -} - -//-------------------------------------------------------------------------------- -// For testing... - -func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidator) { - privVal := GenPrivValidator() - _, tempFilePath := Tempfile("priv_validator_") - privVal.SetFile(tempFilePath) - votePower := minPower - if randPower { - votePower += int64(RandUint32()) - } - val := &Validator{ - Address: privVal.Address, - PubKey: privVal.PubKey, - LastCommitHeight: 0, - VotingPower: votePower, - Accum: 0, - } - return val, privVal -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set_test.go deleted file mode 100644 index d066b9f18c755326de8f450272f47c908094818e..0000000000000000000000000000000000000000 --- a/Godeps/_workspace/src/github.com/tendermint/tendermint/types/vote_set_test.go +++ /dev/null @@ -1,278 +0,0 @@ -package types - -import ( - "bytes" - "sort" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common/test" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - - "testing" -) - -func randVoteSet(height int, round int, type_ byte, numValidators int, votingPower int64) (*VoteSet, *ValidatorSet, []*PrivValidator) { - vals := make([]*Validator, numValidators) - privValidators := make([]*PrivValidator, numValidators) - for i := 0; i < numValidators; i++ { - val, privValidator := RandValidator(false, votingPower) - vals[i] = val - privValidators[i] = privValidator - } - valSet := NewValidatorSet(vals) - sort.Sort(PrivValidatorsByAddress(privValidators)) - return NewVoteSet(height, round, type_, valSet), valSet, privValidators -} - -// Convenience: Return new vote with different height -func withHeight(vote *Vote, height int) *Vote { - vote = vote.Copy() - vote.Height = height - return vote -} - -// Convenience: Return new vote with different round -func withRound(vote *Vote, round int) *Vote { - vote = vote.Copy() - vote.Round = round - return vote -} - -// Convenience: Return new vote with different type -func withType(vote *Vote, type_ byte) *Vote { - vote = vote.Copy() - vote.Type = type_ - return vote -} - -// Convenience: Return new vote with different blockHash -func withBlockHash(vote *Vote, blockHash []byte) *Vote { - vote = vote.Copy() - vote.BlockHash = blockHash - return vote -} - -// Convenience: Return new vote with different blockParts -func withBlockPartsHeader(vote *Vote, blockPartsHeader PartSetHeader) *Vote { - vote = vote.Copy() - vote.BlockPartsHeader = blockPartsHeader - return vote -} - -func signAddVote(privVal *PrivValidator, vote *Vote, voteSet *VoteSet) (bool, error) { - privVal.SignVoteUnsafe(config.GetString("chain_id"), vote) - added, _, err := voteSet.AddByAddress(privVal.Address, vote) - return added, err -} - -func TestAddVote(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) - val0 := privValidators[0] - - // t.Logf(">> %v", voteSet) - - if voteSet.GetByAddress(val0.Address) != nil { - t.Errorf("Expected GetByAddress(val0.Address) to be nil") - } - if voteSet.BitArray().GetIndex(0) { - t.Errorf("Expected BitArray.GetIndex(0) to be false") - } - hash, header, ok := voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } - - vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} - signAddVote(val0, vote, voteSet) - - if voteSet.GetByAddress(val0.Address) == nil { - t.Errorf("Expected GetByAddress(val0.Address) to be present") - } - if !voteSet.BitArray().GetIndex(0) { - t.Errorf("Expected BitArray.GetIndex(0) to be true") - } - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } -} - -func Test2_3Majority(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) - - vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} - - // 6 out of 10 voted for nil. - for i := 0; i < 6; i++ { - signAddVote(privValidators[i], vote, voteSet) - } - hash, header, ok := voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } - - // 7th validator voted for some blockhash - { - signAddVote(privValidators[6], withBlockHash(vote, RandBytes(32)), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } - } - - // 8th validator voted for nil. - { - signAddVote(privValidators[7], vote, voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || !ok { - t.Errorf("There should be 2/3 majority for nil") - } - } -} - -func Test2_3MajorityRedux(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 100, 1) - - blockHash := CRandBytes(32) - blockPartsTotal := 123 - blockPartsHeader := PartSetHeader{blockPartsTotal, CRandBytes(32)} - - vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockPartsHeader: blockPartsHeader} - - // 66 out of 100 voted for nil. - for i := 0; i < 66; i++ { - signAddVote(privValidators[i], vote, voteSet) - } - hash, header, ok := voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority") - } - - // 67th validator voted for nil - { - signAddVote(privValidators[66], withBlockHash(vote, nil), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority: last vote added was nil") - } - } - - // 68th validator voted for a different BlockParts PartSetHeader - { - blockPartsHeader := PartSetHeader{blockPartsTotal, CRandBytes(32)} - signAddVote(privValidators[67], withBlockPartsHeader(vote, blockPartsHeader), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Hash") - } - } - - // 69th validator voted for different BlockParts Total - { - blockPartsHeader := PartSetHeader{blockPartsTotal + 1, blockPartsHeader.Hash} - signAddVote(privValidators[68], withBlockPartsHeader(vote, blockPartsHeader), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Total") - } - } - - // 70th validator voted for different BlockHash - { - signAddVote(privValidators[69], withBlockHash(vote, RandBytes(32)), voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if hash != nil || !header.IsZero() || ok { - t.Errorf("There should be no 2/3 majority: last vote added had different BlockHash") - } - } - - // 71st validator voted for the right BlockHash & BlockPartsHeader - { - signAddVote(privValidators[70], vote, voteSet) - hash, header, ok = voteSet.TwoThirdsMajority() - if !bytes.Equal(hash, blockHash) || !header.Equals(blockPartsHeader) || !ok { - t.Errorf("There should be 2/3 majority") - } - } -} - -func TestBadVotes(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) - - // val0 votes for nil. - vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} - added, err := signAddVote(privValidators[0], vote, voteSet) - if !added || err != nil { - t.Errorf("Expected VoteSet.Add to succeed") - } - - // val0 votes again for some block. - added, err = signAddVote(privValidators[0], withBlockHash(vote, RandBytes(32)), voteSet) - if added || err == nil { - t.Errorf("Expected VoteSet.Add to fail, dupeout.") - } - - // val1 votes on another height - added, err = signAddVote(privValidators[1], withHeight(vote, height+1), voteSet) - if added { - t.Errorf("Expected VoteSet.Add to fail, wrong height") - } - - // val2 votes on another round - added, err = signAddVote(privValidators[2], withRound(vote, round+1), voteSet) - if added { - t.Errorf("Expected VoteSet.Add to fail, wrong round") - } - - // val3 votes of another type. - added, err = signAddVote(privValidators[3], withType(vote, VoteTypePrecommit), voteSet) - if added { - t.Errorf("Expected VoteSet.Add to fail, wrong type") - } -} - -func TestMakeValidation(t *testing.T) { - height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrecommit, 10, 1) - blockHash, blockPartsHeader := CRandBytes(32), PartSetHeader{123, CRandBytes(32)} - - vote := &Vote{Height: height, Round: round, Type: VoteTypePrecommit, - BlockHash: blockHash, BlockPartsHeader: blockPartsHeader} - - // 6 out of 10 voted for some block. - for i := 0; i < 6; i++ { - signAddVote(privValidators[i], vote, voteSet) - } - - // MakeValidation should fail. - AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeValidation() }) - - // 7th voted for some other block. - { - vote := withBlockHash(vote, RandBytes(32)) - vote = withBlockPartsHeader(vote, PartSetHeader{123, RandBytes(32)}) - signAddVote(privValidators[6], vote, voteSet) - } - - // The 8th voted like everyone else. - { - signAddVote(privValidators[7], vote, voteSet) - } - - validation := voteSet.MakeValidation() - - // Validation should have 10 elements - if len(validation.Precommits) != 10 { - t.Errorf("Validation Precommits should have the same number of precommits as validators") - } - - // Ensure that Validation precommits are ordered. - if err := validation.ValidateBasic(); err != nil { - t.Errorf("Error in Validation.ValidateBasic(): %v", err) - } - -} diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go index f8478ba69bf39bcc30be4e11370d00a4ebc4f751..e5945c81cb8b7277a74e72233b0780eb61994eb3 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/server/server.go @@ -7,9 +7,9 @@ import ( "net" "strings" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" + "github.com/tendermint/tmsp/types" ) // var maxNumberConnections = 2 diff --git a/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go index e8756a414f0b7b6ddff72a594ccb676f2a4e2161..634c89b3bde7f5697fb02f39d824c29a460ec425 100644 --- a/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go +++ b/Godeps/_workspace/src/github.com/tendermint/tmsp/types/messages.go @@ -1,6 +1,6 @@ package types -import "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" +import "github.com/tendermint/go-wire" const ( requestTypeEcho = byte(0x01) diff --git a/account/account.go b/account/account.go index 2caea0d2d97262c8041eeb3166189f49d2080069..62e1a8209e6f4b0aa37de3f5736807560305b927 100644 --- a/account/account.go +++ b/account/account.go @@ -5,10 +5,11 @@ import ( "fmt" "io" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" ptypes "github.com/eris-ltd/eris-db/permission/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-merkle" + "github.com/tendermint/go-wire" ) // Signable is an interface for all signable things. @@ -38,12 +39,12 @@ func HashSignBytes(chainID string, o Signable) []byte { // on the blockchain. // Serialized by wire.[read|write]Reflect type Account struct { - Address []byte `json:"address"` - PubKey PubKey `json:"pub_key"` - Sequence int `json:"sequence"` - Balance int64 `json:"balance"` - Code []byte `json:"code"` // VM code - StorageRoot []byte `json:"storage_root"` // VM storage merkle root. + Address []byte `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` + Sequence int `json:"sequence"` + Balance int64 `json:"balance"` + Code []byte `json:"code"` // VM code + StorageRoot []byte `json:"storage_root"` // VM storage merkle root. Permissions ptypes.AccountPermissions `json:"permissions"` } @@ -72,3 +73,18 @@ var AccountCodec = wire.Codec{ Encode: AccountEncoder, Decode: AccountDecoder, } + +func EncodeAccount(acc *Account) []byte { + w := new(bytes.Buffer) + var n int + var err error + AccountEncoder(acc, w, &n, &err) + return w.Bytes() +} + +func DecodeAccount(accBytes []byte) *Account { + var n int + var err error + acc := AccountDecoder(bytes.NewBuffer(accBytes), &n, &err) + return acc.(*Account) +} diff --git a/account/priv_account.go b/account/priv_account.go index 1def3a2abec94a443b200cdbf759e359dc30566d..4e016a0f40a966683f282e7015232d8157567ce7 100644 --- a/account/priv_account.go +++ b/account/priv_account.go @@ -1,19 +1,20 @@ package account import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/ed25519" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" + "github.com/tendermint/go-crypto" ) type PrivAccount struct { - Address []byte `json:"address"` - PubKey PubKey `json:"pub_key"` - PrivKey PrivKey `json:"priv_key"` + Address []byte `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` + PrivKey crypto.PrivKey `json:"priv_key"` } func (pA *PrivAccount) Generate(index int) *PrivAccount { - newPrivKey := pA.PrivKey.(PrivKeyEd25519).Generate(index) + newPrivKey := pA.PrivKey.(crypto.PrivKeyEd25519).Generate(index) newPubKey := newPrivKey.PubKey() newAddress := newPubKey.Address() return &PrivAccount{ @@ -23,7 +24,7 @@ func (pA *PrivAccount) Generate(index int) *PrivAccount { } } -func (pA *PrivAccount) Sign(chainID string, o Signable) Signature { +func (pA *PrivAccount) Sign(chainID string, o Signable) crypto.Signature { return pA.PrivKey.Sign(SignBytes(chainID, o)) } @@ -38,8 +39,8 @@ func GenPrivAccount() *PrivAccount { privKeyBytes := new([64]byte) copy(privKeyBytes[:32], CRandBytes(32)) pubKeyBytes := ed25519.MakePublicKey(privKeyBytes) - pubKey := PubKeyEd25519(*pubKeyBytes) - privKey := PrivKeyEd25519(*privKeyBytes) + pubKey := crypto.PubKeyEd25519(*pubKeyBytes) + privKey := crypto.PrivKeyEd25519(*privKeyBytes) return &PrivAccount{ Address: pubKey.Address(), PubKey: pubKey, @@ -58,8 +59,8 @@ func GenPrivAccountFromSecret(secret string) *PrivAccount { privKeyBytes := new([64]byte) copy(privKeyBytes[:32], privKey32) pubKeyBytes := ed25519.MakePublicKey(privKeyBytes) - pubKey := PubKeyEd25519(*pubKeyBytes) - privKey := PrivKeyEd25519(*privKeyBytes) + pubKey := crypto.PubKeyEd25519(*pubKeyBytes) + privKey := crypto.PrivKeyEd25519(*privKeyBytes) return &PrivAccount{ Address: pubKey.Address(), PubKey: pubKey, @@ -74,8 +75,8 @@ func GenPrivAccountFromPrivKeyBytes(privKeyBytes []byte) *PrivAccount { var privKeyArray [64]byte copy(privKeyArray[:], privKeyBytes) pubKeyBytes := ed25519.MakePublicKey(&privKeyArray) - pubKey := PubKeyEd25519(*pubKeyBytes) - privKey := PrivKeyEd25519(privKeyArray) + pubKey := crypto.PubKeyEd25519(*pubKeyBytes) + privKey := crypto.PrivKeyEd25519(privKeyArray) return &PrivAccount{ Address: pubKey.Address(), PubKey: pubKey, diff --git a/account/priv_key.go b/account/priv_key.go deleted file mode 100644 index b7f1dd9f84a64931b668e6a5816091e5a33d0973..0000000000000000000000000000000000000000 --- a/account/priv_key.go +++ /dev/null @@ -1,70 +0,0 @@ -package account - -import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// PrivKey is part of PrivAccount and state.PrivValidator. -type PrivKey interface { - Sign(msg []byte) Signature - PubKey() PubKey -} - -// Types of PrivKey implementations -const ( - PrivKeyTypeEd25519 = byte(0x01) -) - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ PrivKey }{}, - wire.ConcreteType{PrivKeyEd25519{}, PrivKeyTypeEd25519}, -) - -//------------------------------------- - -// Implements PrivKey -type PrivKeyEd25519 [64]byte - -func (key PrivKeyEd25519) Sign(msg []byte) Signature { - privKeyBytes := [64]byte(key) - signatureBytes := ed25519.Sign(&privKeyBytes, msg) - return SignatureEd25519(*signatureBytes) -} - -func (privKey PrivKeyEd25519) PubKey() PubKey { - privKeyBytes := [64]byte(privKey) - return PubKeyEd25519(*ed25519.MakePublicKey(&privKeyBytes)) -} - -func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte { - keyCurve25519 := new([32]byte) - privKeyBytes := [64]byte(privKey) - extra25519.PrivateKeyToCurve25519(keyCurve25519, &privKeyBytes) - return keyCurve25519 -} - -func (privKey PrivKeyEd25519) String() string { - return Fmt("PrivKeyEd25519{*****}") -} - -// Deterministically generates new priv-key bytes from key. -func (key PrivKeyEd25519) Generate(index int) PrivKeyEd25519 { - newBytes := wire.BinarySha256(struct { - PrivKey [64]byte - Index int - }{key, index}) - var newKey [64]byte - copy(newKey[:], newBytes) - return PrivKeyEd25519(newKey) -} - -func GenPrivKeyEd25519() PrivKeyEd25519 { - privKeyBytes := new([64]byte) - copy(privKeyBytes[:32], CRandBytes(32)) - ed25519.MakePublicKey(privKeyBytes) - return PrivKeyEd25519(*privKeyBytes) -} diff --git a/account/pub_key.go b/account/pub_key.go deleted file mode 100644 index 9b949a518d9b8412b4bc7ecdf7fcd554a207c82a..0000000000000000000000000000000000000000 --- a/account/pub_key.go +++ /dev/null @@ -1,90 +0,0 @@ -package account - -import ( - "bytes" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519/extra25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/ripemd160" -) - -// PubKey is part of Account and Validator. -type PubKey interface { - Address() []byte - VerifyBytes(msg []byte, sig Signature) bool -} - -// Types of PubKey implementations -const ( - PubKeyTypeEd25519 = byte(0x01) -) - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ PubKey }{}, - wire.ConcreteType{PubKeyEd25519{}, PubKeyTypeEd25519}, -) - -//------------------------------------- - -// Implements PubKey -type PubKeyEd25519 [32]byte - -// TODO: Slicing the array gives us length prefixing but loses the type byte. -// Revisit if we add more pubkey types. -// For now, we artificially append the type byte in front to give us backwards -// compatibility for when the pubkey wasn't fixed length array -func (pubKey PubKeyEd25519) Address() []byte { - w, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(pubKey[:], w, n, err) - if *err != nil { - PanicCrisis(*err) - } - // append type byte - encodedPubkey := append([]byte{1}, w.Bytes()...) - hasher := ripemd160.New() - hasher.Write(encodedPubkey) // does not error - return hasher.Sum(nil) -} - -// TODO: Consider returning a reason for failure, or logging a runtime type mismatch. -func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool { - sig, ok := sig_.(SignatureEd25519) - if !ok { - return false - } - pubKeyBytes := [32]byte(pubKey) - sigBytes := [64]byte(sig) - return ed25519.Verify(&pubKeyBytes, msg, &sigBytes) -} - -// For use with golang/crypto/nacl/box -// If error, returns nil. -func (pubKey PubKeyEd25519) ToCurve25519() *[32]byte { - keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey) - ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes) - if !ok { - return nil - } - return keyCurve25519 -} - -func (pubKey PubKeyEd25519) String() string { - return Fmt("PubKeyEd25519{%X}", pubKey[:]) -} - -// Must return the full bytes in hex. -// Used for map keying, etc. -func (pubKey PubKeyEd25519) KeyString() string { - return Fmt("%X", pubKey[:]) -} - -func (pubKey PubKeyEd25519) Equals(other PubKey) bool { - if otherEd, ok := other.(PubKeyEd25519); ok { - return bytes.Equal(pubKey[:], otherEd[:]) - } else { - return false - } -} diff --git a/account/signature.go b/account/signature.go deleted file mode 100644 index 2b829324d726b9981bca1626523efb7f20a3263c..0000000000000000000000000000000000000000 --- a/account/signature.go +++ /dev/null @@ -1,34 +0,0 @@ -package account - -import ( - "fmt" - - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -// Signature is a part of Txs and consensus Votes. -type Signature interface { - IsZero() bool - String() string -} - -// Types of Signature implementations -const ( - SignatureTypeEd25519 = byte(0x01) -) - -// for wire.readReflect -var _ = wire.RegisterInterface( - struct{ Signature }{}, - wire.ConcreteType{SignatureEd25519{}, SignatureTypeEd25519}, -) - -//------------------------------------- - -// Implements Signature -type SignatureEd25519 [64]byte - -func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 } - -func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) } diff --git a/account/signature_test.go b/account/signature_test.go deleted file mode 100644 index 0e2789357ec21db621650da07dff2f960e1853c6..0000000000000000000000000000000000000000 --- a/account/signature_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package account - -import ( - "bytes" - "testing" - - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/ed25519" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" -) - -func TestSignAndValidate(t *testing.T) { - - privAccount := GenPrivAccount() - pubKey := privAccount.PubKey - privKey := privAccount.PrivKey - - msg := CRandBytes(128) - sig := privKey.Sign(msg) - t.Logf("msg: %X, sig: %X", msg, sig) - - // Test the signature - if !pubKey.VerifyBytes(msg, sig) { - t.Errorf("Account message signature verification failed") - } - - // Mutate the signature, just one bit. - sigEd := sig.(SignatureEd25519) - sigEd[0] ^= byte(0x01) - sig = Signature(sigEd) - - if pubKey.VerifyBytes(msg, sig) { - t.Errorf("Account message signature verification should have failed but passed instead") - } -} - -func TestBinaryDecode(t *testing.T) { - - privAccount := GenPrivAccount() - pubKey := privAccount.PubKey - privKey := privAccount.PrivKey - - msg := CRandBytes(128) - sig := privKey.Sign(msg) - t.Logf("msg: %X, sig: %X", msg, sig) - - buf, n, err := new(bytes.Buffer), new(int64), new(error) - wire.WriteBinary(sig, buf, n, err) - if *err != nil { - t.Fatalf("Failed to write Signature: %v", err) - } - - if len(buf.Bytes()) != ed25519.SignatureSize+1 { - // 1 byte TypeByte, 64 bytes signature bytes - t.Fatalf("Unexpected signature write size: %v", len(buf.Bytes())) - } - if buf.Bytes()[0] != SignatureTypeEd25519 { - t.Fatalf("Unexpected signature type byte") - } - - sig2, ok := wire.ReadBinary(SignatureEd25519{}, buf, n, err).(SignatureEd25519) - if !ok || *err != nil { - t.Fatalf("Failed to read Signature: %v", err) - } - - // Test the signature - if !pubKey.VerifyBytes(msg, sig2) { - t.Errorf("Account message signature verification failed") - } -} diff --git a/erisdb/codec.go b/erisdb/codec.go index 84d297613198634820160174528f31aed20b66d3..0039c675b4260df4e348bf5b5ce6e6326031be58 100644 --- a/erisdb/codec.go +++ b/erisdb/codec.go @@ -1,7 +1,7 @@ package erisdb import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/go-wire" rpc "github.com/eris-ltd/eris-db/rpc" "io" "io/ioutil" diff --git a/erisdb/config.go b/erisdb/config.go index 1c038cd66b6f599ea0b1423af403935c31e1f602..7873d89da89fe28d0afd84d6eba94da75591bcde 100644 --- a/erisdb/config.go +++ b/erisdb/config.go @@ -1,7 +1,7 @@ package erisdb import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" + cfg "github.com/tendermint/go-config" ) var config cfg.Config diff --git a/erisdb/erisdbss/http.go b/erisdb/erisdbss/http.go index c98a45a638e2130fe252c4cb77e2445e64d6cd9a..7349b35f156a07163e9b9d273396ee4486f94b85 100644 --- a/erisdb/erisdbss/http.go +++ b/erisdb/erisdbss/http.go @@ -4,9 +4,9 @@ import ( "bytes" "encoding/json" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/server" stypes "github.com/eris-ltd/eris-db/state/types" "net/http" diff --git a/erisdb/erisdbss/log.go b/erisdb/erisdbss/log.go index 37760e9c26334c5751d2e5da0200e196234cda2c..719216427a0cbd239e0ae187dcfac8bf14604a72 100644 --- a/erisdb/erisdbss/log.go +++ b/erisdb/erisdbss/log.go @@ -1,7 +1,7 @@ package erisdbss import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" ) var log = log15.New("module", "eris/serverserver") diff --git a/erisdb/erisdbss/server_manager.go b/erisdb/erisdbss/server_manager.go index 6c96ac674637b33c0103623985cedf679a41ae96..42f5449fc5bded97c60ca22d7bbdc706ee972327 100644 --- a/erisdb/erisdbss/server_manager.go +++ b/erisdb/erisdbss/server_manager.go @@ -3,8 +3,8 @@ package erisdbss import ( "bufio" "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" "github.com/eris-ltd/eris-db/files" "github.com/eris-ltd/eris-db/server" "os" diff --git a/erisdb/event_cache.go b/erisdb/event_cache.go index 81d4bca5d4394d8f852d4cefbfcec1b1c594f1fd..a28752d0546fb42f0f79271f2fa43302d8e7f652 100644 --- a/erisdb/event_cache.go +++ b/erisdb/event_cache.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/go-events" ) var ( @@ -92,7 +92,7 @@ func (this *EventSubscriptions) add(eventId string) (string, error) { } cache := newEventCache() _, errC := this.eventEmitter.Subscribe(subId, eventId, - func(evt types.EventData) { + func(evt events.EventData) { cache.mtx.Lock() defer cache.mtx.Unlock() cache.events = append(cache.events, evt) diff --git a/erisdb/event_cache_test.go b/erisdb/event_cache_test.go index 83410eae32ca251670dfceb615e8a64d8aed40c9..e2348844edb1e8e505c5b810d36c1e884ad1aee8 100644 --- a/erisdb/event_cache_test.go +++ b/erisdb/event_cache_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/assert" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/types" ) var mockInterval = 10 * time.Millisecond @@ -16,13 +16,13 @@ var mockInterval = 10 * time.Millisecond type mockSub struct { subId string eventId string - f func(types.EventData) + f func(events.EventData) shutdown bool sdChan chan struct{} } // A mock event -func newMockSub(subId, eventId string, f func(types.EventData)) mockSub { +func newMockSub(subId, eventId string, f func(events.EventData)) mockSub { return mockSub{subId, eventId, f, false, make(chan struct{})} } @@ -34,7 +34,7 @@ func newMockEventEmitter() *mockEventEmitter { return &mockEventEmitter{make(map[string]mockSub)} } -func (this *mockEventEmitter) Subscribe(subId, eventId string, callback func(types.EventData)) (bool, error) { +func (this *mockEventEmitter) Subscribe(subId, eventId string, callback func(events.EventData)) (bool, error) { if _, ok := this.subs[subId]; ok { return false, nil } @@ -47,7 +47,7 @@ func (this *mockEventEmitter) Subscribe(subId, eventId string, callback func(typ go func() { for { if !me.shutdown { - me.f(types.EventDataNewBlock{}) + me.f(events.EventDataNewBlock{}) } else { return } diff --git a/erisdb/pipe/accounts.go b/erisdb/pipe/accounts.go index 01b5bded239c0bfe396ced056744f65beab4d06d..c7ca785701157d31c2aebfd89cb0d2cb574589bb 100644 --- a/erisdb/pipe/accounts.go +++ b/erisdb/pipe/accounts.go @@ -6,8 +6,8 @@ import ( "fmt" "sync" - cmn "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" acm "github.com/eris-ltd/eris-db/account" + cmn "github.com/tendermint/go-common" "github.com/eris-ltd/eris-db/tmsp" ) @@ -61,8 +61,8 @@ func (this *accounts) Accounts(fda []*FilterData) (*AccountList, error) { if err != nil { return nil, fmt.Errorf("Error in query: " + err.Error()) } - state.GetAccounts().Iterate(func(key interface{}, value interface{}) bool { - acc := value.(*acm.Account) + state.GetAccounts().Iterate(func(key, value []byte) bool { + acc := acm.DecodeAccount(value) if filter.Match(acc) { accounts = append(accounts, acc) } @@ -93,11 +93,11 @@ func (this *accounts) StorageAt(address, key []byte) (*StorageItem, error) { storageRoot := account.StorageRoot storageTree := state.LoadStorage(storageRoot) - _, value := storageTree.Get(cmn.LeftPadWord256(key).Bytes()) + _, value, _ := storageTree.Get(cmn.LeftPadWord256(key).Bytes()) if value == nil { return &StorageItem{key, []byte{}}, nil } - return &StorageItem{key, value.([]byte)}, nil + return &StorageItem{key, value}, nil } // Get the storage of the account with address 'address'. @@ -112,9 +112,9 @@ func (this *accounts) Storage(address []byte) (*Storage, error) { storageRoot := account.StorageRoot storageTree := state.LoadStorage(storageRoot) - storageTree.Iterate(func(key interface{}, value interface{}) bool { + storageTree.Iterate(func(key, value []byte) bool { storageItems = append(storageItems, StorageItem{ - key.([]byte), value.([]byte)}) + key, value}) return false }) return &Storage{storageRoot, storageItems}, nil diff --git a/erisdb/pipe/blockchain.go b/erisdb/pipe/blockchain.go index e254328297c607c724a06eec013347a00a799485..d2bca86d91bf5dfb1983e03b8fef2c8de91b7982 100644 --- a/erisdb/pipe/blockchain.go +++ b/erisdb/pipe/blockchain.go @@ -2,8 +2,8 @@ package pipe import ( "fmt" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/state" "math" "strconv" diff --git a/erisdb/pipe/config.go b/erisdb/pipe/config.go index 24e78b5cf400ca4274cc874f38b60fe1d3aa901d..43f8f6041f95d5c09d4773f029c1a5e529a5bff8 100644 --- a/erisdb/pipe/config.go +++ b/erisdb/pipe/config.go @@ -1,8 +1,8 @@ package pipe import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + cfg "github.com/tendermint/go-config" + "github.com/tendermint/log15" ) var log = log15.New("module", "eris/erisdb_pipe") diff --git a/erisdb/pipe/consensus.go b/erisdb/pipe/consensus.go index 69f1a7a5e8aa4b131a76ae09faf01e460b0d3e13..0e28643e7315a2689d9c372c90de9c51dfd5616c 100644 --- a/erisdb/pipe/consensus.go +++ b/erisdb/pipe/consensus.go @@ -1,7 +1,7 @@ package pipe import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/tmsp" ) diff --git a/erisdb/pipe/events.go b/erisdb/pipe/events.go index f2d15bdb6f16bd3a8ec3bfc0403411b3a3955129..becd920539bd5ffc519f29defda085e10a0fd751 100644 --- a/erisdb/pipe/events.go +++ b/erisdb/pipe/events.go @@ -1,8 +1,7 @@ package pipe import ( - evts "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + evts "github.com/tendermint/go-events" ) // TODO improve @@ -17,7 +16,7 @@ func newEvents(eventSwitch *evts.EventSwitch) *events { } // Subscribe to an event. -func (this *events) Subscribe(subId, event string, callback func(types.EventData)) (bool, error) { +func (this *events) Subscribe(subId, event string, callback func(evts.EventData)) (bool, error) { this.eventSwitch.AddListenerForEvent(subId, event, callback) return true, nil } diff --git a/erisdb/pipe/namereg.go b/erisdb/pipe/namereg.go index f9a42a77718c18b0f39580f90de34f623f317142..ac15350d7eeeb184ee8d959de46b7142ad16f552 100644 --- a/erisdb/pipe/namereg.go +++ b/erisdb/pipe/namereg.go @@ -6,6 +6,7 @@ import ( "fmt" "sync" + sm "github.com/eris-ltd/eris-db/state" "github.com/eris-ltd/eris-db/tmsp" "github.com/eris-ltd/eris-db/txs" ) @@ -65,8 +66,8 @@ func (this *namereg) Entries(filters []*FilterData) (*ResultListNames, error) { if err != nil { return nil, fmt.Errorf("Error in query: " + err.Error()) } - state.GetNames().Iterate(func(key interface{}, value interface{}) bool { - nre := value.(*types.NameRegEntry) + state.GetNames().Iterate(func(key, value []byte) bool { + nre := sm.DecodeNameRegEntry(value) if filter.Match(nre) { names = append(names, nre) } diff --git a/erisdb/pipe/pipe.go b/erisdb/pipe/pipe.go index 043ba67fce17daf2925e8747827844f07d0b5e75..2e43fa5b4e4784e3a560b82d096941ae359e4474 100644 --- a/erisdb/pipe/pipe.go +++ b/erisdb/pipe/pipe.go @@ -2,9 +2,9 @@ package pipe import ( - em "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" + em "github.com/tendermint/go-events" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/tmsp" txs "github.com/eris-ltd/eris-db/txs" @@ -48,7 +48,7 @@ type ( } EventEmitter interface { - Subscribe(subId, event string, callback func(types.EventData)) (bool, error) + Subscribe(subId, event string, callback func(em.EventData)) (bool, error) Unsubscribe(subId string) (bool, error) } diff --git a/erisdb/pipe/transactor.go b/erisdb/pipe/transactor.go index 07031a7b9c3bd94af93b8207a6914b928267fd1f..31779df3f1fa3a8846d8c51477bf5efffe7b5b09 100644 --- a/erisdb/pipe/transactor.go +++ b/erisdb/pipe/transactor.go @@ -12,9 +12,9 @@ import ( "github.com/eris-ltd/eris-db/state" "github.com/eris-ltd/eris-db/txs" - cmn "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - tEvents "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - mintTypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + cmn "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + tEvents "github.com/tendermint/go-events" "github.com/eris-ltd/eris-db/tmsp" ) @@ -184,7 +184,7 @@ func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, } wc := make(chan *types.EventDataCall) subId := fmt.Sprintf("%X", rec.TxHash) - this.eventEmitter.Subscribe(subId, types.EventStringAccCall(addr), func(evt mintTypes.EventData) { + this.eventEmitter.Subscribe(subId, types.EventStringAccCall(addr), func(evt tEvents.EventData) { event := evt.(types.EventDataCall) if bytes.Equal(event.TxID, rec.TxHash) { wc <- &event @@ -268,7 +268,7 @@ func (this *transactor) SignTx(tx types.Tx, privAccounts []*account.PrivAccount) bondTx := tx.(*types.BondTx) // the first privaccount corresponds to the BondTx pub key. // the rest to the inputs - bondTx.Signature = privAccounts[0].Sign(chainId, bondTx).(account.SignatureEd25519) + bondTx.Signature = privAccounts[0].Sign(chainId, bondTx).(crypto.SignatureEd25519) for i, input := range bondTx.Inputs { input.PubKey = privAccounts[i+1].PubKey input.Signature = privAccounts[i+1].Sign(chainId, bondTx) @@ -276,11 +276,11 @@ func (this *transactor) SignTx(tx types.Tx, privAccounts []*account.PrivAccount) break case *types.UnbondTx: unbondTx := tx.(*types.UnbondTx) - unbondTx.Signature = privAccounts[0].Sign(chainId, unbondTx).(account.SignatureEd25519) + unbondTx.Signature = privAccounts[0].Sign(chainId, unbondTx).(crypto.SignatureEd25519) break case *types.RebondTx: rebondTx := tx.(*types.RebondTx) - rebondTx.Signature = privAccounts[0].Sign(chainId, rebondTx).(account.SignatureEd25519) + rebondTx.Signature = privAccounts[0].Sign(chainId, rebondTx).(crypto.SignatureEd25519) break default: return nil, fmt.Errorf("Object is not a proper transaction: %v\n", tx) diff --git a/erisdb/pipe/types.go b/erisdb/pipe/types.go index 5e1b784ff2c617298c150a149618a6a7a2aaa252..8f7f24704491aa2b76df1bbc0773e79c32f99315 100644 --- a/erisdb/pipe/types.go +++ b/erisdb/pipe/types.go @@ -1,9 +1,9 @@ package pipe import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" // NodeInfo (drop this!) - csus "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/consensus" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/go-p2p" // NodeInfo (drop this!) + csus "github.com/tendermint/tendermint/consensus" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" ) diff --git a/erisdb/serve.go b/erisdb/serve.go index d74e70cd6a62456af751f5d6f85ca26159b1904d..5ca98370b6b65d3c7132eed430fd683c702c065e 100644 --- a/erisdb/serve.go +++ b/erisdb/serve.go @@ -6,23 +6,23 @@ import ( "bytes" "path" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-p2p" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" - tmcfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/node" sm "github.com/eris-ltd/eris-db/state" stypes "github.com/eris-ltd/eris-db/state/types" + . "github.com/tendermint/go-common" + cfg "github.com/tendermint/go-config" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-events" + "github.com/tendermint/go-p2p" + "github.com/tendermint/go-wire" + "github.com/tendermint/log15" + tmcfg "github.com/tendermint/tendermint/config/tendermint" + "github.com/tendermint/tendermint/node" ep "github.com/eris-ltd/eris-db/erisdb/pipe" "github.com/eris-ltd/eris-db/server" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/server" edbapp "github.com/eris-ltd/eris-db/tmsp" + tmsp "github.com/tendermint/tmsp/server" ) const ERISDB_VERSION = "0.11.5" @@ -143,11 +143,13 @@ func startNode(nd *node.Node, ready chan struct{}, shutDown <-chan struct{}) { nd.Start() - // If seedNode is provided by config, dial out. + /* + // If seedNode is provided by config, dial out. + // should be handled by core - if len(tmConfig.GetString("seeds")) > 0 { - nd.DialSeed() - } + if len(tmConfig.GetString("seeds")) > 0 { + nd.DialSeed() + }*/ if len(tmConfig.GetString("rpc_laddr")) > 0 { nd.StartRPC() diff --git a/erisdb/wsService.go b/erisdb/wsService.go index f146a50e9eefc9cffe67d15d57af2a18cf13741b..6c6dfd865990c22b11e76820a0e344eaf87728e8 100644 --- a/erisdb/wsService.go +++ b/erisdb/wsService.go @@ -7,7 +7,7 @@ import ( rpc "github.com/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/server" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/go-events" ) // Used for ErisDb. Implements WebSocketService. @@ -103,7 +103,7 @@ func (this *ErisDbWsService) EventSubscribe(request *rpc.RPCRequest, requester i if errSID != nil { return nil, rpc.INTERNAL_ERROR, errSID } - callback := func(ret types.EventData) { + callback := func(ret events.EventData) { this.writeResponse(subId, ret, session) } _, errC := this.pipe.Events().Subscribe(subId, eventId, callback) diff --git a/evm/log.go b/evm/log.go index e0861876b6606566647c92f221e77da32f9e4f89..82880ae975da279da6f2cc43c4f0b547079ef790 100644 --- a/evm/log.go +++ b/evm/log.go @@ -1,7 +1,7 @@ package vm import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "vm") diff --git a/evm/native.go b/evm/native.go index 6dbc77631c2d8ea70536e7ac462c3f57228c4534..5082e061491a8a7d2171c2cea65c796b9b966364 100644 --- a/evm/native.go +++ b/evm/native.go @@ -3,7 +3,7 @@ package vm import ( "crypto/sha256" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/code.google.com/p/go.crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) var registeredNativeContracts = make(map[Word256]NativeContract) diff --git a/evm/snative.go b/evm/snative.go index 209dcd5e5966974fac6b7387311400f2535c5a62..9c50cd4e4ba2c21ac09086fe8eac0f9828c4dd44 100644 --- a/evm/snative.go +++ b/evm/snative.go @@ -3,7 +3,7 @@ package vm import ( "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/evm/stack.go b/evm/stack.go index 287b34ab13690075bbdfc08b7e15e885c970c41f..979aba2e3ceb1a8d3f61bf4d7935094619579ed8 100644 --- a/evm/stack.go +++ b/evm/stack.go @@ -2,7 +2,7 @@ package vm import ( "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) // Not goroutine safe diff --git a/evm/test/fake_app_state.go b/evm/test/fake_app_state.go index 952c02b6fc06859a42c91f3bb67fc1586f23642a..9204218fcfe1b72107d359b975cb7c49e7046af5 100644 --- a/evm/test/fake_app_state.go +++ b/evm/test/fake_app_state.go @@ -1,7 +1,7 @@ package vm import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" . "github.com/eris-ltd/eris-db/evm" "github.com/eris-ltd/eris-db/evm/sha3" ) diff --git a/evm/test/log_event_test.go b/evm/test/log_event_test.go index a120d349fc902cb92a5d779afdcddd9a2289efef..6df305af65b040be587aefa68fe51277f816cfb9 100644 --- a/evm/test/log_event_test.go +++ b/evm/test/log_event_test.go @@ -5,9 +5,9 @@ import ( "reflect" "testing" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-events" + "github.com/tendermint/tendermint/types" . "github.com/eris-ltd/eris-db/evm" ) diff --git a/evm/test/vm_test.go b/evm/test/vm_test.go index 6753fe8e7ffba4144548d775a47a38062c09470e..f061aa6e96cbcb3a7f7c601c79b055eab09d2d03 100644 --- a/evm/test/vm_test.go +++ b/evm/test/vm_test.go @@ -8,9 +8,9 @@ import ( "testing" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-events" + "github.com/tendermint/tendermint/types" . "github.com/eris-ltd/eris-db/evm" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/evm/types.go b/evm/types.go index f13cd7301a7efba200fd2e3d1ddcd72ca41fc015..5588d996161f338f6d6b3b8e928b74d28734d0dd 100644 --- a/evm/types.go +++ b/evm/types.go @@ -1,7 +1,7 @@ package vm import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/evm/vm.go b/evm/vm.go index d93395dacf42759d83c449ea999f5d65262b8221..af947fbc3456d1df428f1d68fd27d690a8d64c68 100644 --- a/evm/vm.go +++ b/evm/vm.go @@ -6,11 +6,11 @@ import ( "fmt" "math/big" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" "github.com/eris-ltd/eris-db/evm/sha3" ptypes "github.com/eris-ltd/eris-db/permission/types" types "github.com/eris-ltd/eris-db/txs" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-events" ) var ( diff --git a/files/log.go b/files/log.go index 9067bf137b741db2a06094b0de429054bfcc493e..a18f6b6a6ec7420d469269b33832a2e5cc277a43 100644 --- a/files/log.go +++ b/files/log.go @@ -1,7 +1,7 @@ package files import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" ) var log = log15.New("module", "eris/server/files") diff --git a/permission/types/permissions.go b/permission/types/permissions.go index 13c32964dccb2c57208f730462999dfb07b34cdd..3c43ed17bd64c2600d0f6be5292e7d67690ed90e 100644 --- a/permission/types/permissions.go +++ b/permission/types/permissions.go @@ -2,7 +2,7 @@ package types import ( "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" ) //------------------------------------------------------------------------------------------------ diff --git a/permission/types/snatives.go b/permission/types/snatives.go index 94e602b72e9b19c7ac885b1a2a8b83d1f6e7492b..57315ac937f1c6a58a97410d3f8fe5a0045b3dcd 100644 --- a/permission/types/snatives.go +++ b/permission/types/snatives.go @@ -1,7 +1,7 @@ package types import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/go-wire" ) //--------------------------------------------------------------------------------------------------- diff --git a/server/log.go b/server/log.go index 09e6fbdad3708856ff9bfa14bc8e2236a99ba1eb..aacad33d92109b6353e54b91b438b3f2f7e746f3 100644 --- a/server/log.go +++ b/server/log.go @@ -1,7 +1,7 @@ package server import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" ) var log = log15.New("module", "eris/server") diff --git a/server/logging.go b/server/logging.go index 8b1ba444e437a70995ea69461d4d3c31e0500228..a5a70031af162f749641075bd1dd01e32087946e 100644 --- a/server/logging.go +++ b/server/logging.go @@ -2,7 +2,7 @@ package server import ( "fmt" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" "os" ) diff --git a/state/block_cache.go b/state/block_cache.go index a53675bd980c812548de4311523fa68b1a5a5955..a0d282ed8bff480e36f1f92c904346156ca7a8fa 100644 --- a/state/block_cache.go +++ b/state/block_cache.go @@ -4,22 +4,16 @@ import ( "bytes" "sort" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-merkle" acm "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/txs" ) func makeStorage(db dbm.DB, root []byte) merkle.Tree { - storage := merkle.NewIAVLTree( - wire.BasicCodec, - wire.BasicCodec, - 1024, - db, - ) + storage := merkle.NewIAVLTree(1024, db) storage.Load(root) return storage } @@ -104,10 +98,10 @@ func (cache *BlockCache) GetStorage(addr Word256, key Word256) (value Word256) { } // Load and set cache - _, val_ := storage.Get(key.Bytes()) + _, val_, _ := storage.Get(key.Bytes()) value = Zero256 if val_ != nil { - value = LeftPadWord256(val_.([]byte)) + value = LeftPadWord256(val_) } cache.storages[Tuple256{addr, key}] = storageInfo{value, false} return value diff --git a/state/common.go b/state/common.go index 4e65bf06746e085c5ddf4597b23751ef8d255a5c..1f572a2108044082d9be6fbb0229af6a8418286f 100644 --- a/state/common.go +++ b/state/common.go @@ -1,7 +1,7 @@ package state import ( - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" acm "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/evm" ) diff --git a/state/execution.go b/state/execution.go index 295cc1aeda09a4a88820cd16e55b7dcd279c132c..bb635d0cb53b4329eb44d9e297b6a0d6945b3fca 100644 --- a/state/execution.go +++ b/state/execution.go @@ -5,8 +5,8 @@ import ( "errors" "fmt" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-events" acm "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/evm" diff --git a/state/genesis_test.go b/state/genesis_test.go index 4f1c03d0958fd695c5399a540c54489bea6f567b..e47f98f8cd8197bfd7dd90108773d521c9c034bd 100644 --- a/state/genesis_test.go +++ b/state/genesis_test.go @@ -6,7 +6,7 @@ import ( "fmt" "testing" - tdb "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" + tdb "github.com/tendermint/go-db" ptypes "github.com/eris-ltd/eris-db/permission/types" . "github.com/eris-ltd/eris-db/state/types" ) diff --git a/state/log.go b/state/log.go index 316471eac6339438fca259c340423dea26e2f131..5b102b5703e0474c1ee2db377f3b95c7a8705c3c 100644 --- a/state/log.go +++ b/state/log.go @@ -1,7 +1,7 @@ package state import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "state") diff --git a/state/permissions_test.go b/state/permissions_test.go index 12ab10a482b6c621a52be362446327745b5c8e12..9f3e82705df52a3efd3f4976bcec45a8bc8bb789 100644 --- a/state/permissions_test.go +++ b/state/permissions_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + . "github.com/tendermint/go-common" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-events" + "github.com/tendermint/tendermint/types" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" . "github.com/eris-ltd/eris-db/state/types" diff --git a/state/state.go b/state/state.go index da2dc1e2f92ea7d7bd97e9f15134225c912bd656..626c6aaf50a0e49333cbdbb0399375ad0e793aea 100644 --- a/state/state.go +++ b/state/state.go @@ -11,13 +11,13 @@ import ( . "github.com/eris-ltd/eris-db/state/types" txs "github.com/eris-ltd/eris-db/txs" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-merkle" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/go-events" + "github.com/tendermint/go-merkle" + "github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/types" ) var ( @@ -65,13 +65,13 @@ func LoadState(db dbm.DB) *State { s.LastBondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, maxLoadStateElementSize, n, err).(*types.ValidatorSet) s.UnbondingValidators = wire.ReadBinary(&types.ValidatorSet{}, r, maxLoadStateElementSize, n, err).(*types.ValidatorSet) accountsHash := wire.ReadByteSlice(r, maxLoadStateElementSize, n, err) - s.accounts = merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) + s.accounts = merkle.NewIAVLTree(defaultAccountsCacheCapacity, db) s.accounts.Load(accountsHash) //validatorInfosHash := wire.ReadByteSlice(r, maxLoadStateElementSize, n, err) //s.validatorInfos = merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, db) //s.validatorInfos.Load(validatorInfosHash) nameRegHash := wire.ReadByteSlice(r, maxLoadStateElementSize, n, err) - s.nameReg = merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) + s.nameReg = merkle.NewIAVLTree(0, db) s.nameReg.Load(nameRegHash) if *err != nil { // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED @@ -167,22 +167,20 @@ func (s *State) GetGasLimit() int64 { // State.accounts // Returns nil if account does not exist with given address. -// The returned Account is a copy, so mutating it -// has no side effects. // Implements Statelike func (s *State) GetAccount(address []byte) *acm.Account { - _, acc := s.accounts.Get(address) - if acc == nil { + _, accBytes, _ := s.accounts.Get(address) + if accBytes == nil { return nil } - return acc.(*acm.Account).Copy() + return acm.DecodeAccount(accBytes) } // The account is copied before setting, so mutating it // afterwards has no side effects. // Implements Statelike func (s *State) UpdateAccount(account *acm.Account) bool { - return s.accounts.Set(account.Address, account) + return s.accounts.Set(account.Address, acm.EncodeAccount(account)) } // Implements Statelike @@ -316,7 +314,7 @@ func (s *State) SetValidatorInfos(validatorInfos merkle.Tree) { // State.storage func (s *State) LoadStorage(hash []byte) (storage merkle.Tree) { - storage = merkle.NewIAVLTree(wire.BasicCodec, wire.BasicCodec, 1024, s.DB) + storage = merkle.NewIAVLTree(1024, s.DB) storage.Load(hash) return storage } @@ -326,20 +324,31 @@ func (s *State) LoadStorage(hash []byte) (storage merkle.Tree) { // State.nameReg func (s *State) GetNameRegEntry(name string) *txs.NameRegEntry { - _, value := s.nameReg.Get(name) - if value == nil { + _, valueBytes, _ := s.nameReg.Get([]byte(name)) + if valueBytes == nil { return nil } - return value.(*txs.NameRegEntry).Copy() + return DecodeNameRegEntry(valueBytes) +} + +func DecodeNameRegEntry(entryBytes []byte) *txs.NameRegEntry { + var n int + var err error + value := NameRegCodec.Decode(bytes.NewBuffer(entryBytes), &n, &err) + return value.(*txs.NameRegEntry) } func (s *State) UpdateNameRegEntry(entry *txs.NameRegEntry) bool { - return s.nameReg.Set(entry.Name, entry) + w := new(bytes.Buffer) + var n int + var err error + NameRegCodec.Encode(entry, w, &n, &err) + return s.nameReg.Set([]byte(entry.Name), w.Bytes()) } func (s *State) RemoveNameRegEntry(name string) bool { - _, removed := s.nameReg.Remove(name) + _, removed := s.nameReg.Remove([]byte(name)) return removed } @@ -395,7 +404,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { } // Make accounts state tree - accounts := merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) + accounts := merkle.NewIAVLTree(defaultAccountsCacheCapacity, db) for _, genAcc := range genDoc.Accounts { perm := ptypes.ZeroAccountPermissions if genAcc.Permissions != nil { @@ -408,7 +417,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { Balance: genAcc.Amount, Permissions: perm, } - accounts.Set(acc.Address, acc) + accounts.Set(acc.Address, acm.EncodeAccount(acc)) } // global permissions are saved as the 0 address @@ -428,7 +437,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { Balance: 1337, Permissions: globalPerms, } - accounts.Set(permsAcc.Address, permsAcc) + accounts.Set(permsAcc.Address, acm.EncodeAccount(permsAcc)) // Make validatorInfos state tree && validators slice /* @@ -464,7 +473,7 @@ func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { */ // Make namereg tree - nameReg := merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) + nameReg := merkle.NewIAVLTree(0, db) // TODO: add names, contracts to genesis.json // IAVLTrees must be persisted before copy operations. diff --git a/state/state_test.go b/state/state_test.go index 596b1782e4a0c495e0a1f09d0632feffbd227b69..9c917e78c3103755c42462fccc4f766e54e48ccd 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + _ "github.com/tendermint/tendermint/config/tendermint_test" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" ) diff --git a/state/test.go b/state/test.go index 32a070bd9af67f3facc69281cfc802e7e55bdf1e..3e290fb9760f1728f25f34c99ae5de7d57a83855 100644 --- a/state/test.go +++ b/state/test.go @@ -4,12 +4,13 @@ import ( "sort" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - dbm "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-db" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" . "github.com/eris-ltd/eris-db/state/types" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + dbm "github.com/tendermint/go-db" + "github.com/tendermint/tendermint/types" ) func RandAccount(randBalance bool, minBalance int64) (*acm.Account, *acm.PrivAccount) { @@ -46,7 +47,7 @@ func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numVali for i := 0; i < numValidators; i++ { val, privVal := types.RandValidator(randBonded, minBonded) validators[i] = GenesisValidator{ - PubKey: val.PubKey, + PubKey: val.PubKey.(crypto.PubKeyEd25519), Amount: val.VotingPower, UnbondTo: []BasicAccount{ { diff --git a/state/tx_cache.go b/state/tx_cache.go index 06e55bf12160b25a0af6a6c4747dbf489bc1da70..0bc4a8013aae3a24d58dd4eb0e4101ab8f205d12 100644 --- a/state/tx_cache.go +++ b/state/tx_cache.go @@ -6,7 +6,8 @@ import ( ptypes "github.com/eris-ltd/eris-db/permission/types" // for GlobalPermissionAddress ... "github.com/eris-ltd/eris-db/txs" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" ) type TxCache struct { @@ -161,7 +162,7 @@ func toVMAccount(acc *acm.Account) *vm.Account { // Converts vm.Account to backend.Account struct. func toStateAccount(acc *vm.Account) *acm.Account { - var pubKey acm.PubKey + var pubKey crypto.PubKey var storageRoot []byte if acc.Other != nil { pubKey, storageRoot = acc.Other.(vmAccountOther).unpack() @@ -181,11 +182,11 @@ func toStateAccount(acc *vm.Account) *acm.Account { // Everything in acmAccount that doesn't belong in // exported vmAccount fields. type vmAccountOther struct { - PubKey acm.PubKey + PubKey crypto.PubKey StorageRoot []byte } -func (accOther vmAccountOther) unpack() (acm.PubKey, []byte) { +func (accOther vmAccountOther) unpack() (crypto.PubKey, []byte) { return accOther.PubKey, accOther.StorageRoot } diff --git a/state/tx_cache_test.go b/state/tx_cache_test.go index f07d2cfac8f1cd12f32d4c0a253a85fe57bd3f84..a943ec72844fa37791c4771d78b5931231512ff4 100644 --- a/state/tx_cache_test.go +++ b/state/tx_cache_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + "github.com/tendermint/go-wire" ) func TestStateToFromVMAccount(t *testing.T) { diff --git a/state/types/genesis.go b/state/types/genesis.go index 95e34d23979f2edf9921685ccba1b6d24b9e4a7c..8886da405c2b3b294fbfa6586b0be9d15f74a7b8 100644 --- a/state/types/genesis.go +++ b/state/types/genesis.go @@ -3,9 +3,9 @@ package types import ( "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-crypto" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-wire" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/test/mock/mock_web_api_test.go b/test/mock/mock_web_api_test.go index fc5c65caad768b6e54a51bba18a02061dc48bee4..8671952bbd43d571983628d32fa9bfca1d167fd4 100644 --- a/test/mock/mock_web_api_test.go +++ b/test/mock/mock_web_api_test.go @@ -7,9 +7,9 @@ import ( // edb "github.com/eris-ltd/erisdb/erisdb" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/stretchr/testify/suite" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + "github.com/tendermint/log15" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" edb "github.com/eris-ltd/eris-db/erisdb" ep "github.com/eris-ltd/eris-db/erisdb/pipe" diff --git a/test/mock/pipe.go b/test/mock/pipe.go index 03d09e470d5a195217e50d12d15d25bc09f49f28..3ec3966dcf88224a48114442d6637b6d8ca136be 100644 --- a/test/mock/pipe.go +++ b/test/mock/pipe.go @@ -4,8 +4,8 @@ import ( ep "github.com/eris-ltd/eris-db/erisdb/pipe" td "github.com/eris-ltd/eris-db/test/testdata/testdata" - ctypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/rpc/core/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" + ctypes "github.com/tendermint/tendermint/rpc/core/types" + "github.com/tendermint/tendermint/types" "github.com/eris-ltd/eris-db/account" ) diff --git a/test/server/scumbag.go b/test/server/scumbag.go index dbf50eff00cb111f2eb1e60fea15286c7e361e01..b068666a9fc4203434758876665776705f5b6c76 100644 --- a/test/server/scumbag.go +++ b/test/server/scumbag.go @@ -3,7 +3,7 @@ package server import ( "encoding/json" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" "github.com/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/server" "os" diff --git a/test/transacting/transacting_tes.go b/test/transacting/transacting_tes.go index e7fa397b82a8d4a623bd22f6ef1eab3237a7d3eb..50c642a5f8cde26658469fb2ef7bfe6f4a833820 100644 --- a/test/transacting/transacting_tes.go +++ b/test/transacting/transacting_tes.go @@ -10,7 +10,7 @@ import ( ess "github.com/eris-ltd/eris-db/erisdb/erisdbss" // ep "github.com/eris-ltd/eris-db/erisdb/pipe" "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" "github.com/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/server" td "github.com/eris-ltd/eris-db/test/testdata/testdata" diff --git a/test/web_api/shared.go b/test/web_api/shared.go index 4f08a3c45f73170b113a1cef609d13220fb7a2a0..1c3acb46e12daf30669d105af1fd52c2327c16c6 100644 --- a/test/web_api/shared.go +++ b/test/web_api/shared.go @@ -2,7 +2,7 @@ package web_api import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/gin-gonic/gin" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/log15" + "github.com/tendermint/log15" "os" "runtime" ) diff --git a/tmsp/erisdb.go b/tmsp/erisdb.go index dd89e533ae7c19d5c555c097f4830265b76df1cb..b1329313e2380229a0feab0ff5ac21a6ac137232 100644 --- a/tmsp/erisdb.go +++ b/tmsp/erisdb.go @@ -2,28 +2,31 @@ package tmsp import ( "bytes" + "fmt" "sync" - //sm "github.com/eris-ltd/eris-db/state" - // txs "github.com/eris-ltd/eris-db/txs" - sm "github.com/eris-ltd/eris-db/state" types "github.com/eris-ltd/eris-db/txs" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events" + "github.com/tendermint/go-events" + "github.com/tendermint/go-wire" - tmsp "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tmsp/types" + tmsp "github.com/tendermint/tmsp/types" ) //-------------------------------------------------------------------------------- -// ErisDBApp holds the current state and opens new contexts for proposed updates to the state +// ErisDBApp holds the current state, runs transactions, computes hashes. +// Typically two connections are opened by the tendermint core: +// one for mempool, one for consensus. type ErisDBApp struct { mtx sync.Mutex state *sm.State - evsw *events.EventSwitch + cache *sm.BlockCache + + evc *events.EventCache + evsw *events.EventSwitch } func (app *ErisDBApp) GetState() *sm.State { @@ -35,104 +38,61 @@ func (app *ErisDBApp) GetState() *sm.State { func NewErisDBApp(s *sm.State, evsw *events.EventSwitch) *ErisDBApp { return &ErisDBApp{ state: s, + cache: sm.NewBlockCache(s), + evc: events.NewEventCache(evsw), evsw: evsw, } } // Implements tmsp.Application -func (app *ErisDBApp) Open() tmsp.AppContext { - app.mtx.Lock() - state := app.state.Copy() - app.mtx.Unlock() - return &ErisDBAppContext{ - state: state, - cache: sm.NewBlockCache(state), - evc: events.NewEventCache(app.evsw), - } -} - -//-------------------------------------------------------------------------------- -// ErisDBAppContext runs transactions, computes hashes, and handles commits/rollbacks. -// Typically two contexts (connections) are opened by the tendermint core: -// one for mempool, one for consensus. - -type ErisDBAppContext struct { - app *ErisDBApp - - state *sm.State - cache *sm.BlockCache - - evc *events.EventCache -} - -func (appC *ErisDBAppContext) Echo(message string) string { - return message +func (appC *ErisDBApp) Info() (info string) { + return "ErisDB" } -func (appC *ErisDBAppContext) Info() []string { - return []string{"ErisDB"} -} - -func (appC *ErisDBAppContext) SetOption(key string, value string) tmsp.RetCode { - return 0 +// Implements tmsp.Application +func (appC *ErisDBApp) SetOption(key string, value string) (log string) { + return "" } -func (appC ErisDBAppContext) AppendTx(txBytes []byte) ([]tmsp.Event, tmsp.RetCode) { +// Implements tmsp.Application +func (appC ErisDBApp) AppendTx(txBytes []byte) (code tmsp.CodeType, result []byte, log string) { var n int var err error tx := new(types.Tx) buf := bytes.NewBuffer(txBytes) wire.ReadBinaryPtr(tx, buf, len(txBytes), &n, &err) if err != nil { - // TODO: handle error - return nil, tmsp.RetCodeEncodingError + return tmsp.CodeType_EncodingError, nil, fmt.Sprintf("Encoding error: %v", err) } err = sm.ExecTx(appC.cache, *tx, true, appC.evc) if err != nil { - // TODO: handle error - return nil, tmsp.RetCodeInternalError // ?! + return tmsp.CodeType_InternalError, nil, fmt.Sprintf("Encoding error: %v", err) } - return nil, tmsp.RetCodeOK + return tmsp.CodeType_OK, nil, "" } -func (appC *ErisDBAppContext) GetHash() ([]byte, tmsp.RetCode) { - appC.cache.Sync() - return appC.state.Hash(), tmsp.RetCodeOK +// Implements tmsp.Application +func (appC ErisDBApp) CheckTx(txBytes []byte) (code tmsp.CodeType, result []byte, log string) { + // TODO: precheck + return tmsp.CodeType_OK, nil, "" } -func (appC *ErisDBAppContext) Commit() tmsp.RetCode { +// Implements tmsp.Application +// GetHash should commit the state (called at end of block) +func (appC *ErisDBApp) GetHash() (hash []byte, log string) { + appC.cache.Sync() + // save state to disk appC.state.Save() - // flush events to listeners + // flush events to listeners (XXX: note issue with blocking) appC.evc.Flush() - // update underlying app state for new tmsp connections - appC.app.mtx.Lock() - appC.app.state = appC.state - appC.app.mtx.Unlock() - return 0 -} - -func (appC *ErisDBAppContext) Rollback() tmsp.RetCode { - appC.app.mtx.Lock() - appC.state = appC.app.state - appC.app.mtx.Unlock() - - appC.cache = sm.NewBlockCache(appC.state) - return 0 -} - -func (appC *ErisDBAppContext) AddListener(key string) tmsp.RetCode { - return 0 -} - -func (appC *ErisDBAppContext) RemListener(key string) tmsp.RetCode { - return 0 + return appC.state.Hash(), "" } -func (appC *ErisDBAppContext) Close() error { - return nil +func (appC *ErisDBApp) Query(query []byte) (code tmsp.CodeType, result []byte, log string) { + return tmsp.CodeType_OK, nil, "" } diff --git a/txs/config.go b/txs/config.go index e8f96401a51ce5577a08ce232b3a295fa336f63a..cb982879786196ca20c6e3c6eab16b1b1ecb76e9 100644 --- a/txs/config.go +++ b/txs/config.go @@ -1,7 +1,7 @@ package types import ( - cfg "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-config" + cfg "github.com/tendermint/go-config" ) var config cfg.Config = nil diff --git a/txs/events.go b/txs/events.go index 522658e451199abf9b8ec0a19d93a31e79e5af53..edf7046c4b5e4ba7b54550206a0056b10c0082a2 100644 --- a/txs/events.go +++ b/txs/events.go @@ -4,10 +4,10 @@ import ( "fmt" "time" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" // Block + "github.com/tendermint/tendermint/types" // Block ) // Functions to generate eventId strings diff --git a/txs/log.go b/txs/log.go index 1f22008fda5edddd2366b1bb2a1d8b8794459b5a..dbe8a67821e8d2603e19e7ee716b2c61d80b0309 100644 --- a/txs/log.go +++ b/txs/log.go @@ -1,7 +1,7 @@ package types import ( - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-logger" + "github.com/tendermint/go-logger" ) var log = logger.New("module", "types") diff --git a/txs/tx.go b/txs/tx.go index a65666c32a1dea08511b22585fdce5e0a8e357fc..439ffe5526ffed3d1d8476d60ab9ee811f644e05 100644 --- a/txs/tx.go +++ b/txs/tx.go @@ -7,12 +7,13 @@ import ( "github.com/eris-ltd/eris-db/Godeps/_workspace/src/golang.org/x/crypto/ripemd160" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-wire" + . "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" - "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types" // votes for dupeout .. + "github.com/tendermint/tendermint/types" // votes for dupeout .. + "github.com/tendermint/go-crypto" ) var ( @@ -98,11 +99,11 @@ var _ = wire.RegisterInterface( //----------------------------------------------------------------------------- type TxInput struct { - Address []byte `json:"address"` // Hash of the PubKey - Amount int64 `json:"amount"` // Must not exceed account balance - Sequence int `json:"sequence"` // Must be 1 greater than the last committed TxInput - Signature acm.Signature `json:"signature"` // Depends on the PubKey type and the whole Tx - PubKey acm.PubKey `json:"pub_key"` // Must not be nil, may be nil + Address []byte `json:"address"` // Hash of the PubKey + Amount int64 `json:"amount"` // Must not exceed account balance + Sequence int `json:"sequence"` // Must be 1 greater than the last committed TxInput + Signature crypto.Signature `json:"signature"` // Depends on the PubKey type and the whole Tx + PubKey crypto.PubKey `json:"pub_key"` // Must not be nil, may be nil } func (txIn *TxInput) ValidateBasic() error { @@ -256,10 +257,10 @@ func (tx *NameTx) String() string { //----------------------------------------------------------------------------- type BondTx struct { - PubKey acm.PubKeyEd25519 `json:"pub_key"` - Signature acm.SignatureEd25519 `json:"signature"` - Inputs []*TxInput `json:"inputs"` - UnbondTo []*TxOutput `json:"unbond_to"` + PubKey crypto.PubKeyEd25519 `json:"pub_key"` + Signature crypto.SignatureEd25519 `json:"signature"` + Inputs []*TxInput `json:"inputs"` + UnbondTo []*TxOutput `json:"unbond_to"` } func (tx *BondTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { @@ -290,9 +291,9 @@ func (tx *BondTx) String() string { //----------------------------------------------------------------------------- type UnbondTx struct { - Address []byte `json:"address"` - Height int `json:"height"` - Signature acm.SignatureEd25519 `json:"signature"` + Address []byte `json:"address"` + Height int `json:"height"` + Signature crypto.SignatureEd25519 `json:"signature"` } func (tx *UnbondTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { @@ -307,9 +308,9 @@ func (tx *UnbondTx) String() string { //----------------------------------------------------------------------------- type RebondTx struct { - Address []byte `json:"address"` - Height int `json:"height"` - Signature acm.SignatureEd25519 `json:"signature"` + Address []byte `json:"address"` + Height int `json:"height"` + Signature crypto.SignatureEd25519 `json:"signature"` } func (tx *RebondTx) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { diff --git a/txs/tx_test.go b/txs/tx_test.go index b52e4df7b2a01e7c88dd73bdf47867921990195e..8e772b9ac7fef275e561924c658d50b49ee16917 100644 --- a/txs/tx_test.go +++ b/txs/tx_test.go @@ -3,8 +3,8 @@ package types import ( "testing" - . "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/go-common" - _ "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/config/tendermint_test" + . "github.com/tendermint/go-common" + _ "github.com/tendermint/tendermint/config/tendermint_test" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" ) diff --git a/txs/tx_utils.go b/txs/tx_utils.go index 97bc8a6b8742a28d2bde33badc1e8432b34d7e90..f8ce376a96948ba2558ba8c5977f876a1bd31209 100644 --- a/txs/tx_utils.go +++ b/txs/tx_utils.go @@ -4,6 +4,8 @@ import ( "fmt" acm "github.com/eris-ltd/eris-db/account" ptypes "github.com/eris-ltd/eris-db/permission/types" + + "github.com/tendermint/go-crypto" ) type AccountGetter interface { @@ -20,7 +22,7 @@ func NewSendTx() *SendTx { } } -func (tx *SendTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error { +func (tx *SendTx) AddInput(st AccountGetter, pubkey crypto.PubKey, amt int64) error { addr := pubkey.Address() acc := st.GetAccount(addr) if acc == nil { @@ -29,13 +31,13 @@ func (tx *SendTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1) } -func (tx *SendTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error { +func (tx *SendTx) AddInputWithNonce(pubkey crypto.PubKey, amt int64, nonce int) error { addr := pubkey.Address() tx.Inputs = append(tx.Inputs, &TxInput{ Address: addr, Amount: amt, Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: pubkey, }) return nil @@ -61,7 +63,7 @@ func (tx *SendTx) SignInput(chainID string, i int, privAccount *acm.PrivAccount) //---------------------------------------------------------------------------- // CallTx interface for creating tx -func NewCallTx(st AccountGetter, from acm.PubKey, to, data []byte, amt, gasLimit, fee int64) (*CallTx, error) { +func NewCallTx(st AccountGetter, from crypto.PubKey, to, data []byte, amt, gasLimit, fee int64) (*CallTx, error) { addr := from.Address() acc := st.GetAccount(addr) if acc == nil { @@ -72,13 +74,13 @@ func NewCallTx(st AccountGetter, from acm.PubKey, to, data []byte, amt, gasLimit return NewCallTxWithNonce(from, to, data, amt, gasLimit, fee, nonce), nil } -func NewCallTxWithNonce(from acm.PubKey, to, data []byte, amt, gasLimit, fee int64, nonce int) *CallTx { +func NewCallTxWithNonce(from crypto.PubKey, to, data []byte, amt, gasLimit, fee int64, nonce int) *CallTx { addr := from.Address() input := &TxInput{ Address: addr, Amount: amt, Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: from, } @@ -99,7 +101,7 @@ func (tx *CallTx) Sign(chainID string, privAccount *acm.PrivAccount) { //---------------------------------------------------------------------------- // NameTx interface for creating tx -func NewNameTx(st AccountGetter, from acm.PubKey, name, data string, amt, fee int64) (*NameTx, error) { +func NewNameTx(st AccountGetter, from crypto.PubKey, name, data string, amt, fee int64) (*NameTx, error) { addr := from.Address() acc := st.GetAccount(addr) if acc == nil { @@ -110,13 +112,13 @@ func NewNameTx(st AccountGetter, from acm.PubKey, name, data string, amt, fee in return NewNameTxWithNonce(from, name, data, amt, fee, nonce), nil } -func NewNameTxWithNonce(from acm.PubKey, name, data string, amt, fee int64, nonce int) *NameTx { +func NewNameTxWithNonce(from crypto.PubKey, name, data string, amt, fee int64, nonce int) *NameTx { addr := from.Address() input := &TxInput{ Address: addr, Amount: amt, Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: from, } @@ -136,8 +138,8 @@ func (tx *NameTx) Sign(chainID string, privAccount *acm.PrivAccount) { //---------------------------------------------------------------------------- // BondTx interface for adding inputs/outputs and adding signatures -func NewBondTx(pubkey acm.PubKey) (*BondTx, error) { - pubkeyEd, ok := pubkey.(acm.PubKeyEd25519) +func NewBondTx(pubkey crypto.PubKey) (*BondTx, error) { + pubkeyEd, ok := pubkey.(crypto.PubKeyEd25519) if !ok { return nil, fmt.Errorf("Pubkey must be ed25519") } @@ -148,7 +150,7 @@ func NewBondTx(pubkey acm.PubKey) (*BondTx, error) { }, nil } -func (tx *BondTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error { +func (tx *BondTx) AddInput(st AccountGetter, pubkey crypto.PubKey, amt int64) error { addr := pubkey.Address() acc := st.GetAccount(addr) if acc == nil { @@ -157,13 +159,13 @@ func (tx *BondTx) AddInput(st AccountGetter, pubkey acm.PubKey, amt int64) error return tx.AddInputWithNonce(pubkey, amt, acc.Sequence+1) } -func (tx *BondTx) AddInputWithNonce(pubkey acm.PubKey, amt int64, nonce int) error { +func (tx *BondTx) AddInputWithNonce(pubkey crypto.PubKey, amt int64, nonce int) error { addr := pubkey.Address() tx.Inputs = append(tx.Inputs, &TxInput{ Address: addr, Amount: amt, Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: pubkey, }) return nil @@ -179,7 +181,7 @@ func (tx *BondTx) AddOutput(addr []byte, amt int64) error { func (tx *BondTx) SignBond(chainID string, privAccount *acm.PrivAccount) error { sig := privAccount.Sign(chainID, tx) - sigEd, ok := sig.(acm.SignatureEd25519) + sigEd, ok := sig.(crypto.SignatureEd25519) if !ok { return fmt.Errorf("Bond signer must be ED25519") } @@ -207,7 +209,7 @@ func NewUnbondTx(addr []byte, height int) *UnbondTx { } func (tx *UnbondTx) Sign(chainID string, privAccount *acm.PrivAccount) { - tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519) + tx.Signature = privAccount.Sign(chainID, tx).(crypto.SignatureEd25519) } //---------------------------------------------------------------------- @@ -221,13 +223,13 @@ func NewRebondTx(addr []byte, height int) *RebondTx { } func (tx *RebondTx) Sign(chainID string, privAccount *acm.PrivAccount) { - tx.Signature = privAccount.Sign(chainID, tx).(acm.SignatureEd25519) + tx.Signature = privAccount.Sign(chainID, tx).(crypto.SignatureEd25519) } //---------------------------------------------------------------------------- // PermissionsTx interface for creating tx -func NewPermissionsTx(st AccountGetter, from acm.PubKey, args ptypes.PermArgs) (*PermissionsTx, error) { +func NewPermissionsTx(st AccountGetter, from crypto.PubKey, args ptypes.PermArgs) (*PermissionsTx, error) { addr := from.Address() acc := st.GetAccount(addr) if acc == nil { @@ -238,13 +240,13 @@ func NewPermissionsTx(st AccountGetter, from acm.PubKey, args ptypes.PermArgs) ( return NewPermissionsTxWithNonce(from, args, nonce), nil } -func NewPermissionsTxWithNonce(from acm.PubKey, args ptypes.PermArgs, nonce int) *PermissionsTx { +func NewPermissionsTxWithNonce(from crypto.PubKey, args ptypes.PermArgs, nonce int) *PermissionsTx { addr := from.Address() input := &TxInput{ Address: addr, Amount: 1, // NOTE: amounts can't be 0 ... Sequence: nonce, - Signature: acm.SignatureEd25519{}, + Signature: crypto.SignatureEd25519{}, PubKey: from, }