Merge pull request #711 from tendermint/imports

get rid of anonymous imports
This commit is contained in:
Ethan Buchman 2017-10-04 22:16:07 -04:00 committed by GitHub
commit e756906a0e
55 changed files with 406 additions and 374 deletions

View File

@ -31,14 +31,16 @@ BUG FIXES:
## 0.11.0 (September 22, 2017)
BREAKING:
- state: every validator set change is persisted to disk, which required some changes to the `State` structure.
- cmd: if there is no genesis, exit immediately instead of waiting around for one to show.
- p2p: new `p2p.Peer` interface used for all reactor methods (instead of `*p2p.Peer` struct).
- types: `Signer.Sign` returns an error.
- genesis file: validator `amount` is now `power`
- abci: Info, BeginBlock, InitChain all take structs
- rpc: various changes to match JSONRPC spec (http://www.jsonrpc.org/specification), including breaking ones:
- requests that previously returned HTTP code 4XX now return 200 with an error code in the JSONRPC.
- `rpctypes.RPCResponse` uses new `RPCError` type instead of `string`.
- abci: Info, BeginBlock, InitChain all take structs
- cmd: if there is no genesis, exit immediately instead of waiting around for one to show.
- types: `Signer.Sign` returns an error.
- state: every validator set change is persisted to disk, which required some changes to the `State` structure.
- p2p: new `p2p.Peer` interface used for all reactor methods (instead of `*p2p.Peer` struct).
FEATURES:
- rpc: `/validators?height=X` allows querying of validators at previous heights.

View File

@ -1,8 +1,9 @@
package benchmarks
import (
. "github.com/tendermint/tmlibs/common"
"testing"
cmn "github.com/tendermint/tmlibs/common"
)
func BenchmarkSomething(b *testing.B) {
@ -11,11 +12,11 @@ func BenchmarkSomething(b *testing.B) {
numChecks := 100000
keys := make([]string, numItems)
for i := 0; i < numItems; i++ {
keys[i] = RandStr(100)
keys[i] = cmn.RandStr(100)
}
txs := make([]string, numChecks)
for i := 0; i < numChecks; i++ {
txs[i] = RandStr(100)
txs[i] = cmn.RandStr(100)
}
b.StartTimer()

View File

@ -4,7 +4,7 @@ import (
"os"
"testing"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
func BenchmarkFileWrite(b *testing.B) {
@ -14,7 +14,7 @@ func BenchmarkFileWrite(b *testing.B) {
if err != nil {
b.Error(err)
}
testString := RandStr(200) + "\n"
testString := cmn.RandStr(200) + "\n"
b.StartTimer()
for i := 0; i < b.N; i++ {

View File

@ -3,9 +3,8 @@ package main
import (
"context"
"encoding/binary"
"time"
//"encoding/hex"
"fmt"
"time"
rpcclient "github.com/tendermint/tendermint/rpc/lib/client"
cmn "github.com/tendermint/tmlibs/common"

View File

@ -6,7 +6,7 @@ import (
"time"
"github.com/tendermint/tendermint/types"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
flow "github.com/tendermint/tmlibs/flowrate"
"github.com/tendermint/tmlibs/log"
)
@ -33,7 +33,7 @@ var peerTimeoutSeconds = time.Duration(15) // not const so we can override with
*/
type BlockPool struct {
BaseService
cmn.BaseService
startTime time.Time
mtx sync.Mutex
@ -59,7 +59,7 @@ func NewBlockPool(start int, requestsCh chan<- BlockRequest, timeoutsCh chan<- s
requestsCh: requestsCh,
timeoutsCh: timeoutsCh,
}
bp.BaseService = *NewBaseService(nil, "BlockPool", bp)
bp.BaseService = *cmn.NewBaseService(nil, "BlockPool", bp)
return bp
}
@ -137,14 +137,14 @@ func (pool *BlockPool) IsCaughtUp() bool {
maxPeerHeight := 0
for _, peer := range pool.peers {
maxPeerHeight = MaxInt(maxPeerHeight, peer.height)
maxPeerHeight = cmn.MaxInt(maxPeerHeight, peer.height)
}
// some conditions to determine if we're caught up
receivedBlockOrTimedOut := (pool.height > 0 || time.Since(pool.startTime) > 5*time.Second)
ourChainIsLongestAmongPeers := maxPeerHeight == 0 || pool.height >= maxPeerHeight
isCaughtUp := receivedBlockOrTimedOut && ourChainIsLongestAmongPeers
pool.Logger.Info(Fmt("IsCaughtUp: %v", isCaughtUp), "height", pool.height, "maxPeerHeight", maxPeerHeight)
pool.Logger.Info(cmn.Fmt("IsCaughtUp: %v", isCaughtUp), "height", pool.height, "maxPeerHeight", maxPeerHeight)
return isCaughtUp
}
@ -180,7 +180,7 @@ func (pool *BlockPool) PopRequest() {
delete(pool.requesters, pool.height)
pool.height++
} else {
PanicSanity(Fmt("Expected requester to pop, got nothing at height %v", pool.height))
cmn.PanicSanity(cmn.Fmt("Expected requester to pop, got nothing at height %v", pool.height))
}
}
@ -192,7 +192,7 @@ func (pool *BlockPool) RedoRequest(height int) {
pool.mtx.Unlock()
if request.block == nil {
PanicSanity("Expected block to be non-nil")
cmn.PanicSanity("Expected block to be non-nil")
}
// RemovePeer will redo all requesters associated with this peer.
// TODO: record this malfeasance
@ -311,10 +311,10 @@ func (pool *BlockPool) debug() string {
str := ""
for h := pool.height; h < pool.height+len(pool.requesters); h++ {
if pool.requesters[h] == nil {
str += Fmt("H(%v):X ", h)
str += cmn.Fmt("H(%v):X ", h)
} else {
str += Fmt("H(%v):", h)
str += Fmt("B?(%v) ", pool.requesters[h].block != nil)
str += cmn.Fmt("H(%v):", h)
str += cmn.Fmt("B?(%v) ", pool.requesters[h].block != nil)
}
}
return str
@ -394,7 +394,7 @@ func (peer *bpPeer) onTimeout() {
//-------------------------------------
type bpRequester struct {
BaseService
cmn.BaseService
pool *BlockPool
height int
gotBlockCh chan struct{}
@ -415,7 +415,7 @@ func newBPRequester(pool *BlockPool, height int) *bpRequester {
peerID: "",
block: nil,
}
bpr.BaseService = *NewBaseService(nil, "bpRequester", bpr)
bpr.BaseService = *cmn.NewBaseService(nil, "bpRequester", bpr)
return bpr
}

View File

@ -6,7 +6,7 @@ import (
"time"
"github.com/tendermint/tendermint/types"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tmlibs/log"
)
@ -22,7 +22,7 @@ type testPeer struct {
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)
peerID := cmn.RandStr(12)
height := minHeight + rand.Intn(maxHeight-minHeight)
peers[peerID] = testPeer{peerID, height}
}

View File

@ -235,7 +235,7 @@ FOR_LOOP:
err := bcR.state.Validators.VerifyCommit(
bcR.state.ChainID, types.BlockID{first.Hash(), firstPartsHeader}, first.Height, second.LastCommit)
if err != nil {
bcR.Logger.Info("error in validation", "err", err)
bcR.Logger.Error("Error in validation", "err", err)
bcR.pool.RedoRequest(first.Height)
break SYNC_LOOP
} else {

View File

@ -3,15 +3,15 @@ package commands
import (
"os"
"strconv"
"testing"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tmlibs/cli"
"testing"
)
var (

View File

@ -9,7 +9,7 @@ import (
data "github.com/tendermint/go-wire/data"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/types"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tmlibs/events"
)
@ -149,8 +149,8 @@ func TestByzantine(t *testing.T) {
case <-done:
case <-tick.C:
for i, reactor := range reactors {
t.Log(Fmt("Consensus Reactor %v", i))
t.Log(Fmt("%v", reactor))
t.Log(cmn.Fmt("Consensus Reactor %v", i))
t.Log(cmn.Fmt("%v", reactor))
}
t.Fatalf("Timed out waiting for all validators to commit first block")
}
@ -220,7 +220,7 @@ func sendProposalAndParts(height, round int, cs *ConsensusState, peer p2p.Peer,
// byzantine consensus reactor
type ByzantineReactor struct {
Service
cmn.Service
reactor *ConsensusReactor
}
@ -296,5 +296,5 @@ func (privVal *ByzantinePrivValidator) SignHeartbeat(chainID string, heartbeat *
}
func (privVal *ByzantinePrivValidator) String() string {
return Fmt("PrivValidator{%X}", privVal.GetAddress())
return cmn.Fmt("PrivValidator{%X}", privVal.GetAddress())
}

View File

@ -19,7 +19,7 @@ import (
"github.com/tendermint/tendermint/p2p"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
@ -34,7 +34,7 @@ var config *cfg.Config // NOTE: must be reset for each _test.go file
var ensureTimeout = time.Second * 2
func ensureDir(dir string, mode os.FileMode) {
if err := EnsureDir(dir, mode); err != nil {
if err := cmn.EnsureDir(dir, mode); err != nil {
panic(err)
}
}
@ -341,7 +341,7 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou
state, _ := sm.MakeGenesisState(db, genDoc)
state.SetLogger(logger.With("module", "state", "validator", i))
state.Save()
thisConfig := ResetConfig(Fmt("%s_%d", testName, i))
thisConfig := ResetConfig(cmn.Fmt("%s_%d", testName, i))
for _, opt := range configOpts {
opt(thisConfig)
}
@ -362,13 +362,13 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF
state, _ := sm.MakeGenesisState(db, genDoc)
state.SetLogger(log.TestingLogger().With("module", "state"))
state.Save()
thisConfig := ResetConfig(Fmt("%s_%d", testName, i))
thisConfig := ResetConfig(cmn.Fmt("%s_%d", testName, i))
ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
var privVal types.PrivValidator
if i < nValidators {
privVal = privVals[i]
} else {
_, tempFilePath := Tempfile("priv_validator_")
_, tempFilePath := cmn.Tempfile("priv_validator_")
privVal = types.GenPrivValidatorFS(tempFilePath)
}

View File

@ -5,7 +5,7 @@ import (
"sync"
"github.com/tendermint/tendermint/types"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
type RoundVoteSet struct {
@ -76,7 +76,7 @@ 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")
cmn.PanicSanity("SetRound() must increment hvs.round")
}
for r := hvs.round + 1; r <= round; r++ {
if _, ok := hvs.roundVoteSets[r]; ok {
@ -89,7 +89,7 @@ func (hvs *HeightVoteSet) SetRound(round int) {
func (hvs *HeightVoteSet) addRound(round int) {
if _, ok := hvs.roundVoteSets[round]; ok {
PanicSanity("addRound() for an existing round")
cmn.PanicSanity("addRound() for an existing round")
}
// log.Debug("addRound(round)", "round", round)
prevotes := types.NewVoteSet(hvs.chainID, hvs.height, round, types.VoteTypePrevote, hvs.valSet)
@ -164,7 +164,7 @@ func (hvs *HeightVoteSet) getVoteSet(round int, type_ byte) *types.VoteSet {
case types.VoteTypePrecommit:
return rvs.Precommits
default:
PanicSanity(Fmt("Unexpected vote type %X", type_))
cmn.PanicSanity(cmn.Fmt("Unexpected vote type %X", type_))
return nil
}
}
@ -194,7 +194,7 @@ func (hvs *HeightVoteSet) StringIndented(indent string) string {
voteSetString = roundVoteSet.Precommits.StringShort()
vsStrings = append(vsStrings, voteSetString)
}
return Fmt(`HeightVoteSet{H:%v R:0~%v
return cmn.Fmt(`HeightVoteSet{H:%v R:0~%v
%s %v
%s}`,
hvs.height, hvs.round,

View File

@ -4,7 +4,7 @@ import (
"testing"
"github.com/tendermint/tendermint/types"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
func init() {
@ -57,7 +57,7 @@ func makeVoteHR(t *testing.T, height, round int, privVals []*types.PrivValidator
chainID := config.ChainID
err := privVal.SignVote(chainID, vote)
if err != nil {
panic(Fmt("Error signing vote: %v", err))
panic(cmn.Fmt("Error signing vote: %v", err))
return nil
}
return vote

View File

@ -8,7 +8,7 @@ import (
abci "github.com/tendermint/abci/types"
"github.com/tendermint/tendermint/types"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
func init() {
@ -86,7 +86,7 @@ func deliverTxsRange(cs *ConsensusState, start, end int) {
binary.BigEndian.PutUint64(txBytes, uint64(i))
err := cs.mempool.CheckTx(txBytes, nil)
if err != nil {
panic(Fmt("Error after CheckTx: %v", err))
panic(cmn.Fmt("Error after CheckTx: %v", err))
}
}
}
@ -184,7 +184,7 @@ func NewCounterApplication() *CounterApplication {
}
func (app *CounterApplication) Info(req abci.RequestInfo) abci.ResponseInfo {
return abci.ResponseInfo{Data: Fmt("txs:%v", app.txCount)}
return abci.ResponseInfo{Data: cmn.Fmt("txs:%v", app.txCount)}
}
func (app *CounterApplication) DeliverTx(tx []byte) abci.Result {
@ -201,7 +201,7 @@ func runTx(tx []byte, countPtr *int) abci.Result {
copy(tx8[len(tx8)-len(tx):], tx)
txValue := binary.BigEndian.Uint64(tx8)
if txValue != uint64(count) {
return abci.ErrBadNonce.AppendLog(Fmt("Invalid nonce. Expected %v, got %v", count, txValue))
return abci.ErrBadNonce.AppendLog(cmn.Fmt("Invalid nonce. Expected %v, got %v", count, txValue))
}
*countPtr += 1
return abci.OK

View File

@ -6,6 +6,7 @@ import (
"fmt"
"path/filepath"
"reflect"
"runtime/debug"
"sync"
"time"
@ -609,7 +610,7 @@ func (cs *ConsensusState) newStep() {
func (cs *ConsensusState) receiveRoutine(maxSteps int) {
defer func() {
if r := recover(); r != nil {
cs.Logger.Error("CONSENSUS FAILURE!!!", "err", r)
cs.Logger.Error("CONSENSUS FAILURE!!!", "err", r, "stack", string(debug.Stack()))
}
}()

View File

@ -7,7 +7,7 @@ import (
"time"
"github.com/tendermint/tendermint/types"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
func init() {
@ -80,7 +80,7 @@ func TestProposerSelection0(t *testing.T) {
prop = cs1.GetRoundState().Validators.GetProposer()
if !bytes.Equal(prop.Address, vss[1].GetAddress()) {
panic(Fmt("expected proposer to be validator %d. Got %X", 1, prop.Address))
panic(cmn.Fmt("expected proposer to be validator %d. Got %X", 1, prop.Address))
}
}
@ -101,7 +101,7 @@ func TestProposerSelection2(t *testing.T) {
for i := 0; i < len(vss); i++ {
prop := cs1.GetRoundState().Validators.GetProposer()
if !bytes.Equal(prop.Address, vss[(i+2)%len(vss)].GetAddress()) {
panic(Fmt("expected proposer to be validator %d. Got %X", (i+2)%len(vss), prop.Address))
panic(cmn.Fmt("expected proposer to be validator %d. Got %X", (i+2)%len(vss), prop.Address))
}
rs := cs1.GetRoundState()
@ -432,7 +432,7 @@ func TestLockNoPOL(t *testing.T) {
// now we're on a new round and are the proposer
if !bytes.Equal(rs.ProposalBlock.Hash(), rs.LockedBlock.Hash()) {
panic(Fmt("Expected proposal block to be locked block. Got %v, Expected %v", rs.ProposalBlock, rs.LockedBlock))
panic(cmn.Fmt("Expected proposal block to be locked block. Got %v, Expected %v", rs.ProposalBlock, rs.LockedBlock))
}
<-voteCh // prevote

View File

@ -1,7 +1,7 @@
package consensus
import (
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
// kind of arbitrary
@ -10,4 +10,4 @@ var Major = "0" //
var Minor = "2" // replay refactor
var Revision = "2" // validation -> commit
var Version = Fmt("v%s/%s.%s.%s", Spec, Major, Minor, Revision)
var Version = cmn.Fmt("v%s/%s.%s.%s", Spec, Major, Minor, Revision)

View File

@ -6,7 +6,7 @@ import (
wire "github.com/tendermint/go-wire"
"github.com/tendermint/tendermint/types"
auto "github.com/tendermint/tmlibs/autofile"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
//--------------------------------------------------------
@ -34,7 +34,7 @@ var _ = wire.RegisterInterface(
// TODO: currently the wal is overwritten during replay catchup
// give it a mode so it's either reading or appending - must read to end to start appending again
type WAL struct {
BaseService
cmn.BaseService
group *auto.Group
light bool // ignore block parts
@ -49,7 +49,7 @@ func NewWAL(walFile string, light bool) (*WAL, error) {
group: group,
light: light,
}
wal.BaseService = *NewBaseService(nil, "WAL", wal)
wal.BaseService = *cmn.NewBaseService(nil, "WAL", wal)
return wal, nil
}
@ -86,19 +86,19 @@ func (wal *WAL) Save(wmsg WALMessage) {
var wmsgBytes = wire.JSONBytes(TimedWALMessage{time.Now(), wmsg})
err := wal.group.WriteLine(string(wmsgBytes))
if err != nil {
PanicQ(Fmt("Error writing msg to consensus wal. Error: %v \n\nMessage: %v", err, wmsg))
cmn.PanicQ(cmn.Fmt("Error writing msg to consensus wal. Error: %v \n\nMessage: %v", err, wmsg))
}
// TODO: only flush when necessary
if err := wal.group.Flush(); err != nil {
PanicQ(Fmt("Error flushing consensus wal buf to file. Error: %v \n", err))
cmn.PanicQ(cmn.Fmt("Error flushing consensus wal buf to file. Error: %v \n", err))
}
}
func (wal *WAL) writeEndHeight(height int) {
wal.group.WriteLine(Fmt("#ENDHEIGHT: %v", height))
wal.group.WriteLine(cmn.Fmt("#ENDHEIGHT: %v", height))
// TODO: only flush when necessary
if err := wal.group.Flush(); err != nil {
PanicQ(Fmt("Error flushing consensus wal buf to file. Error: %v \n", err))
cmn.PanicQ(cmn.Fmt("Error flushing consensus wal buf to file. Error: %v \n", err))
}
}

View File

@ -142,6 +142,13 @@ It is unlikely that you will need to implement a client. For details of
our client, see
`here <https://github.com/tendermint/abci/tree/master/client>`__.
Most of the examples below are from `dummy application
<https://github.com/tendermint/abci/blob/master/example/dummy/dummy.go>`__,
which is a part of the abci repo. `persistent_dummy application
<https://github.com/tendermint/abci/blob/master/example/dummy/persistent_dummy.go>`__
is used to show ``BeginBlock``, ``EndBlock`` and ``InitChain``
example implementations.
Blockchain Protocol
-------------------
@ -187,6 +194,12 @@ through all transactions in the mempool, removing any that were included
in the block, and re-run the rest using CheckTx against the post-Commit
mempool state.
::
func (app *DummyApplication) CheckTx(tx []byte) types.Result {
return types.OK
}
Consensus Connection
~~~~~~~~~~~~~~~~~~~~
@ -215,6 +228,19 @@ The block header will be updated (TODO) to include some commitment to
the results of DeliverTx, be it a bitarray of non-OK transactions, or a
merkle root of the data returned by the DeliverTx requests, or both.
::
// tx is either "key=value" or just arbitrary bytes
func (app *DummyApplication) DeliverTx(tx []byte) types.Result {
parts := strings.Split(string(tx), "=")
if len(parts) == 2 {
app.state.Set([]byte(parts[0]), []byte(parts[1]))
} else {
app.state.Set(tx, tx)
}
return types.OK
}
Commit
^^^^^^
@ -228,7 +254,7 @@ Commit, or there will be deadlock. Note also that all remaining
transactions in the mempool are replayed on the mempool connection
(CheckTx) following a commit.
The Commit response includes a byte array, which is the deterministic
The app should respond to the Commit request with a byte array, which is the deterministic
state root of the application. It is included in the header of the next
block. It can be used to provide easily verified Merkle-proofs of the
state of the application.
@ -237,6 +263,13 @@ It is expected that the app will persist state to disk on Commit. The
option to have all transactions replayed from some previous block is the
job of the `Handshake <#handshake>`__.
::
func (app *DummyApplication) Commit() types.Result {
hash := app.state.Hash()
return types.NewResultOK(hash, "")
}
BeginBlock
^^^^^^^^^^
@ -248,6 +281,17 @@ The app should remember the latest height and header (ie. from which it
has run a successful Commit) so that it can tell Tendermint where to
pick up from when it restarts. See information on the Handshake, below.
::
// Track the block hash and header information
func (app *PersistentDummyApplication) BeginBlock(params types.RequestBeginBlock) {
// update latest block info
app.blockHeader = params.Header
// reset valset changes
app.changes = make([]*types.Validator, 0)
}
EndBlock
^^^^^^^^
@ -260,6 +304,13 @@ EndBlock response. To remove one, include it in the list with a
validator set. Note validator set changes are only available in v0.8.0
and up.
::
// Update the validator set
func (app *PersistentDummyApplication) EndBlock(height uint64) (resEndBlock types.ResponseEndBlock) {
return types.ResponseEndBlock{Diffs: app.changes}
}
Query Connection
~~~~~~~~~~~~~~~~
@ -281,6 +332,34 @@ cause Tendermint to not connect to the corresponding peer:
Note: these query formats are subject to change!
::
func (app *DummyApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
if reqQuery.Prove {
value, proof, exists := app.state.Proof(reqQuery.Data)
resQuery.Index = -1 // TODO make Proof return index
resQuery.Key = reqQuery.Data
resQuery.Value = value
resQuery.Proof = proof
if exists {
resQuery.Log = "exists"
} else {
resQuery.Log = "does not exist"
}
return
} else {
index, value, exists := app.state.Get(reqQuery.Data)
resQuery.Index = int64(index)
resQuery.Value = value
if exists {
resQuery.Log = "exists"
} else {
resQuery.Log = "does not exist"
}
return
}
}
Handshake
~~~~~~~~~
@ -297,3 +376,28 @@ the app are synced to the latest block height.
If the app returns a LastBlockHeight of 0, Tendermint will just replay
all blocks.
::
func (app *DummyApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
return types.ResponseInfo{Data: cmn.Fmt("{\"size\":%v}", app.state.Size())}
}
Genesis
~~~~~~~
``InitChain`` will be called once upon the genesis. ``params`` includes the
initial validator set. Later on, it may be extended to take parts of the
consensus params.
::
// Save the validators in the merkle tree
func (app *PersistentDummyApplication) InitChain(params types.RequestInitChain) {
for _, v := range params.Validators {
r := app.updateValidator(v)
if r.IsErr() {
app.logger.Error("Error updating validators", "r", r)
}
}
}

View File

@ -107,7 +107,24 @@ like:
::
{"jsonrpc":"2.0","id":"","result":[98,{"check_tx":{},"deliver_tx":{}}],"error":""}
{
"jsonrpc": "2.0",
"id": "",
"result": {
"check_tx": {
"code": 0,
"data": "",
"log": ""
},
"deliver_tx": {
"code": 0,
"data": "",
"log": ""
},
"hash": "2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF",
"height": 154
}
}
The ``98`` is a type-byte, and can be ignored (it's useful for
serializing and deserializing arbitrary json). Otherwise, this result is
@ -118,14 +135,27 @@ querying the app:
::
curl -s 'localhost:46657/abci_query?data="abcd"&path=""&prove=false'
curl -s 'localhost:46657/abci_query?data="abcd"'
The ``path`` and ``prove`` arguments can be ignored for now, and in a
future release can be left out. The result should look like:
The result should look like:
::
{"jsonrpc":"2.0","id":"","result":[112,{"response":{"value":"61626364","log":"exists"}}],"error":""}
{
"jsonrpc": "2.0",
"id": "",
"result": {
"response": {
"code": 0,
"index": 0,
"key": "",
"value": "61626364",
"proof": "",
"height": 0,
"log": "exists"
}
}
}
Again, the ``112`` is the type-byte. Note the ``value`` in the result
(``61626364``); this is the hex-encoding of the ASCII of ``abcd``. You
@ -144,7 +174,7 @@ Now if we query for ``name``, we should get ``satoshi``, or
::
curl -s 'localhost:46657/abci_query?data="name"&path=""&prove=false'
curl -s 'localhost:46657/abci_query?data="name"'
Try some other transactions and queries to make sure everything is
working!
@ -204,14 +234,48 @@ the number ``1``. If instead, we try to send a ``5``, we get an error:
::
> curl localhost:46657/broadcast_tx_commit?tx=0x05
{"jsonrpc":"2.0","id":"","result":[98,{"check_tx":{},"deliver_tx":{"code":3,"log":"Invalid nonce. Expected 1, got 5"}}],"error":""}
{
"jsonrpc": "2.0",
"id": "",
"result": {
"check_tx": {
"code": 0,
"data": "",
"log": ""
},
"deliver_tx": {
"code": 3,
"data": "",
"log": "Invalid nonce. Expected 1, got 5"
},
"hash": "33B93DFF98749B0D6996A70F64071347060DC19C",
"height": 38
}
}
But if we send a ``1``, it works again:
::
> curl localhost:46657/broadcast_tx_commit?tx=0x01
{"jsonrpc":"2.0","id":"","result":[98,{"check_tx":{},"deliver_tx":{}}],"error":""}
{
"jsonrpc": "2.0",
"id": "",
"result": {
"check_tx": {
"code": 0,
"data": "",
"log": ""
},
"deliver_tx": {
"code": 0,
"data": "",
"log": ""
},
"hash": "F17854A977F6FA7EEA1BD758E296710B86F72F3D",
"height": 87
}
}
For more details on the ``broadcast_tx`` API, see `the guide on using
Tendermint <./using-tendermint.html>`__.

View File

@ -15,8 +15,6 @@ Welcome to Tendermint!
Tendermint 101
--------------
.. maxdepth set to 2 for sexinesss
.. but use 4 to upgrade overall documentation
.. toctree::
:maxdepth: 2
@ -25,9 +23,19 @@ Tendermint 101
getting-started.rst
using-tendermint.rst
Tendermint Ecosystem
--------------------
.. toctree::
:maxdepth: 2
ecosystem.rst
Tendermint Tools
----------------
.. the tools/ files are pulled in from the tools repo
.. see the bottom of conf.py
.. toctree::
:maxdepth: 2
@ -38,15 +46,6 @@ Tendermint Tools
tools/terraform-digitalocean.rst
tools/benchmarking-and-monitoring.rst
Tendermint Ecosystem
--------------------
.. toctree::
:maxdepth: 2
ecosystem.rst
Tendermint 102
--------------

View File

@ -30,14 +30,16 @@ The main config parameters are defined
- ``consensus.max_block_size_txs``: Maximum number of block txs.
*Default*: ``10000``
- ``consensus.create_empty_blocks``: Create empty blocks w/o txs.
*Default*: ``true``
- ``consensus.create_empty_blocks_interval``: Block creation interval, even if empty.
- ``consensus.timeout_*``: Various consensus timeout parameters
**TODO**
- ``consensus.wal_file``: Consensus state WAL. *Default*:
``"$TMHOME/data/cswal"``
``"$TMHOME/data/cs.wal/wal"``
- ``consensus.wal_light``: Whether to use light-mode for Consensus
state WAL. *Default*: ``false``
- ``mempool.*``: Various mempool parameters **TODO**
- ``mempool.*``: Various mempool parameters
- ``p2p.addr_book_file``: Peer address book. *Default*:
``"$TMHOME/addrbook.json"``. **NOT USED**

View File

@ -126,6 +126,38 @@ Notable options include the socket address of the application
Some fields from the config file can be overwritten with flags.
No Empty Blocks
---------------
This much requested feature was implemented in version 0.10.3. While the default behaviour of ``tendermint`` is still to create blocks approximately once per second, it is possible to disable empty blocks or set a block creation interval. In the former case, blocks will be created when there are new transactions or when the AppHash changes.
To configure tendermint to not produce empty blocks unless there are txs or the app hash changes,
run tendermint with this additional flag:
::
tendermint node --consensus.create_empty_blocks=false
or set the configuration via the ``config.toml`` file:
::
[consensus]
create_empty_blocks = false
Remember: because the default is to *create empty blocks*, avoiding empty blocks requires the config option to be set to ``false``.
The block interval setting allows for a delay (in seconds) between the creation of each new empty block. It is set via the ``config.toml``:
::
[consensus]
create_empty_blocks_interval = 5
With this setting, empty blocks will be produced every 5s if no block has been produced otherwise,
regardless of the value of `create_empty_blocks`.
Broadcast API
-------------

70
glide.lock generated
View File

@ -1,16 +1,18 @@
hash: e3649cac7b1b9a23c024a9d1bbebd5a147861d55da2bca77c95129b6021850b4
updated: 2017-09-22T13:24:29.443800586-04:00
hash: 816d84782ab66637e02bd0a3c7f652a9a31f9b88e3ae11438c5bf641cf585f19
updated: 2017-10-02T23:32:49.162422718-04:00
imports:
- name: github.com/btcsuite/btcd
version: 4803a8291c92a1d2d41041b942a9a9e37deab065
version: b8df516b4b267acf2de46be593a9d948d1d2c420
subpackages:
- btcec
- name: github.com/btcsuite/fastsha256
version: 637e656429416087660c84436a2a035d69d54e2e
- name: github.com/ebuchman/fail-test
version: 95f809107225be108efcf10a3509e4ea6ceef3c4
- name: github.com/fsnotify/fsnotify
version: 4da3e2cfbabc9f751898f250b49f2439785783a1
- name: github.com/go-kit/kit
version: 0d313fb5fb3a94d87d61e6434785264e87a5d740
version: d67bb4c202e3b91377d1079b110a6c9ce23ab2f8
subpackages:
- log
- log/level
@ -24,25 +26,22 @@ imports:
- name: github.com/go-playground/universal-translator
version: 71201497bace774495daed26a3874fd339e0b538
- name: github.com/go-stack/stack
version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf
version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82
- name: github.com/gogo/protobuf
version: 2adc21fd136931e0388e278825291678e1d98309
version: f7f1376d9d231a646d4e62fe1075623ced6db327
subpackages:
- proto
- name: github.com/golang/protobuf
version: 130e6b02ab059e7b717a096f397c5b60111cae74
version: 18c9bb3261723cd5401db4d0c9fbc5c3b6c70fe8
subpackages:
- proto
- ptypes
- ptypes/any
- ptypes/duration
- ptypes/timestamp
- name: github.com/golang/snappy
version: 553a641470496b2327abcac10b36396bd98e45c9
- name: github.com/gorilla/websocket
version: 6f34763140ed8887aed6a044912009832b4733d7
version: a91eba7f97777409bc2c443f5534d41dd20c5720
- name: github.com/hashicorp/hcl
version: 68e816d1c783414e79bc65b3994d9ab6b0a722ab
version: 392dba7d905ed5d04a5794ba89f558b27e2ba1ca
subpackages:
- hcl/ast
- hcl/parser
@ -59,31 +58,33 @@ imports:
- name: github.com/kr/logfmt
version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
- name: github.com/magiconair/properties
version: 8d7837e64d3c1ee4e54a880c5a920ab4316fc90a
version: 51463bfca2576e06c62a8504b5c0f06d61312647
- name: github.com/mitchellh/mapstructure
version: d0303fe809921458f417bcf828397a65db30a7e4
version: cc8532a8e9a55ea36402aa21efdf403a60d34096
- name: github.com/pelletier/go-buffruneio
version: c37440a7cf42ac63b919c752ca73a85067e05992
- name: github.com/pelletier/go-toml
version: 1d6b12b7cb290426e27e6b4e38b89fcda3aeef03
version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a
- name: github.com/pkg/errors
version: 645ef00459ed84a119197bfb8d8205042c6df63d
- name: github.com/rcrowley/go-metrics
version: 1f30fe9094a513ce4c700b9a54458bbb0c96996c
- name: github.com/spf13/afero
version: ee1bd8ee15a1306d1f9201acc41ef39cd9f99a1b
version: 9be650865eab0c12963d8753212f4f9c66cdcf12
subpackages:
- mem
- name: github.com/spf13/cast
version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4
- name: github.com/spf13/cobra
version: b78744579491c1ceeaaa3b40205e56b0591b93a3
version: 4cdb38c072b86bf795d2c81de50784d9fdd6eb77
- name: github.com/spf13/jwalterweatherman
version: 12bd96e66386c1960ab0f74ced1362f66f552f7b
version: 8f07c835e5cc1450c082fe3a439cf87b0cbb2d99
- name: github.com/spf13/pflag
version: 7aff26db30c1be810f9de5038ec5ef96ac41fd7c
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
- name: github.com/spf13/viper
version: 25b30aa063fc18e48662b86996252eabdcf2f0c7
version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2
- name: github.com/syndtr/goleveldb
version: b89cc31ef7977104127d34c1bd31ebd1a9db2199
version: 8c81ea47d4c41a385645e133e15510fc6a2a74b4
subpackages:
- leveldb
- leveldb/cache
@ -122,7 +123,7 @@ imports:
subpackages:
- iavl
- name: github.com/tendermint/tmlibs
version: 9997e3a3b46db1d2f88aa9816ed0e7915dad6ac1
version: 096dcb90e60aa00b748b3fe49a4b95e48ebf1e13
subpackages:
- autofile
- cli
@ -136,7 +137,7 @@ imports:
- merkle
- test
- name: golang.org/x/crypto
version: 7d9177d70076375b9a59c8fde23d52d9c4a7ecd5
version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
subpackages:
- curve25519
- nacl/box
@ -147,7 +148,7 @@ imports:
- ripemd160
- salsa20/salsa
- name: golang.org/x/net
version: 0744d001aa8470aaa53df28d32e5ceeb8af9bd70
version: feeb485667d1fdabe727840fe00adc22431bc86e
subpackages:
- context
- http2
@ -157,46 +158,43 @@ imports:
- lex/httplex
- trace
- name: golang.org/x/sys
version: 429f518978ab01db8bb6f44b66785088e7fba58b
version: e62c3de784db939836898e5c19ffd41bece347da
subpackages:
- unix
- name: golang.org/x/text
version: 1cbadb444a806fd9430d14ad08967ed91da4fa0a
version: 470f45bf29f4147d6fbd7dfd0a02a848e49f5bf4
subpackages:
- secure/bidirule
- transform
- unicode/bidi
- unicode/norm
- name: google.golang.org/genproto
version: 1e559d0a00eef8a9a43151db4665280bd8dd5886
version: 411e09b969b1170a9f0c467558eb4c4c110d9c77
subpackages:
- googleapis/rpc/status
- name: google.golang.org/grpc
version: d4b75ebd4f9f8c4a2b1cdadbdbe0d7920431ccca
version: 844f573616520565fdc6fb4db242321b5456fd6d
subpackages:
- balancer
- codes
- connectivity
- credentials
- grpclb/grpc_lb_v1/messages
- grpclb/grpc_lb_v1
- grpclog
- internal
- keepalive
- metadata
- naming
- peer
- resolver
- stats
- status
- tap
- transport
- name: gopkg.in/go-playground/validator.v9
version: a021b2ec9a8a8bb970f3f15bc42617cb520e8a64
version: 6d8c18553ea1ac493d049edd6f102f52e618f085
- name: gopkg.in/yaml.v2
version: eb3733d160e74a9c7e442f435eb3bea458e1d19f
version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b
testImports:
- name: github.com/davecgh/go-spew
version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
subpackages:
- spew
- name: github.com/pmezard/go-difflib
@ -204,7 +202,7 @@ testImports:
subpackages:
- difflib
- name: github.com/stretchr/testify
version: 890a5c3458b43e6104ff5da8dfa139d013d77544
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
subpackages:
- assert
- require

View File

@ -30,7 +30,7 @@ import:
subpackages:
- iavl
- package: github.com/tendermint/tmlibs
version: ~0.3.1
version: ~0.3.2
subpackages:
- autofile
- cli

View File

@ -1,8 +1,9 @@
package node
import (
"github.com/tendermint/go-crypto"
"time"
"github.com/tendermint/go-crypto"
)
type NodeID struct {

View File

@ -196,7 +196,7 @@ func getUPNPExternalAddress(externalPort, internalPort int, logger log.Logger) *
return NewNetAddressIPPort(ext, uint16(externalPort))
}
// TODO: use syscalls: http://pastebin.com/9exZG4rh
// TODO: use syscalls: see issue #712
func getNaiveExternalAddress(port int, settleForLocal bool, logger log.Logger) *NetAddress {
addrs, err := net.InterfaceAddrs()
if err != nil {

View File

@ -7,6 +7,7 @@ import (
"time"
"github.com/pkg/errors"
crypto "github.com/tendermint/go-crypto"
wire "github.com/tendermint/go-wire"
cmn "github.com/tendermint/tmlibs/common"

View File

@ -1,5 +0,0 @@
# `tendermint/p2p/upnp`
## Resources
* http://www.upnp-hacks.org/upnp.html

View File

@ -1,11 +1,9 @@
/*
Taken from taipei-torrent
Just enough UPnP to be able to forward ports
*/
// Taken from taipei-torrent.
// Just enough UPnP to be able to forward ports
// For more information, see: http://www.upnp-hacks.org/upnp.html
package upnp
// BUG(jae): TODO: use syscalls to get actual ourIP. http://pastebin.com/9exZG4rh
// TODO: use syscalls to get actual ourIP, see issue #712
import (
"bytes"

View File

@ -6,6 +6,7 @@ import (
"fmt"
"github.com/pkg/errors"
data "github.com/tendermint/go-wire/data"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
rpcclient "github.com/tendermint/tendermint/rpc/lib/client"

View File

@ -8,13 +8,13 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/abci/example/dummy"
abci "github.com/tendermint/abci/types"
data "github.com/tendermint/go-wire/data"
"github.com/tendermint/tendermint/rpc/client/mock"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
"github.com/tendermint/tendermint/rpc/client/mock"
)
func TestABCIMock(t *testing.T) {

View File

@ -5,10 +5,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
data "github.com/tendermint/go-wire/data"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
data "github.com/tendermint/go-wire/data"
"github.com/tendermint/tendermint/rpc/client/mock"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
func TestStatus(t *testing.T) {

View File

@ -6,7 +6,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/merkleeyes/iavl"
"github.com/tendermint/merkleeyes/iavl" //TODO use tendermint/iavl ?
"github.com/tendermint/tendermint/rpc/client"
rpctest "github.com/tendermint/tendermint/rpc/test"
"github.com/tendermint/tendermint/types"

View File

@ -5,7 +5,7 @@ import (
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
// Get block headers for minHeight <= height <= maxHeight.
@ -65,12 +65,12 @@ func BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResultBlockchainInfo, err
if maxHeight == 0 {
maxHeight = blockStore.Height()
} else {
maxHeight = MinInt(blockStore.Height(), maxHeight)
maxHeight = cmn.MinInt(blockStore.Height(), maxHeight)
}
if minHeight == 0 {
minHeight = MaxInt(1, maxHeight-20)
minHeight = cmn.MaxInt(1, maxHeight-20)
} else {
minHeight = MaxInt(minHeight, maxHeight-20)
minHeight = cmn.MaxInt(minHeight, maxHeight-20)
}
logger.Debug("BlockchainInfoHandler", "maxHeight", maxHeight, "minHeight", minHeight)

View File

@ -2,14 +2,13 @@ package core
import (
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/tmlibs/log"
"github.com/tendermint/tendermint/consensus"
p2p "github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/state/txindex"
"github.com/tendermint/tendermint/types"
"github.com/tendermint/tmlibs/log"
)
//----------------------------------------------

View File

@ -6,7 +6,6 @@ import (
abci "github.com/tendermint/abci/types"
"github.com/tendermint/go-crypto"
"github.com/tendermint/go-wire/data"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/types"
)

View File

@ -4,6 +4,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/p2p"
)

View File

@ -1,11 +1,10 @@
package core_grpc
import (
core "github.com/tendermint/tendermint/rpc/core"
context "golang.org/x/net/context"
abci "github.com/tendermint/abci/types"
context "golang.org/x/net/context"
core "github.com/tendermint/tendermint/rpc/core"
)
type broadcastAPI struct {

View File

@ -8,7 +8,7 @@ import (
"google.golang.org/grpc"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
// Start the grpcServer in a go routine
@ -40,5 +40,5 @@ func StartGRPCClient(protoAddr string) BroadcastAPIClient {
}
func dialerFunc(addr string, timeout time.Duration) (net.Conn, error) {
return Connect(addr)
return cmn.Connect(addr)
}

View File

@ -1,12 +0,0 @@
FROM golang:latest
RUN mkdir -p /go/src/github.com/tendermint/tendermint/rpc/lib
WORKDIR /go/src/github.com/tendermint/tendermint/rpc/lib
COPY Makefile /go/src/github.com/tendermint/tendermint/rpc/lib/
# COPY glide.yaml /go/src/github.com/tendermint/tendermint/rpc/lib/
# COPY glide.lock /go/src/github.com/tendermint/tendermint/rpc/lib/
COPY . /go/src/github.com/tendermint/tendermint/rpc/lib
RUN make get_deps

View File

@ -1,18 +0,0 @@
PACKAGES=$(shell go list ./... | grep -v "test")
all: get_deps test
test:
@echo "--> Running go test --race"
@go test --race $(PACKAGES)
@echo "--> Running integration tests"
@bash ./test/integration_test.sh
get_deps:
@echo "--> Running go get"
@go get -v -d $(PACKAGES)
@go list -f '{{join .TestImports "\n"}}' ./... | \
grep -v /vendor/ | sort | uniq | \
xargs go get -v -d
.PHONY: all test get_deps

View File

@ -1,121 +0,0 @@
# tendermint/rpc/lib
[![CircleCI](https://circleci.com/gh/tendermint/tendermint/rpc/lib.svg?style=svg)](https://circleci.com/gh/tendermint/tendermint/rpc/lib)
HTTP RPC server supporting calls via uri params, jsonrpc, and jsonrpc over websockets
# Client Requests
Suppose we want to expose the rpc function `HelloWorld(name string, num int)`.
## GET (URI)
As a GET request, it would have URI encoded parameters, and look like:
```
curl 'http://localhost:8008/hello_world?name="my_world"&num=5'
```
Note the `'` around the url, which is just so bash doesn't ignore the quotes in `"my_world"`.
This should also work:
```
curl http://localhost:8008/hello_world?name=\"my_world\"&num=5
```
A GET request to `/` returns a list of available endpoints.
For those which take arguments, the arguments will be listed in order, with `_` where the actual value should be.
## POST (JSONRPC)
As a POST request, we use JSONRPC. For instance, the same request would have this as the body:
```
{
"jsonrpc": "2.0",
"id": "anything",
"method": "hello_world",
"params": {
"name": "my_world",
"num": 5
}
}
```
With the above saved in file `data.json`, we can make the request with
```
curl --data @data.json http://localhost:8008
```
## WebSocket (JSONRPC)
All requests are exposed over websocket in the same form as the POST JSONRPC.
Websocket connections are available at their own endpoint, typically `/websocket`,
though this is configurable when starting the server.
# Server Definition
Define some types and routes:
```
type ResultStatus struct {
Value string
}
// Define some routes
var Routes = map[string]*rpcserver.RPCFunc{
"status": rpcserver.NewRPCFunc(Status, "arg"),
}
// an rpc function
func Status(v string) (*ResultStatus, error) {
return &ResultStatus{v}, nil
}
```
Now start the server:
```
mux := http.NewServeMux()
rpcserver.RegisterRPCFuncs(mux, Routes)
wm := rpcserver.NewWebsocketManager(Routes, nil)
mux.HandleFunc("/websocket", wm.WebsocketHandler)
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
go func() {
_, err := rpcserver.StartHTTPServer("0.0.0.0:8008", mux, logger)
if err != nil {
panic(err)
}
}()
```
Note that unix sockets are supported as well (eg. `/path/to/socket` instead of `0.0.0.0:8008`)
Now see all available endpoints by sending a GET request to `0.0.0.0:8008`.
Each route is available as a GET request, as a JSONRPCv2 POST request, and via JSONRPCv2 over websockets.
# Examples
* [Tendermint](https://github.com/tendermint/tendermint/blob/master/rpc/core/routes.go)
* [tm-monitor](https://github.com/tendermint/tools/blob/master/tm-monitor/rpc.go)
## CHANGELOG
### 0.7.0
BREAKING CHANGES:
- removed `Client` empty interface
- `ClientJSONRPC#Call` `params` argument became a map
- rename `ClientURI` -> `URIClient`, `ClientJSONRPC` -> `JSONRPCClient`
IMPROVEMENTS:
- added `HTTPClient` interface, which can be used for both `ClientURI`
and `ClientJSONRPC`
- all params are now optional (Golang's default will be used if some param is missing)
- added `Call` method to `WSClient` (see method's doc for details)

View File

@ -1,21 +0,0 @@
machine:
environment:
GOPATH: /home/ubuntu/.go_workspace
REPO: $GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME
hosts:
circlehost: 127.0.0.1
localhost: 127.0.0.1
checkout:
post:
- rm -rf $REPO
- mkdir -p $HOME/.go_workspace/src/github.com/$CIRCLE_PROJECT_USERNAME
- mv $HOME/$CIRCLE_PROJECT_REPONAME $REPO
dependencies:
override:
- "cd $REPO && make get_deps"
test:
override:
- "cd $REPO && make test"

View File

@ -16,6 +16,7 @@ import (
"github.com/go-kit/kit/log/term"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/go-wire/data"
client "github.com/tendermint/tendermint/rpc/lib/client"
server "github.com/tendermint/tendermint/rpc/lib/server"

View File

@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/abci/example/dummy"
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/tendermint/proxy"

View File

@ -7,16 +7,14 @@ import (
"github.com/stretchr/testify/assert"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/types"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/types"
)
// setupTestCase does setup common to all test cases

View File

@ -5,6 +5,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
crypto "github.com/tendermint/go-crypto"
)

View File

@ -5,7 +5,7 @@ import (
"io/ioutil"
"testing"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
const (
@ -15,7 +15,7 @@ const (
func TestBasicPartSet(t *testing.T) {
// Construct random data of size partSize * 100
data := RandBytes(testPartSize * 100)
data := cmn.RandBytes(testPartSize * 100)
partSet := NewPartSetFromData(data, testPartSize)
if len(partSet.Hash()) == 0 {
@ -65,7 +65,7 @@ func TestBasicPartSet(t *testing.T) {
func TestWrongProof(t *testing.T) {
// Construct random data of size partSize * 100
data := RandBytes(testPartSize * 100)
data := cmn.RandBytes(testPartSize * 100)
partSet := NewPartSetFromData(data, testPartSize)
// Test adding a part with wrong data.

View File

@ -5,7 +5,6 @@ import (
"fmt"
"io"
//. "github.com/tendermint/tmlibs/common"
"github.com/tendermint/go-crypto"
"github.com/tendermint/go-wire"
)

View File

@ -4,7 +4,7 @@ import (
"bytes"
"io"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tmlibs/merkle"
)
@ -19,7 +19,7 @@ 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)
cmn.PanicCrisis(err)
}
return buf.Bytes()
}

View File

@ -5,6 +5,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
wire "github.com/tendermint/go-wire"
cmn "github.com/tendermint/tmlibs/common"
ctest "github.com/tendermint/tmlibs/test"

View File

@ -99,7 +99,12 @@ func (valSet *ValidatorSet) GetByAddress(address []byte) (index int, val *Valida
}
}
// GetByIndex returns the validator by index.
// It returns nil values if index >= len(ValidatorSet.Validators)
func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) {
if index >= len(valSet.Validators) {
return nil, nil
}
val = valSet.Validators[index]
return val.Address, val.Copy()
}

View File

@ -13,9 +13,9 @@ import (
var (
ErrVoteUnexpectedStep = errors.New("Unexpected step")
ErrVoteInvalidValidatorIndex = errors.New("Invalid round vote validator index")
ErrVoteInvalidValidatorAddress = errors.New("Invalid round vote validator address")
ErrVoteInvalidSignature = errors.New("Invalid round vote signature")
ErrVoteInvalidValidatorIndex = errors.New("Invalid validator index")
ErrVoteInvalidValidatorAddress = errors.New("Invalid validator address")
ErrVoteInvalidSignature = errors.New("Invalid signature")
ErrVoteInvalidBlockHash = errors.New("Invalid block hash")
)

View File

@ -6,7 +6,7 @@ import (
"strings"
"sync"
. "github.com/tendermint/tmlibs/common"
cmn "github.com/tendermint/tmlibs/common"
)
/*
@ -51,7 +51,7 @@ type VoteSet struct {
mtx sync.Mutex
valSet *ValidatorSet
votesBitArray *BitArray
votesBitArray *cmn.BitArray
votes []*Vote // Primary votes to share
sum int64 // Sum of voting power for seen votes, discounting conflicts
maj23 *BlockID // First 2/3 majority seen
@ -62,7 +62,7 @@ type VoteSet struct {
// Constructs a new VoteSet struct used to accumulate votes for given height/round.
func NewVoteSet(chainID string, height int, round int, type_ byte, valSet *ValidatorSet) *VoteSet {
if height == 0 {
PanicSanity("Cannot make VoteSet for height == 0, doesn't make sense.")
cmn.PanicSanity("Cannot make VoteSet for height == 0, doesn't make sense.")
}
return &VoteSet{
chainID: chainID,
@ -70,7 +70,7 @@ func NewVoteSet(chainID string, height int, round int, type_ byte, valSet *Valid
round: round,
type_: type_,
valSet: valSet,
votesBitArray: NewBitArray(valSet.Size()),
votesBitArray: cmn.NewBitArray(valSet.Size()),
votes: make([]*Vote, valSet.Size()),
sum: 0,
maj23: nil,
@ -125,7 +125,7 @@ func (voteSet *VoteSet) Size() int {
// NOTE: VoteSet must not be nil
func (voteSet *VoteSet) AddVote(vote *Vote) (added bool, err error) {
if voteSet == nil {
PanicSanity("AddVote() on nil VoteSet")
cmn.PanicSanity("AddVote() on nil VoteSet")
}
voteSet.mtx.Lock()
defer voteSet.mtx.Unlock()
@ -140,8 +140,10 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
blockKey := vote.BlockID.Key()
// Ensure that validator index was set
if valIndex < 0 || len(valAddr) == 0 {
panic("Validator index or address was not set in vote.")
if valIndex < 0 {
return false, ErrVoteInvalidValidatorIndex
} else if len(valAddr) == 0 {
return false, ErrVoteInvalidValidatorAddress
}
// Make sure the step matches.
@ -186,7 +188,7 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
}
} else {
if !added {
PanicSanity("Expected to add non-conflicting vote")
cmn.PanicSanity("Expected to add non-conflicting vote")
}
return added, nil
}
@ -212,7 +214,7 @@ func (voteSet *VoteSet) addVerifiedVote(vote *Vote, blockKey string, votingPower
// Already exists in voteSet.votes?
if existing := voteSet.votes[valIndex]; existing != nil {
if existing.BlockID.Equals(vote.BlockID) {
PanicSanity("addVerifiedVote does not expect duplicate votes")
cmn.PanicSanity("addVerifiedVote does not expect duplicate votes")
} else {
conflicting = existing
}
@ -283,7 +285,7 @@ func (voteSet *VoteSet) addVerifiedVote(vote *Vote, blockKey string, votingPower
// NOTE: VoteSet must not be nil
func (voteSet *VoteSet) SetPeerMaj23(peerID string, blockID BlockID) {
if voteSet == nil {
PanicSanity("SetPeerMaj23() on nil VoteSet")
cmn.PanicSanity("SetPeerMaj23() on nil VoteSet")
}
voteSet.mtx.Lock()
defer voteSet.mtx.Unlock()
@ -316,7 +318,7 @@ func (voteSet *VoteSet) SetPeerMaj23(peerID string, blockID BlockID) {
}
}
func (voteSet *VoteSet) BitArray() *BitArray {
func (voteSet *VoteSet) BitArray() *cmn.BitArray {
if voteSet == nil {
return nil
}
@ -325,7 +327,7 @@ func (voteSet *VoteSet) BitArray() *BitArray {
return voteSet.votesBitArray.Copy()
}
func (voteSet *VoteSet) BitArrayByBlockID(blockID BlockID) *BitArray {
func (voteSet *VoteSet) BitArrayByBlockID(blockID BlockID) *cmn.BitArray {
if voteSet == nil {
return nil
}
@ -356,7 +358,7 @@ func (voteSet *VoteSet) GetByAddress(address []byte) *Vote {
defer voteSet.mtx.Unlock()
valIndex, val := voteSet.valSet.GetByAddress(address)
if val == nil {
PanicSanity("GetByAddress(address) returned nil")
cmn.PanicSanity("GetByAddress(address) returned nil")
}
return voteSet.votes[valIndex]
}
@ -454,14 +456,14 @@ func (voteSet *VoteSet) StringShort() string {
func (voteSet *VoteSet) MakeCommit() *Commit {
if voteSet.type_ != VoteTypePrecommit {
PanicSanity("Cannot MakeCommit() unless VoteSet.Type is VoteTypePrecommit")
cmn.PanicSanity("Cannot MakeCommit() unless VoteSet.Type is VoteTypePrecommit")
}
voteSet.mtx.Lock()
defer voteSet.mtx.Unlock()
// Make sure we have a 2/3 majority
if voteSet.maj23 == nil {
PanicSanity("Cannot MakeCommit() unless a blockhash has +2/3")
cmn.PanicSanity("Cannot MakeCommit() unless a blockhash has +2/3")
}
// For every validator, get the precommit
@ -483,7 +485,7 @@ func (voteSet *VoteSet) MakeCommit() *Commit {
*/
type blockVotes struct {
peerMaj23 bool // peer claims to have maj23
bitArray *BitArray // valIndex -> hasVote?
bitArray *cmn.BitArray // valIndex -> hasVote?
votes []*Vote // valIndex -> *Vote
sum int64 // vote sum
}
@ -491,7 +493,7 @@ type blockVotes struct {
func newBlockVotes(peerMaj23 bool, numValidators int) *blockVotes {
return &blockVotes{
peerMaj23: peerMaj23,
bitArray: NewBitArray(numValidators),
bitArray: cmn.NewBitArray(numValidators),
votes: make([]*Vote, numValidators),
sum: 0,
}
@ -521,7 +523,7 @@ type VoteSetReader interface {
Round() int
Type() byte
Size() int
BitArray() *BitArray
BitArray() *cmn.BitArray
GetByIndex(int) *Vote
IsCommit() bool
}

View File

@ -2,12 +2,11 @@ package types
import (
"bytes"
"testing"
"github.com/tendermint/go-crypto"
. "github.com/tendermint/tmlibs/common"
. "github.com/tendermint/tmlibs/test"
"testing"
cmn "github.com/tendermint/tmlibs/common"
tst "github.com/tendermint/tmlibs/test"
)
// NOTE: privValidators are in order
@ -137,7 +136,7 @@ func Test2_3Majority(t *testing.T) {
// 7th validator voted for some blockhash
{
vote := withValidator(voteProto, privValidators[6].GetAddress(), 6)
signAddVote(privValidators[6], withBlockHash(vote, RandBytes(32)), voteSet)
signAddVote(privValidators[6], withBlockHash(vote, cmn.RandBytes(32)), voteSet)
blockID, ok = voteSet.TwoThirdsMajority()
if ok || !blockID.IsZero() {
t.Errorf("There should be no 2/3 majority")
@ -217,7 +216,7 @@ func Test2_3MajorityRedux(t *testing.T) {
// 70th validator voted for different BlockHash
{
vote := withValidator(voteProto, privValidators[69].GetAddress(), 69)
signAddVote(privValidators[69], withBlockHash(vote, RandBytes(32)), voteSet)
signAddVote(privValidators[69], withBlockHash(vote, cmn.RandBytes(32)), voteSet)
blockID, ok = voteSet.TwoThirdsMajority()
if ok || !blockID.IsZero() {
t.Errorf("There should be no 2/3 majority: last vote added had different BlockHash")
@ -260,7 +259,7 @@ func TestBadVotes(t *testing.T) {
// val0 votes again for some block.
{
vote := withValidator(voteProto, privValidators[0].GetAddress(), 0)
added, err := signAddVote(privValidators[0], withBlockHash(vote, RandBytes(32)), voteSet)
added, err := signAddVote(privValidators[0], withBlockHash(vote, cmn.RandBytes(32)), voteSet)
if added || err == nil {
t.Errorf("Expected VoteSet.Add to fail, conflicting vote.")
}
@ -297,8 +296,8 @@ func TestBadVotes(t *testing.T) {
func TestConflicts(t *testing.T) {
height, round := 1, 0
voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 4, 1)
blockHash1 := RandBytes(32)
blockHash2 := RandBytes(32)
blockHash1 := cmn.RandBytes(32)
blockHash2 := cmn.RandBytes(32)
voteProto := &Vote{
ValidatorAddress: nil,
@ -444,13 +443,13 @@ func TestMakeCommit(t *testing.T) {
}
// MakeCommit should fail.
AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeCommit() })
tst.AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeCommit() })
// 7th voted for some other block.
{
vote := withValidator(voteProto, privValidators[6].GetAddress(), 6)
vote = withBlockHash(vote, RandBytes(32))
vote = withBlockPartsHeader(vote, PartSetHeader{123, RandBytes(32)})
vote = withBlockHash(vote, cmn.RandBytes(32))
vote = withBlockPartsHeader(vote, PartSetHeader{123, cmn.RandBytes(32)})
signAddVote(privValidators[6], vote, voteSet)
}