From cf686d4f835f474019a548258fbfd07f3e052142 Mon Sep 17 00:00:00 2001 From: spring1843 Date: Sat, 20 May 2017 21:43:00 -0700 Subject: [PATCH 01/39] Fix commonly misspelled words --- consensus/state_test.go | 6 +++--- consensus/ticker.go | 2 +- mempool/mempool.go | 2 +- rpc/client/mock/abci.go | 4 ++-- rpc/core/mempool.go | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/consensus/state_test.go b/consensus/state_test.go index 2606685a4..8b3693ec6 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -544,7 +544,7 @@ func TestLockPOLRelock(t *testing.T) { // timeout to new round <-timeoutWaitCh - //XXX: this isnt gauranteed to get there before the timeoutPropose ... + //XXX: this isnt guaranteed to get there before the timeoutPropose ... cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer") <-newRoundCh @@ -655,7 +655,7 @@ func TestLockPOLUnlock(t *testing.T) { rs = re.(types.TMEventData).Unwrap().(types.EventDataRoundState).RoundState.(*RoundState) lockedBlockHash := rs.LockedBlock.Hash() - //XXX: this isnt gauranteed to get there before the timeoutPropose ... + //XXX: this isnt guaranteed to get there before the timeoutPropose ... cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer") <-newRoundCh @@ -742,7 +742,7 @@ func TestLockPOLSafety1(t *testing.T) { incrementRound(vs2, vs3, vs4) - //XXX: this isnt gauranteed to get there before the timeoutPropose ... + //XXX: this isnt guaranteed to get there before the timeoutPropose ... cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer") <-newRoundCh diff --git a/consensus/ticker.go b/consensus/ticker.go index e869cdef1..e47a3412a 100644 --- a/consensus/ticker.go +++ b/consensus/ticker.go @@ -117,7 +117,7 @@ func (t *timeoutTicker) timeoutRoutine() { t.Logger.Debug("Scheduled timeout", "dur", ti.Duration, "height", ti.Height, "round", ti.Round, "step", ti.Step) case <-t.timer.C: t.Logger.Info("Timed out", "dur", ti.Duration, "height", ti.Height, "round", ti.Round, "step", ti.Step) - // go routine here gaurantees timeoutRoutine doesn't block. + // go routine here guarantees timeoutRoutine doesn't block. // Determinism comes from playback in the receiveRoutine. // We can eliminate it by merging the timeoutRoutine into receiveRoutine // and managing the timeouts ourselves with a millisecond ticker diff --git a/mempool/mempool.go b/mempool/mempool.go index 9e53108e5..fd922ed8e 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -409,7 +409,7 @@ func (cache *txCache) Push(tx types.Tx) bool { popped := cache.list.Front() poppedTx := popped.Value.(types.Tx) // NOTE: the tx may have already been removed from the map - // but deleting a non-existant element is fine + // but deleting a non-existent element is fine delete(cache.map_, string(poppedTx)) cache.list.Remove(popped) } diff --git a/rpc/client/mock/abci.go b/rpc/client/mock/abci.go index 0d1012557..71fa90b2a 100644 --- a/rpc/client/mock/abci.go +++ b/rpc/client/mock/abci.go @@ -40,7 +40,7 @@ func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit func (a ABCIApp) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { c := a.App.CheckTx(tx) - // and this gets writen in a background thread... + // and this gets written in a background thread... if c.IsOK() { go func() { a.App.DeliverTx(tx) }() } @@ -49,7 +49,7 @@ func (a ABCIApp) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error func (a ABCIApp) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { c := a.App.CheckTx(tx) - // and this gets writen in a background thread... + // and this gets written in a background thread... if c.IsOK() { go func() { a.App.DeliverTx(tx) }() } diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 1988b05c6..5b794db79 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -75,7 +75,7 @@ func BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { // Wait for the tx to be included in a block, // timeout after something reasonable. - // TODO: configureable? + // TODO: configurable? timer := time.NewTimer(60 * 2 * time.Second) select { case deliverTxRes := <-deliverTxResCh: From 9bc179032057289ba3af254af65b6524e1ef1c8a Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Wed, 24 May 2017 14:28:25 +0200 Subject: [PATCH 02/39] tracing logger (Refs #506) DEPENDS ON https://github.com/tendermint/tmlibs/pull/21 --- cmd/tendermint/commands/root.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go index 3565f3bb8..d0c5f90eb 100644 --- a/cmd/tendermint/commands/root.go +++ b/cmd/tendermint/commands/root.go @@ -8,6 +8,7 @@ import ( tmflags "github.com/tendermint/tendermint/cmd/tendermint/commands/flags" cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tmlibs/cli" "github.com/tendermint/tmlibs/log" ) @@ -34,6 +35,9 @@ var RootCmd = &cobra.Command{ if err != nil { return err } + if viper.GetBool(cli.TraceFlag) { + logger = log.NewTracingLogger(logger) + } return nil }, } From cf31f8d06fc6aa10c8ff29917db0a8081ee9fc59 Mon Sep 17 00:00:00 2001 From: zramsay Date: Mon, 29 May 2017 23:11:40 -0400 Subject: [PATCH 03/39] core: apply megacheck vet tool (unused, gosimple, staticcheck) --- blockchain/pool.go | 15 ++++---- blockchain/reactor.go | 10 ++--- consensus/byzantine_test.go | 1 + consensus/common_test.go | 21 ----------- consensus/height_vote_set_test.go | 3 ++ consensus/reactor.go | 2 +- consensus/replay.go | 5 ++- consensus/replay_test.go | 61 ------------------------------- consensus/state.go | 25 ++++++------- consensus/state_test.go | 18 +++++++-- p2p/addrbook.go | 3 -- p2p/connection.go | 8 ++-- p2p/listener.go | 2 +- p2p/netaddress.go | 1 - p2p/pex_reactor.go | 1 - p2p/secret_connection.go | 14 ------- p2p/upnp/probe.go | 9 ++--- p2p/upnp/upnp.go | 10 ++--- rpc/test/client_test.go | 2 - state/execution.go | 12 ------ state/state.go | 4 -- state/txindex/kv/kv_test.go | 4 +- types/block.go | 5 +-- types/validator_set.go | 8 ++-- 24 files changed, 67 insertions(+), 177 deletions(-) diff --git a/blockchain/pool.go b/blockchain/pool.go index a657b091e..49e255883 100644 --- a/blockchain/pool.go +++ b/blockchain/pool.go @@ -142,7 +142,7 @@ func (pool *BlockPool) IsCaughtUp() bool { maxPeerHeight = MaxInt(maxPeerHeight, peer.height) } - isCaughtUp := (height > 0 || time.Now().Sub(pool.startTime) > 5*time.Second) && (maxPeerHeight == 0 || height >= maxPeerHeight) + isCaughtUp := (height > 0 || time.Since(pool.startTime) > 5*time.Second) && (maxPeerHeight == 0 || height >= maxPeerHeight) pool.Logger.Info(Fmt("IsCaughtUp: %v", isCaughtUp), "height", height, "maxPeerHeight", maxPeerHeight) return isCaughtUp } @@ -212,9 +212,9 @@ func (pool *BlockPool) AddBlock(peerID string, block *types.Block, blockSize int pool.numPending-- peer := pool.peers[peerID] peer.decrPending(blockSize) - } else { - // Bad peer? - } + } // else { + // Bad peer? + // } } // Sets the peer's alleged blockchain height. @@ -261,7 +261,6 @@ func (pool *BlockPool) pickIncrAvailablePeer(minHeight int) *bpPeer { if peer.didTimeout { pool.removePeer(peer.id) continue - } else { } if peer.numPending >= maxPendingRequestsPerPeer { continue @@ -303,7 +302,8 @@ func (pool *BlockPool) sendTimeout(peerID string) { pool.timeoutsCh <- peerID } -func (pool *BlockPool) debug() string { +// unused by tendermint; left for debugging purposes +/*func (pool *BlockPool) debug() string { pool.mtx.Lock() // Lock defer pool.mtx.Unlock() @@ -317,7 +317,7 @@ func (pool *BlockPool) debug() string { } } return str -} +}*/ //------------------------------------- @@ -326,7 +326,6 @@ type bpPeer struct { id string recvMonitor *flow.Monitor - mtx sync.Mutex height int numPending int32 timeout *time.Timer diff --git a/blockchain/reactor.go b/blockchain/reactor.go index 1c0ef3a7d..670396b02 100644 --- a/blockchain/reactor.go +++ b/blockchain/reactor.go @@ -19,7 +19,6 @@ 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. @@ -49,7 +48,6 @@ type BlockchainReactor struct { fastSync bool requestsCh chan BlockRequest timeoutsCh chan string - lastBlock *types.Block evsw types.EventSwitch } @@ -134,6 +132,8 @@ func (bcR *BlockchainReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) bcR.Logger.Debug("Receive", "src", src, "chID", chID, "msg", msg) + // [zr] note: the `megacheck` tool (go vet on steroids) + // really dislikes the logic in this switch switch msg := msg.(type) { case *bcBlockRequestMessage: // Got a request for a block. Respond with block if we have it. @@ -194,10 +194,10 @@ FOR_LOOP: if peer != nil { bcR.Switch.StopPeerForError(peer, errors.New("BlockchainReactor Timeout")) } - case _ = <-statusUpdateTicker.C: + case <-statusUpdateTicker.C: // ask for status updates go bcR.BroadcastStatusRequest() - case _ = <-switchToConsensusTicker.C: + case <-switchToConsensusTicker.C: height, numPending, _ := bcR.pool.GetStatus() outbound, inbound, _ := bcR.Switch.NumPeers() bcR.Logger.Info("Consensus ticker", "numPending", numPending, "total", len(bcR.pool.requesters), @@ -211,7 +211,7 @@ FOR_LOOP: break FOR_LOOP } - case _ = <-trySyncTicker.C: // chan time + 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++ { diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go index 56aeeeeaa..e779d6179 100644 --- a/consensus/byzantine_test.go +++ b/consensus/byzantine_test.go @@ -77,6 +77,7 @@ func TestByzantine(t *testing.T) { var conRI p2p.Reactor conRI = conR + if i == 0 { conRI = NewByzantineReactor(conR) } diff --git a/consensus/common_test.go b/consensus/common_test.go index ae6e399d5..103294ab2 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -222,17 +222,6 @@ func subscribeToVoter(cs *ConsensusState, addr []byte) chan interface{} { return voteCh } -func readVotes(ch chan interface{}, reads int) chan struct{} { - wg := make(chan struct{}) - go func() { - for i := 0; i < reads; i++ { - <-ch // read the precommit event - } - close(wg) - }() - return wg -} - //------------------------------------------------------------------------------- // consensus states @@ -274,16 +263,6 @@ func loadPrivValidator(config *cfg.Config) *types.PrivValidator { return privValidator } -func fixedConsensusState() *ConsensusState { - stateDB := dbm.NewMemDB() - state := sm.MakeGenesisStateFromFile(stateDB, config.GenesisFile()) - state.SetLogger(log.TestingLogger().With("module", "state")) - privValidator := loadPrivValidator(config) - cs := newConsensusState(state, privValidator, counter.NewCounterApplication(true)) - cs.SetLogger(log.TestingLogger()) - return cs -} - func fixedConsensusStateDummy() *ConsensusState { stateDB := dbm.NewMemDB() state := sm.MakeGenesisStateFromFile(stateDB, config.GenesisFile()) diff --git a/consensus/height_vote_set_test.go b/consensus/height_vote_set_test.go index f1ef8b7ff..29751b40a 100644 --- a/consensus/height_vote_set_test.go +++ b/consensus/height_vote_set_test.go @@ -30,6 +30,9 @@ func TestPeerCatchupRounds(t *testing.T) { vote1001_0 := makeVoteHR(t, 1, 1001, privVals, 0) added, err = hvs.AddVote(vote1001_0, "peer1") + if err != nil { + t.Error("AddVote error", err) + } if added { t.Error("Expected to *not* add vote from peer, too many catchup rounds.") } diff --git a/consensus/reactor.go b/consensus/reactor.go index 3652697b5..437652583 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -351,7 +351,7 @@ func makeRoundStepMessages(rs *RoundState) (nrsMsg *NewRoundStepMessage, csMsg * Height: rs.Height, Round: rs.Round, Step: rs.Step, - SecondsSinceStartTime: int(time.Now().Sub(rs.StartTime).Seconds()), + SecondsSinceStartTime: int(time.Since(rs.StartTime).Seconds()), LastCommitRound: rs.LastCommit.Round(), } if rs.Step == RoundStepCommit { diff --git a/consensus/replay.go b/consensus/replay.go index af30b8894..f14fa42f0 100644 --- a/consensus/replay.go +++ b/consensus/replay.go @@ -104,6 +104,9 @@ func (cs *ConsensusState) catchupReplay(csHeight int) error { // NOTE: This is just a sanity check. As far as we know things work fine without it, // and Handshake could reuse ConsensusState if it weren't for this check (since we can crash after writing ENDHEIGHT). gr, found, err := cs.wal.group.Search("#ENDHEIGHT: ", makeHeightSearchFunc(csHeight)) + if err != nil { + return err + } if gr != nil { gr.Close() } @@ -132,7 +135,7 @@ func (cs *ConsensusState) catchupReplay(csHeight int) error { if !found { // if we upgraded from 0.9 to 0.9.1, we may have #HEIGHT instead // TODO (0.10.0): remove this - gr, found, err = cs.wal.group.Search("#HEIGHT: ", makeHeightSearchFunc(csHeight)) + gr, _, err = cs.wal.group.Search("#HEIGHT: ", makeHeightSearchFunc(csHeight)) if err == io.EOF { cs.Logger.Error("Replay: wal.group.Search returned EOF", "#HEIGHT", csHeight) return nil diff --git a/consensus/replay_test.go b/consensus/replay_test.go index 23290a7f5..78cdaf7bc 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -557,67 +557,6 @@ func readPieceFromWAL(msgBytes []byte) (interface{}, error) { return nil, nil } -// make some bogus txs -func txsFunc(blockNum int) (txs []types.Tx) { - for i := 0; i < 10; i++ { - txs = append(txs, types.Tx([]byte{byte(blockNum), byte(i)})) - } - return txs -} - -// sign a commit vote -func signCommit(chainID string, privVal *types.PrivValidator, height, round int, hash []byte, header types.PartSetHeader) *types.Vote { - vote := &types.Vote{ - ValidatorIndex: 0, - ValidatorAddress: privVal.Address, - Height: height, - Round: round, - Type: types.VoteTypePrecommit, - BlockID: types.BlockID{hash, header}, - } - - sig := privVal.Sign(types.SignBytes(chainID, vote)) - vote.Signature = sig - return vote -} - -// make a blockchain with one validator -func makeBlockchain(t *testing.T, chainID string, nBlocks int, privVal *types.PrivValidator, proxyApp proxy.AppConns, state *sm.State) (blockchain []*types.Block, commits []*types.Commit) { - - prevHash := state.LastBlockID.Hash - lastCommit := new(types.Commit) - prevParts := types.PartSetHeader{} - valHash := state.Validators.Hash() - prevBlockID := types.BlockID{prevHash, prevParts} - - for i := 1; i < nBlocks+1; i++ { - block, parts := types.MakeBlock(i, chainID, txsFunc(i), lastCommit, - prevBlockID, valHash, state.AppHash, testPartSize) - fmt.Println(i) - fmt.Println(block.LastBlockID) - err := state.ApplyBlock(nil, proxyApp.Consensus(), block, block.MakePartSet(testPartSize).Header(), mempool) - if err != nil { - t.Fatal(i, err) - } - - voteSet := types.NewVoteSet(chainID, i, 0, types.VoteTypePrecommit, state.Validators) - vote := signCommit(chainID, privVal, i, 0, block.Hash(), parts.Header()) - _, err = voteSet.AddVote(vote) - if err != nil { - t.Fatal(err) - } - - prevHash = block.Hash() - prevParts = parts.Header() - lastCommit = voteSet.MakeCommit() - prevBlockID = types.BlockID{prevHash, prevParts} - - blockchain = append(blockchain, block) - commits = append(commits, lastCommit) - } - return blockchain, commits -} - // fresh state and mock store func stateAndStore(config *cfg.Config, pubKey crypto.PubKey) (*sm.State, *mockBlockStore) { stateDB := dbm.NewMemDB() diff --git a/consensus/state.go b/consensus/state.go index d4056facf..9d9c75851 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -648,10 +648,10 @@ func (cs *ConsensusState) handleMsg(mi msgInfo, rs RoundState) { case *VoteMessage: // attempt to add the vote and dupeout the validator if its a duplicate signature // if the vote gives us a 2/3-any or 2/3-one, we transition - err := cs.tryAddVote(msg.Vote, peerKey) - if err == ErrAddingVote { - // TODO: punish peer - } + _ = cs.tryAddVote(msg.Vote, peerKey) + //if err == ErrAddingVote { + // TODO: punish peer + //} // NOTE: the vote is broadcast to peers by the reactor listening // for vote events @@ -897,10 +897,10 @@ func (cs *ConsensusState) enterPrevote(height int, round int) { // fire event for how we got here if cs.isProposalComplete() { types.FireEventCompleteProposal(cs.evsw, cs.RoundStateEvent()) - } else { - // we received +2/3 prevotes for a future round - // TODO: catchup event? - } + } // else { + // we received +2/3 prevotes for a future round + // TODO: catchup event? + //} cs.Logger.Info(cmn.Fmt("enterPrevote(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) @@ -939,7 +939,6 @@ func (cs *ConsensusState) defaultDoPrevote(height int, round int) { // 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. @@ -1059,7 +1058,6 @@ func (cs *ConsensusState) enterPrecommit(height int, round int) { } types.FireEventUnlock(cs.evsw, cs.RoundStateEvent()) cs.signAddVote(types.VoteTypePrecommit, nil, types.PartSetHeader{}) - return } // Enter: any +2/3 precommits for next round. @@ -1124,9 +1122,9 @@ func (cs *ConsensusState) enterCommit(height int, commitRound int) { // Set up ProposalBlockParts and keep waiting. cs.ProposalBlock = nil cs.ProposalBlockParts = types.NewPartSetFromHeader(blockID.PartsHeader) - } else { - // We just need to keep waiting. - } + } // else { + // We just need to keep waiting. + //} } } @@ -1250,7 +1248,6 @@ func (cs *ConsensusState) finalizeCommit(height int) { // * cs.Height has been increment to height+1 // * cs.Step is now RoundStepNewHeight // * cs.StartTime is set to when we will start round0. - return } //----------------------------------------------------------------------------- diff --git a/consensus/state_test.go b/consensus/state_test.go index 8b3693ec6..ee88ac258 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -523,7 +523,10 @@ func TestLockPOLRelock(t *testing.T) { <-voteCh // prevote signAddVotes(cs1, types.VoteTypePrevote, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vs2, vs3, vs4) - _, _, _ = <-voteCh, <-voteCh, <-voteCh // prevotes + // prevotes + <-voteCh + <-voteCh + <-voteCh <-voteCh // our precommit // the proposed block should now be locked and our precommit added @@ -532,7 +535,10 @@ func TestLockPOLRelock(t *testing.T) { // add precommits from the rest signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2, vs4) signAddVotes(cs1, types.VoteTypePrecommit, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vs3) - _, _, _ = <-voteCh, <-voteCh, <-voteCh // precommits + // precommites + <-voteCh + <-voteCh + <-voteCh // before we timeout to the new round set the new proposal prop, propBlock := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) @@ -570,7 +576,10 @@ func TestLockPOLRelock(t *testing.T) { // now lets add prevotes from everyone else for the new block signAddVotes(cs1, types.VoteTypePrevote, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) - _, _, _ = <-voteCh, <-voteCh, <-voteCh // prevotes + // prevotes + <-voteCh + <-voteCh + <-voteCh // now either we go to PrevoteWait or Precommit select { @@ -585,7 +594,8 @@ func TestLockPOLRelock(t *testing.T) { validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash) signAddVotes(cs1, types.VoteTypePrecommit, propBlockHash, propBlockParts.Header(), vs2, vs3) - _, _ = <-voteCh, <-voteCh + <-voteCh + <-voteCh be := <-newBlockCh b := be.(types.TMEventData).Unwrap().(types.EventDataNewBlockHeader) diff --git a/p2p/addrbook.go b/p2p/addrbook.go index 1df0817ee..c87e806bd 100644 --- a/p2p/addrbook.go +++ b/p2p/addrbook.go @@ -68,9 +68,6 @@ const ( // max addresses returned by GetSelection // NOTE: this must match "maxPexMessageSize" maxGetSelection = 250 - - // current version of the on-disk format. - serializationVersion = 1 ) const ( diff --git a/p2p/connection.go b/p2p/connection.go index 36f15abb7..1e3da1778 100644 --- a/p2p/connection.go +++ b/p2p/connection.go @@ -366,9 +366,9 @@ func (c *MConnection) sendMsgPacket() bool { // Nothing to send? if leastChannel == nil { return true - } else { - // c.Logger.Info("Found a msgPacket to send") - } + } // else { + // c.Logger.Info("Found a msgPacket to send") + //} // Make & send a msgPacket from this channel n, err := leastChannel.writeMsgPacketTo(c.bufWriter) @@ -468,7 +468,7 @@ FOR_LOOP: // Cleanup close(c.pong) - for _ = range c.pong { + for range c.pong { // Drain } } diff --git a/p2p/listener.go b/p2p/listener.go index d31f0de83..90e40fec7 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -135,7 +135,7 @@ func (l *DefaultListener) listenRoutine() { // Cleanup close(l.connections) - for _ = range l.connections { + for range l.connections { // Drain } } diff --git a/p2p/netaddress.go b/p2p/netaddress.go index 09787481c..d424f8c32 100644 --- a/p2p/netaddress.go +++ b/p2p/netaddress.go @@ -174,7 +174,6 @@ func (na *NetAddress) ReachabilityTo(o *NetAddress) int { Ipv6_weak Ipv4 Ipv6_strong - Private ) if !na.Routable() { return Unreachable diff --git a/p2p/pex_reactor.go b/p2p/pex_reactor.go index 269a8d006..a017c931e 100644 --- a/p2p/pex_reactor.go +++ b/p2p/pex_reactor.go @@ -44,7 +44,6 @@ const ( type PEXReactor struct { BaseReactor - sw *Switch book *AddrBook ensurePeersPeriod time.Duration diff --git a/p2p/secret_connection.go b/p2p/secret_connection.go index 24cae0f61..06c28317d 100644 --- a/p2p/secret_connection.go +++ b/p2p/secret_connection.go @@ -293,10 +293,6 @@ func shareAuthSignature(sc *SecretConnection, pubKey crypto.PubKeyEd25519, signa return &recvMsg, nil } -func verifyChallengeSignature(challenge *[32]byte, remPubKey crypto.PubKeyEd25519, remSignature crypto.SignatureEd25519) bool { - return remPubKey.VerifyBytes(challenge[:], remSignature.Wrap()) -} - //-------------------------------------------------------------------------------- // sha256 @@ -319,16 +315,6 @@ func hash24(input []byte) (res *[24]byte) { return } -// ripemd160 -func hash20(input []byte) (res *[20]byte) { - hasher := ripemd160.New() - hasher.Write(input) // does not error - resSlice := hasher.Sum(nil) - res = new([20]byte) - copy(res[:], resSlice) - return -} - // increment nonce big-endian by 2 with wraparound. func incr2Nonce(nonce *[24]byte) { incrNonce(nonce) diff --git a/p2p/upnp/probe.go b/p2p/upnp/probe.go index 3537e1c65..0c263ee1c 100644 --- a/p2p/upnp/probe.go +++ b/p2p/upnp/probe.go @@ -1,7 +1,6 @@ package upnp import ( - "errors" "fmt" "net" "time" @@ -18,26 +17,26 @@ type UPNPCapabilities struct { func makeUPNPListener(intPort int, extPort int, logger log.Logger) (NAT, net.Listener, net.IP, error) { nat, err := Discover() if err != nil { - return nil, nil, nil, errors.New(fmt.Sprintf("NAT upnp could not be discovered: %v", err)) + return nil, nil, nil, fmt.Errorf("NAT upnp could not be discovered: %v", err) } logger.Info(cmn.Fmt("ourIP: %v", nat.(*upnpNAT).ourIP)) ext, err := nat.GetExternalAddress() if err != nil { - return nat, nil, nil, errors.New(fmt.Sprintf("External address error: %v", err)) + return nat, nil, nil, fmt.Errorf("External address error: %v", err) } logger.Info(cmn.Fmt("External address: %v", ext)) port, err := nat.AddPortMapping("tcp", extPort, intPort, "Tendermint UPnP Probe", 0) if err != nil { - return nat, nil, ext, errors.New(fmt.Sprintf("Port mapping error: %v", err)) + return nat, nil, ext, fmt.Errorf("Port mapping error: %v", err) } logger.Info(cmn.Fmt("Port mapping mapped: %v", port)) // also run the listener, open for all remote addresses. listener, err := net.Listen("tcp", fmt.Sprintf(":%v", intPort)) if err != nil { - return nat, nil, ext, errors.New(fmt.Sprintf("Error establishing listener: %v", err)) + return nat, nil, ext, fmt.Errorf("Error establishing listener: %v", err) } return nat, listener, ext, nil } diff --git a/p2p/upnp/upnp.go b/p2p/upnp/upnp.go index 3d6c55035..29abbe794 100644 --- a/p2p/upnp/upnp.go +++ b/p2p/upnp/upnp.go @@ -65,14 +65,14 @@ func Discover() (nat NAT, err error) { return } var n int - n, _, err = socket.ReadFromUDP(answerBytes) + _, _, err = socket.ReadFromUDP(answerBytes) for { n, _, err = socket.ReadFromUDP(answerBytes) if err != nil { break } answer := string(answerBytes[0:n]) - if strings.Index(answer, st) < 0 { + if !strings.Contains(answer, st) { continue } // HTTP header field names are case-insensitive. @@ -153,7 +153,7 @@ type Root struct { func getChildDevice(d *Device, deviceType string) *Device { dl := d.DeviceList.Device for i := 0; i < len(dl); i++ { - if strings.Index(dl[i].DeviceType, deviceType) >= 0 { + if strings.Contains(dl[i].DeviceType, deviceType) { return &dl[i] } } @@ -163,7 +163,7 @@ func getChildDevice(d *Device, deviceType string) *Device { func getChildService(d *Device, serviceType string) *UPNPService { sl := d.ServiceList.Service for i := 0; i < len(sl); i++ { - if strings.Index(sl[i].ServiceType, serviceType) >= 0 { + if strings.Contains(sl[i].ServiceType, serviceType) { return &sl[i] } } @@ -211,7 +211,7 @@ func getServiceURL(rootURL string) (url, urnDomain string, err error) { return } a := &root.Device - if strings.Index(a.DeviceType, "InternetGatewayDevice:1") < 0 { + if !strings.Contains(a.DeviceType, "InternetGatewayDevice:1") { err = errors.New("No InternetGatewayDevice") return } diff --git a/rpc/test/client_test.go b/rpc/test/client_test.go index b7df67841..c5e01de9a 100644 --- a/rpc/test/client_test.go +++ b/rpc/test/client_test.go @@ -238,8 +238,6 @@ func testTx(t *testing.T, client rpc.HTTPClient, withIndexer bool) { //-------------------------------------------------------------------------------- // Test the websocket service -var wsTyp = "JSONRPC" - // make a simple connection to the server func TestWSConnect(t *testing.T) { wsc := GetWSClient() diff --git a/state/execution.go b/state/execution.go index 768a0b1de..547fd3675 100644 --- a/state/execution.go +++ b/state/execution.go @@ -155,18 +155,6 @@ func updateValidators(validators *types.ValidatorSet, changedValidators []*abci. return nil } -// return a bit array of validators that signed the last commit -// NOTE: assumes commits have already been authenticated -func commitBitArrayFromBlock(block *types.Block) *cmn.BitArray { - signed := cmn.NewBitArray(len(block.LastCommit.Precommits)) - for i, precommit := range block.LastCommit.Precommits { - if precommit != nil { - signed.SetIndex(i, true) // val_.LastCommitHeight = block.Height - 1 - } - } - return signed -} - //----------------------------------------------------- // Validate block diff --git a/state/state.go b/state/state.go index 808fcbe24..932e1c0eb 100644 --- a/state/state.go +++ b/state/state.go @@ -46,10 +46,6 @@ type State struct { TxIndexer txindex.TxIndexer `json:"-"` // Transaction indexer. - // Intermediate results from processing - // Persisted separately from the state - abciResponses *ABCIResponses - logger log.Logger } diff --git a/state/txindex/kv/kv_test.go b/state/txindex/kv/kv_test.go index 8de9b8cda..734a17b3e 100644 --- a/state/txindex/kv/kv_test.go +++ b/state/txindex/kv/kv_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" - db "github.com/tendermint/tmlibs/db" "github.com/tendermint/tendermint/state/txindex" "github.com/tendermint/tendermint/types" + db "github.com/tendermint/tmlibs/db" ) func TestTxIndex(t *testing.T) { @@ -52,7 +52,7 @@ func benchmarkTxIndex(txsCount int, b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - err = indexer.AddBatch(batch) + _ = indexer.AddBatch(batch) } } diff --git a/types/block.go b/types/block.go index b306d57d0..26fc152ce 100644 --- a/types/block.go +++ b/types/block.go @@ -282,10 +282,7 @@ func (commit *Commit) GetByIndex(index int) *Vote { } func (commit *Commit) IsCommit() bool { - if len(commit.Precommits) == 0 { - return false - } - return true + return len(commit.Precommits) == 0 } func (commit *Commit) ValidateBasic() error { diff --git a/types/validator_set.go b/types/validator_set.go index b374df576..e334ed9f3 100644 --- a/types/validator_set.go +++ b/types/validator_set.go @@ -85,14 +85,14 @@ 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 + return idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) } 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 { + if idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) { return idx, valSet.Validators[idx].Copy() } else { return 0, nil @@ -159,7 +159,7 @@ func (valSet *ValidatorSet) Add(val *Validator) (added bool) { valSet.Proposer = nil valSet.totalVotingPower = 0 return true - } else if bytes.Compare(valSet.Validators[idx].Address, val.Address) == 0 { + } else if bytes.Equal(valSet.Validators[idx].Address, val.Address) { return false } else { newValidators := make([]*Validator, len(valSet.Validators)+1) @@ -191,7 +191,7 @@ 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 { + if idx == len(valSet.Validators) || !bytes.Equal(valSet.Validators[idx].Address, address) { return nil, false } else { removedVal := valSet.Validators[idx] From 989cb6dd2e576212bf3052a28849ee44c8411b04 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Tue, 30 May 2017 16:33:48 +0300 Subject: [PATCH 04/39] update Dockerfile [ci skip] --- DOCKER/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DOCKER/Dockerfile b/DOCKER/Dockerfile index a5f734f19..8143efacb 100644 --- a/DOCKER/Dockerfile +++ b/DOCKER/Dockerfile @@ -1,8 +1,8 @@ FROM alpine:3.5 # This is the release of tendermint to pull in. -ENV TM_VERSION 0.9.1 -ENV TM_SHA256SUM da34234755937140dcd953afcc965555fad7e05afd546711bc5bdc2df3d54226 +ENV TM_VERSION 0.10.0-rc1 +ENV TM_SHA256SUM bde0758123deecd3e961e7e254214e100444f520994316a2512fc6b6656045c4 # Tendermint will be looking for genesis file in /tendermint (unless you change # `genesis_file` in config.toml). You can put your config.toml and private @@ -26,7 +26,7 @@ RUN mkdir -p $DATA_ROOT && \ RUN apk add --no-cache bash curl jq RUN apk add --no-cache openssl && \ - wget https://s3-us-west-2.amazonaws.com/tendermint/${TM_VERSION}/tendermint_${TM_VERSION}_linux_amd64.zip && \ + wget https://s3-us-west-2.amazonaws.com/tendermint/binaries/tendermint/v${TM_VERSION}/tendermint_${TM_VERSION}_linux_amd64.zip && \ echo "${TM_SHA256SUM} tendermint_${TM_VERSION}_linux_amd64.zip" | sha256sum -c && \ unzip -d /bin tendermint_${TM_VERSION}_linux_amd64.zip && \ apk del openssl && \ From bf5181d9cad4687c35ddc1c5cdf89d88c4140a18 Mon Sep 17 00:00:00 2001 From: zramsay Date: Tue, 30 May 2017 11:00:40 -0400 Subject: [PATCH 05/39] address PR comments --- p2p/upnp/probe.go | 10 ++++++---- state/execution.go | 12 ++++++++++++ types/block.go | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/p2p/upnp/probe.go b/p2p/upnp/probe.go index 0c263ee1c..74d4d4c51 100644 --- a/p2p/upnp/probe.go +++ b/p2p/upnp/probe.go @@ -5,6 +5,8 @@ import ( "net" "time" + "github.com/pkg/errors" + cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/log" ) @@ -17,26 +19,26 @@ type UPNPCapabilities struct { func makeUPNPListener(intPort int, extPort int, logger log.Logger) (NAT, net.Listener, net.IP, error) { nat, err := Discover() if err != nil { - return nil, nil, nil, fmt.Errorf("NAT upnp could not be discovered: %v", err) + return nil, nil, nil, errors.Errorf("NAT upnp could not be discovered: %v", err) } logger.Info(cmn.Fmt("ourIP: %v", nat.(*upnpNAT).ourIP)) ext, err := nat.GetExternalAddress() if err != nil { - return nat, nil, nil, fmt.Errorf("External address error: %v", err) + return nat, nil, nil, errors.Errorf("External address error: %v", err) } logger.Info(cmn.Fmt("External address: %v", ext)) port, err := nat.AddPortMapping("tcp", extPort, intPort, "Tendermint UPnP Probe", 0) if err != nil { - return nat, nil, ext, fmt.Errorf("Port mapping error: %v", err) + return nat, nil, ext, errors.Errorf("Port mapping error: %v", err) } logger.Info(cmn.Fmt("Port mapping mapped: %v", port)) // also run the listener, open for all remote addresses. listener, err := net.Listen("tcp", fmt.Sprintf(":%v", intPort)) if err != nil { - return nat, nil, ext, fmt.Errorf("Error establishing listener: %v", err) + return nat, nil, ext, errors.Errorf("Error establishing listener: %v", err) } return nat, listener, ext, nil } diff --git a/state/execution.go b/state/execution.go index 547fd3675..2a64f1885 100644 --- a/state/execution.go +++ b/state/execution.go @@ -155,6 +155,18 @@ func updateValidators(validators *types.ValidatorSet, changedValidators []*abci. return nil } +// return a bit array of validators that signed the last commit +// NOTE: assumes commits have already been authenticated +/*func commitBitArrayFromBlock(block *types.Block) *cmn.BitArray { + signed := cmn.NewBitArray(len(block.LastCommit.Precommits)) + for i, precommit := range block.LastCommit.Precommits { + if precommit != nil { + signed.SetIndex(i, true) // val_.LastCommitHeight = block.Height - 1 + } + } + return signed +}*/ + //----------------------------------------------------- // Validate block diff --git a/types/block.go b/types/block.go index 26fc152ce..6592ad5dd 100644 --- a/types/block.go +++ b/types/block.go @@ -282,7 +282,7 @@ func (commit *Commit) GetByIndex(index int) *Vote { } func (commit *Commit) IsCommit() bool { - return len(commit.Precommits) == 0 + return len(commit.Precommits) != 0 } func (commit *Commit) ValidateBasic() error { From 9c3eee0b00f068d5bab062d9a1716a40615c7a20 Mon Sep 17 00:00:00 2001 From: zramsay Date: Tue, 30 May 2017 13:27:31 -0400 Subject: [PATCH 06/39] Makefile: add megacheck & some additional fixes --- Makefile | 9 ++++++++- cmd/tendermint/commands/root.go | 5 +---- consensus/byzantine_test.go | 5 +---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 7848e4785..8c9c5214d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,8 @@ GOTOOLS = \ github.com/mitchellh/gox \ - github.com/Masterminds/glide + github.com/Masterminds/glide \ + honnef.co/go/tools/cmd/megacheck + PACKAGES=$(shell go list ./... | grep -v '/vendor/') BUILD_TAGS?=tendermint TMHOME = $${TMHOME:-$$HOME/.tendermint} @@ -72,5 +74,10 @@ tools: ensure_tools: go get $(GOTOOLS) +### Formatting, linting, and vetting + +megacheck: + @for pkg in ${PACKAGES}; do megacheck "$$pkg"; done + .PHONY: install build build_race dist test test_race test_integrations test100 draw_deps list_deps get_deps get_vendor_deps update_deps revision tools diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go index 3565f3bb8..a10ff3fca 100644 --- a/cmd/tendermint/commands/root.go +++ b/cmd/tendermint/commands/root.go @@ -31,9 +31,6 @@ var RootCmd = &cobra.Command{ config.SetRoot(config.RootDir) cfg.EnsureRoot(config.RootDir) logger, err = tmflags.ParseLogLevel(config.LogLevel, logger) - if err != nil { - return err - } - return nil + return err }, } diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go index e779d6179..3a68a2f5d 100644 --- a/consensus/byzantine_test.go +++ b/consensus/byzantine_test.go @@ -117,10 +117,7 @@ func TestByzantine(t *testing.T) { p2p.Connect2Switches(switches, ind1, ind2) // wait for someone in the big partition to make a block - - select { - case <-eventChans[ind2]: - } + <-eventChans[ind2] t.Log("A block has been committed. Healing partition") From e5342f4054ab784b2cd6150e14f01053d7c8deb2 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 3 Jun 2017 21:37:56 -0400 Subject: [PATCH 07/39] docker: update for 0.10.0 [ci skip]" --- DOCKER/Dockerfile | 4 ++-- DOCKER/README.md | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/DOCKER/Dockerfile b/DOCKER/Dockerfile index 8143efacb..09b25f732 100644 --- a/DOCKER/Dockerfile +++ b/DOCKER/Dockerfile @@ -1,8 +1,8 @@ FROM alpine:3.5 # This is the release of tendermint to pull in. -ENV TM_VERSION 0.10.0-rc1 -ENV TM_SHA256SUM bde0758123deecd3e961e7e254214e100444f520994316a2512fc6b6656045c4 +ENV TM_VERSION 0.10.0 +ENV TM_SHA256SUM a29852b8d51c00db93c87c3d148fa419a047abd38f32b2507a905805131acc19 # Tendermint will be looking for genesis file in /tendermint (unless you change # `genesis_file` in config.toml). You can put your config.toml and private diff --git a/DOCKER/README.md b/DOCKER/README.md index a1f9f28c9..2bd2b27ea 100644 --- a/DOCKER/README.md +++ b/DOCKER/README.md @@ -1,6 +1,7 @@ # Supported tags and respective `Dockerfile` links -- `0.9.1`, `0.9`, `latest` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/809e0e8c5933604ba8b2d096803ada7c5ec4dfd3/DOCKER/Dockerfile) +- `0.10.0`, `latest` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/v0.10.0/DOCKER/Dockerfile) +- `0.9.1`, `0.9`, [(Dockerfile)](https://github.com/tendermint/tendermint/blob/809e0e8c5933604ba8b2d096803ada7c5ec4dfd3/DOCKER/Dockerfile) - `0.9.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/d474baeeea6c22b289e7402449572f7c89ee21da/DOCKER/Dockerfile) - `0.8.0`, `0.8` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/bf64dd21fdb193e54d8addaaaa2ecf7ac371de8c/DOCKER/Dockerfile) - `develop` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/master/DOCKER/Dockerfile.develop) From ed7183936d46439673a9280586f5caddec4c92da Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Tue, 23 May 2017 00:32:26 +0200 Subject: [PATCH 08/39] move log level parsing to tmlibs/cli package (Refs #504) --- cmd/tendermint/commands/flags/log_level.go | 87 ------------------- .../commands/flags/log_level_test.go | 64 -------------- cmd/tendermint/commands/root.go | 4 +- 3 files changed, 2 insertions(+), 153 deletions(-) delete mode 100644 cmd/tendermint/commands/flags/log_level.go delete mode 100644 cmd/tendermint/commands/flags/log_level_test.go diff --git a/cmd/tendermint/commands/flags/log_level.go b/cmd/tendermint/commands/flags/log_level.go deleted file mode 100644 index 6821563ad..000000000 --- a/cmd/tendermint/commands/flags/log_level.go +++ /dev/null @@ -1,87 +0,0 @@ -package flags - -import ( - "fmt" - "strings" - - "github.com/pkg/errors" - - cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tmlibs/log" -) - -const ( - defaultLogLevelKey = "*" -) - -// ParseLogLevel parses complex log level - comma-separated -// list of module:level pairs with an optional *:level pair (* means -// all other modules). -// -// Example: -// ParseLogLevel("consensus:debug,mempool:debug,*:error", log.NewTMLogger(os.Stdout)) -func ParseLogLevel(lvl string, logger log.Logger) (log.Logger, error) { - if lvl == "" { - return nil, errors.New("Empty log level") - } - - l := lvl - - // prefix simple one word levels (e.g. "info") with "*" - if !strings.Contains(l, ":") { - l = defaultLogLevelKey + ":" + l - } - - options := make([]log.Option, 0) - - isDefaultLogLevelSet := false - var option log.Option - var err error - - list := strings.Split(l, ",") - for _, item := range list { - moduleAndLevel := strings.Split(item, ":") - - if len(moduleAndLevel) != 2 { - return nil, fmt.Errorf("Expected list in a form of \"module:level\" pairs, given pair %s, list %s", item, list) - } - - module := moduleAndLevel[0] - level := moduleAndLevel[1] - - if module == defaultLogLevelKey { - option, err = log.AllowLevel(level) - if err != nil { - return nil, errors.Wrap(err, fmt.Sprintf("Failed to parse default log level (pair %s, list %s)", item, l)) - } - options = append(options, option) - isDefaultLogLevelSet = true - } else { - switch level { - case "debug": - option = log.AllowDebugWith("module", module) - case "info": - option = log.AllowInfoWith("module", module) - case "error": - option = log.AllowErrorWith("module", module) - case "none": - option = log.AllowNoneWith("module", module) - default: - return nil, fmt.Errorf("Expected either \"info\", \"debug\", \"error\" or \"none\" log level, given %s (pair %s, list %s)", level, item, list) - } - options = append(options, option) - - } - } - - // if "*" is not provided, set default global level - if !isDefaultLogLevelSet { - option, err = log.AllowLevel(cfg.DefaultLogLevel()) - if err != nil { - return nil, err - } - options = append(options, option) - } - - return log.NewFilter(logger, options...), nil -} diff --git a/cmd/tendermint/commands/flags/log_level_test.go b/cmd/tendermint/commands/flags/log_level_test.go deleted file mode 100644 index c89f3f880..000000000 --- a/cmd/tendermint/commands/flags/log_level_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package flags_test - -import ( - "bytes" - "strings" - "testing" - - tmflags "github.com/tendermint/tendermint/cmd/tendermint/commands/flags" - "github.com/tendermint/tmlibs/log" -) - -func TestParseLogLevel(t *testing.T) { - var buf bytes.Buffer - jsonLogger := log.NewTMJSONLogger(&buf) - - correctLogLevels := []struct { - lvl string - expectedLogLines []string - }{ - {"mempool:error", []string{``, ``, `{"_msg":"Mesmero","level":"error","module":"mempool"}`}}, - {"mempool:error,*:debug", []string{``, ``, `{"_msg":"Mesmero","level":"error","module":"mempool"}`}}, - {"*:debug,wire:none", []string{ - `{"_msg":"Kingpin","level":"debug","module":"mempool"}`, - `{"_msg":"Kitty Pryde","level":"info","module":"mempool"}`, - `{"_msg":"Mesmero","level":"error","module":"mempool"}`}}, - } - - for _, c := range correctLogLevels { - logger, err := tmflags.ParseLogLevel(c.lvl, jsonLogger) - if err != nil { - t.Fatal(err) - } - - logger = logger.With("module", "mempool") - - buf.Reset() - - logger.Debug("Kingpin") - if have := strings.TrimSpace(buf.String()); c.expectedLogLines[0] != have { - t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[0], have, c.lvl) - } - - buf.Reset() - - logger.Info("Kitty Pryde") - if have := strings.TrimSpace(buf.String()); c.expectedLogLines[1] != have { - t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[1], have, c.lvl) - } - - buf.Reset() - - logger.Error("Mesmero") - if have := strings.TrimSpace(buf.String()); c.expectedLogLines[2] != have { - t.Errorf("\nwant '%s'\nhave '%s'\nlevel '%s'", c.expectedLogLines[2], have, c.lvl) - } - } - - incorrectLogLevel := []string{"some", "mempool:some", "*:some,mempool:error"} - for _, lvl := range incorrectLogLevel { - if _, err := tmflags.ParseLogLevel(lvl, jsonLogger); err == nil { - t.Fatalf("Expected %s to produce error", lvl) - } - } -} diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go index 3565f3bb8..695dfcb11 100644 --- a/cmd/tendermint/commands/root.go +++ b/cmd/tendermint/commands/root.go @@ -6,8 +6,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - tmflags "github.com/tendermint/tendermint/cmd/tendermint/commands/flags" cfg "github.com/tendermint/tendermint/config" + tmflags "github.com/tendermint/tmlibs/cli/flags" "github.com/tendermint/tmlibs/log" ) @@ -30,7 +30,7 @@ var RootCmd = &cobra.Command{ } config.SetRoot(config.RootDir) cfg.EnsureRoot(config.RootDir) - logger, err = tmflags.ParseLogLevel(config.LogLevel, logger) + logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultBaseConfig().LogLevel) if err != nil { return err } From 9dcf130d67d6662ab4b1b445e72c821335b05df4 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 12 Jun 2017 19:25:34 +0400 Subject: [PATCH 09/39] update tmlibs (Refs #504) --- cmd/tendermint/commands/root.go | 2 +- glide.lock | 35 ++++++++++++++++++--------------- glide.yaml | 2 +- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go index 695dfcb11..ef5e86df6 100644 --- a/cmd/tendermint/commands/root.go +++ b/cmd/tendermint/commands/root.go @@ -30,7 +30,7 @@ var RootCmd = &cobra.Command{ } config.SetRoot(config.RootDir) cfg.EnsureRoot(config.RootDir) - logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultBaseConfig().LogLevel) + logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel()) if err != nil { return err } diff --git a/glide.lock b/glide.lock index 195386500..575f6a33f 100644 --- a/glide.lock +++ b/glide.lock @@ -1,12 +1,14 @@ -hash: 93f15c9766ea826c29a91f545c42172eafd8c61e39c1d81617114ad1a9c9eaf2 -updated: 2017-05-18T06:13:24.295793122-04:00 +hash: 74281881f3abf6e6c95e5aa5fe15e1891298c985f6c0584e658c8a03b4a5f7e1 +updated: 2017-06-12T15:23:33.311059702Z imports: - name: github.com/btcsuite/btcd - version: 53f55a46349aa8f44b90895047e843666991cf24 + version: b8df516b4b267acf2de46be593a9d948d1d2c420 subpackages: - btcec +- name: github.com/btcsuite/fastsha256 + version: 637e656429416087660c84436a2a035d69d54e2e - name: github.com/davecgh/go-spew - version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9 + version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 subpackages: - spew - name: github.com/ebuchman/fail-test @@ -14,7 +16,7 @@ imports: - name: github.com/fsnotify/fsnotify version: 4da3e2cfbabc9f751898f250b49f2439785783a1 - name: github.com/go-kit/kit - version: 6964666de57c88f7d93da127e900d201b632f561 + version: d67bb4c202e3b91377d1079b110a6c9ce23ab2f8 subpackages: - log - log/level @@ -22,13 +24,13 @@ imports: - name: github.com/go-logfmt/logfmt version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 - name: github.com/go-stack/stack - version: 7a2f19628aabfe68f0766b59e74d6315f8347d22 + version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 - name: github.com/gogo/protobuf version: 9df9efe4c742f1a2bfdedf1c3b6902fc6e814c6b subpackages: - proto - name: github.com/golang/protobuf - version: fec3b39b059c0f88fa6b20f5ed012b1aa203a8b4 + version: 18c9bb3261723cd5401db4d0c9fbc5c3b6c70fe8 subpackages: - proto - ptypes/any @@ -62,7 +64,7 @@ imports: - name: github.com/pelletier/go-toml version: 5c26a6ff6fd178719e15decac1c8196da0d7d6d1 - name: github.com/pkg/errors - version: c605e284fe17294bda444b34710735b29d1a9d90 + version: ff09b135c25aae272398c51a07235b90a75aa4f0 - name: github.com/pmezard/go-difflib version: d8ed2627bdf02c080bf22230dbb337003b7aba2d subpackages: @@ -82,7 +84,7 @@ imports: - name: github.com/spf13/viper version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2 - name: github.com/stretchr/testify - version: 4d4bfba8f1d1027c4fdbe371823030df51419987 + version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 subpackages: - assert - require @@ -122,17 +124,18 @@ imports: - data - data/base58 - name: github.com/tendermint/merkleeyes - version: a0e73e1ac3e18e12a007520a4ea2c9822256e307 + version: feb2c3fadac8221f96fbfce65a63af034327f972 subpackages: - app - client - iavl - testutil - name: github.com/tendermint/tmlibs - version: 306795ae1d8e4f4a10dcc8bdb32a00455843c9d5 + version: 6b619742ac69388dd591c30f55aaee46197b086e subpackages: - autofile - cli + - cli/flags - clist - common - db @@ -142,7 +145,7 @@ imports: - merkle - test - name: golang.org/x/crypto - version: 0fe963104e9d1877082f8fb38f816fcd97eb1d10 + version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e subpackages: - curve25519 - nacl/box @@ -153,7 +156,7 @@ imports: - ripemd160 - salsa20/salsa - name: golang.org/x/net - version: 513929065c19401a1c7b76ecd942f9f86a0c061b + version: feeb485667d1fdabe727840fe00adc22431bc86e subpackages: - context - http2 @@ -167,18 +170,18 @@ imports: subpackages: - unix - name: golang.org/x/text - version: 19e51611da83d6be54ddafce4a4af510cb3e9ea4 + version: 470f45bf29f4147d6fbd7dfd0a02a848e49f5bf4 subpackages: - secure/bidirule - transform - unicode/bidi - unicode/norm - name: google.golang.org/genproto - version: bb3573be0c484136831138976d444b8754777aff + version: 411e09b969b1170a9f0c467558eb4c4c110d9c77 subpackages: - googleapis/rpc/status - name: google.golang.org/grpc - version: 11d93ecdb918872ee841ba3a2dc391aa6d4f57c3 + version: 844f573616520565fdc6fb4db242321b5456fd6d subpackages: - codes - credentials diff --git a/glide.yaml b/glide.yaml index 63acdcbaa..f36ad9440 100644 --- a/glide.yaml +++ b/glide.yaml @@ -27,7 +27,7 @@ import: subpackages: - data - package: github.com/tendermint/tmlibs - version: v0.2.0 + version: v0.2.1 subpackages: - autofile - cli From b9b2782c3c7d8fdc09457818027d38fb71011bdd Mon Sep 17 00:00:00 2001 From: hxzqlh Date: Wed, 14 Jun 2017 14:41:36 +0800 Subject: [PATCH 10/39] logger key doesn't support space --- state/execution.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/state/execution.go b/state/execution.go index 768a0b1de..da39b369b 100644 --- a/state/execution.go +++ b/state/execution.go @@ -106,7 +106,7 @@ func execBlockOnProxyApp(eventCache types.Fireable, proxyAppConn proxy.AppConnCo valDiff := abciResponses.EndBlock.Diffs - logger.Info("Executed block", "height", block.Height, "valid txs", validTxs, "invalid txs", invalidTxs) + logger.Info("Executed block", "height", block.Height, "validTxs", validTxs, "invalidTxs", invalidTxs) if len(valDiff) > 0 { logger.Info("Update to validator set", "updates", abci.ValidatorsString(valDiff)) } From 562dd67e16e0d17050e069dfef8da3e998ab153e Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Wed, 14 Jun 2017 12:50:01 +0400 Subject: [PATCH 11/39] fix invalid keys (space is prohibited by logfmt encoder) --- consensus/reactor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/reactor.go b/consensus/reactor.go index 3652697b5..2c71dbc32 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -412,7 +412,7 @@ OUTER_LOOP: // Ensure that the peer's PartSetHeader is correct blockMeta := conR.conS.blockStore.LoadBlockMeta(prs.Height) if blockMeta == nil { - logger.Error("Failed to load block meta", "peer height", prs.Height, "our height", rs.Height, "blockstore height", conR.conS.blockStore.Height(), "pv", conR.conS.privValidator) + logger.Error("Failed to load block meta", "peer height", prs.Height, "ourHeight", rs.Height, "blockstoreHeight", conR.conS.blockStore.Height(), "pv", conR.conS.privValidator) time.Sleep(peerGossipSleepDuration) continue OUTER_LOOP } else if !blockMeta.BlockID.PartsHeader.Equals(prs.ProposalBlockPartsHeader) { From b4ece657263180d20d4474341152350ec2cd9909 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Wed, 14 Jun 2017 12:50:49 +0400 Subject: [PATCH 12/39] standardize key for errors (should be "err") --- blockchain/reactor.go | 4 ++-- consensus/reactor.go | 4 ++-- consensus/state.go | 20 ++++++++++---------- mempool/reactor.go | 2 +- node/node.go | 4 ++-- p2p/addrbook.go | 2 +- p2p/connection.go | 14 +++++++------- p2p/listener.go | 6 +++--- p2p/pex_reactor.go | 4 ++-- p2p/switch.go | 14 +++++++------- rpc/lib/client/ws_client.go | 4 ++-- rpc/lib/server/handlers.go | 8 ++++---- rpc/lib/server/http_server.go | 2 +- state/execution.go | 8 ++++---- state/state.go | 2 +- 15 files changed, 49 insertions(+), 49 deletions(-) diff --git a/blockchain/reactor.go b/blockchain/reactor.go index 1c0ef3a7d..9fa3b2a87 100644 --- a/blockchain/reactor.go +++ b/blockchain/reactor.go @@ -128,7 +128,7 @@ func (bcR *BlockchainReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { func (bcR *BlockchainReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { _, msg, err := DecodeMessage(msgBytes) if err != nil { - bcR.Logger.Error("Error decoding message", "error", err) + bcR.Logger.Error("Error decoding message", "err", err) return } @@ -231,7 +231,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", "error", err) + bcR.Logger.Info("error in validation", "err", err) bcR.pool.RedoRequest(first.Height) break SYNC_LOOP } else { diff --git a/consensus/reactor.go b/consensus/reactor.go index 2c71dbc32..df9fa1809 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -154,7 +154,7 @@ func (conR *ConsensusReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) _, msg, err := DecodeMessage(msgBytes) if err != nil { - conR.Logger.Error("Error decoding message", "src", src, "chId", chID, "msg", msg, "error", err, "bytes", msgBytes) + conR.Logger.Error("Error decoding message", "src", src, "chId", chID, "msg", msg, "err", err, "bytes", msgBytes) // TODO punish peer? return } @@ -282,7 +282,7 @@ func (conR *ConsensusReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) } if err != nil { - conR.Logger.Error("Error in Receive()", "error", err) + conR.Logger.Error("Error in Receive()", "err", err) } } diff --git a/consensus/state.go b/consensus/state.go index d4056facf..0d1868606 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -311,7 +311,7 @@ func (cs *ConsensusState) OnStart() error { walFile := cs.config.WalFile() if err := cs.OpenWAL(walFile); err != nil { - cs.Logger.Error("Error loading ConsensusState wal", "error", err.Error()) + cs.Logger.Error("Error loading ConsensusState wal", "err", err.Error()) return err } @@ -325,7 +325,7 @@ func (cs *ConsensusState) OnStart() error { // we may have lost some votes if the process crashed // reload from consensus log to catchup if err := cs.catchupReplay(cs.Height); err != nil { - cs.Logger.Error("Error on catchup replay. Proceeding to start ConsensusState anyway", "error", err.Error()) + cs.Logger.Error("Error on catchup replay. Proceeding to start ConsensusState anyway", "err", err.Error()) // NOTE: if we ever do return an error here, // make sure to stop the timeoutTicker } @@ -368,7 +368,7 @@ func (cs *ConsensusState) Wait() { func (cs *ConsensusState) OpenWAL(walFile string) (err error) { err = cmn.EnsureDir(path.Dir(walFile), 0700) if err != nil { - cs.Logger.Error("Error ensuring ConsensusState wal dir", "error", err.Error()) + cs.Logger.Error("Error ensuring ConsensusState wal dir", "err", err.Error()) return err } @@ -663,7 +663,7 @@ func (cs *ConsensusState) handleMsg(mi msgInfo, rs RoundState) { cs.Logger.Error("Unknown msg type", reflect.TypeOf(msg)) } if err != nil { - cs.Logger.Error("Error with msg", "type", reflect.TypeOf(msg), "peer", peerKey, "error", err, "msg", msg) + cs.Logger.Error("Error with msg", "type", reflect.TypeOf(msg), "peer", peerKey, "err", err, "msg", msg) } } @@ -831,7 +831,7 @@ func (cs *ConsensusState) defaultDecideProposal(height, round int) { cs.Logger.Debug(cmn.Fmt("Signed proposal block: %v", block)) } else { if !cs.replayMode { - cs.Logger.Error("enterPropose: Error signing proposal", "height", height, "round", round, "error", err) + cs.Logger.Error("enterPropose: Error signing proposal", "height", height, "round", round, "err", err) } } } @@ -930,7 +930,7 @@ func (cs *ConsensusState) defaultDoPrevote(height int, round int) { err := cs.state.ValidateBlock(cs.ProposalBlock) if err != nil { // ProposalBlock is invalid, prevote nil. - cs.Logger.Error("enterPrevote: ProposalBlock is invalid", "error", err) + cs.Logger.Error("enterPrevote: ProposalBlock is invalid", "err", err) cs.signAddVote(types.VoteTypePrevote, nil, types.PartSetHeader{}) return } @@ -1218,7 +1218,7 @@ func (cs *ConsensusState) finalizeCommit(height int) { // NOTE: the block.AppHash wont reflect these txs until the next block err := stateCopy.ApplyBlock(eventCache, cs.proxyAppConn, block, blockParts.Header(), cs.mempool) if err != nil { - cs.Logger.Error("Error on ApplyBlock. Did the application crash? Please restart tendermint", "error", err) + cs.Logger.Error("Error on ApplyBlock. Did the application crash? Please restart tendermint", "err", err) return } @@ -1350,7 +1350,7 @@ func (cs *ConsensusState) tryAddVote(vote *types.Vote, peerKey string) error { return err } else { // Probably an invalid signature. Bad peer. - cs.Logger.Error("Error attempting to add vote", "error", err) + cs.Logger.Error("Error attempting to add vote", "err", err) return ErrAddingVote } } @@ -1491,11 +1491,11 @@ func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.Part vote, err := cs.signVote(type_, hash, header) if err == nil { cs.sendInternalMessage(msgInfo{&VoteMessage{vote}, ""}) - cs.Logger.Info("Signed and pushed vote", "height", cs.Height, "round", cs.Round, "vote", vote, "error", err) + cs.Logger.Info("Signed and pushed vote", "height", cs.Height, "round", cs.Round, "vote", vote, "err", err) return vote } else { //if !cs.replayMode { - cs.Logger.Error("Error signing vote", "height", cs.Height, "round", cs.Round, "vote", vote, "error", err) + cs.Logger.Error("Error signing vote", "height", cs.Height, "round", cs.Round, "vote", vote, "err", err) //} return nil } diff --git a/mempool/reactor.go b/mempool/reactor.go index 842e11538..25806c00f 100644 --- a/mempool/reactor.go +++ b/mempool/reactor.go @@ -63,7 +63,7 @@ func (memR *MempoolReactor) RemovePeer(peer *p2p.Peer, reason interface{}) { func (memR *MempoolReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) { _, msg, err := DecodeMessage(msgBytes) if err != nil { - memR.Logger.Error("Error decoding message", "error", err) + memR.Logger.Error("Error decoding message", "err", err) return } memR.Logger.Debug("Receive", "src", src, "chId", chID, "msg", msg) diff --git a/node/node.go b/node/node.go index 12f683153..672e384b9 100644 --- a/node/node.go +++ b/node/node.go @@ -205,7 +205,7 @@ func NewNode(config *cfg.Config, privValidator *types.PrivValidator, clientCreat if profileHost != "" { go func() { - logger.Error("Profile server", "error", http.ListenAndServe(profileHost, nil)) + logger.Error("Profile server", "err", http.ListenAndServe(profileHost, nil)) }() } @@ -276,7 +276,7 @@ func (n *Node) OnStop() { for _, l := range n.rpcListeners { n.Logger.Info("Closing rpc listener", "listener", l) if err := l.Close(); err != nil { - n.Logger.Error("Error closing listener", "listener", l, "error", err) + n.Logger.Error("Error closing listener", "listener", l, "err", err) } } } diff --git a/p2p/addrbook.go b/p2p/addrbook.go index 1df0817ee..b91c441f7 100644 --- a/p2p/addrbook.go +++ b/p2p/addrbook.go @@ -340,7 +340,7 @@ func (a *AddrBook) saveToFile(filePath string) { } err = cmn.WriteFileAtomic(filePath, jsonBytes, 0644) if err != nil { - a.Logger.Error("Failed to save AddrBook to file", "file", filePath, "error", err) + a.Logger.Error("Failed to save AddrBook to file", "file", filePath, "err", err) } } diff --git a/p2p/connection.go b/p2p/connection.go index 36f15abb7..634a8ce14 100644 --- a/p2p/connection.go +++ b/p2p/connection.go @@ -180,7 +180,7 @@ func (c *MConnection) flush() { c.Logger.Debug("Flush", "conn", c) err := c.bufWriter.Flush() if err != nil { - c.Logger.Error("MConnection flush failed", "error", err) + c.Logger.Error("MConnection flush failed", "err", err) } } @@ -318,7 +318,7 @@ FOR_LOOP: break FOR_LOOP } if err != nil { - c.Logger.Error("Connection failed @ sendRoutine", "conn", c, "error", err) + c.Logger.Error("Connection failed @ sendRoutine", "conn", c, "err", err) c.stopForError(err) break FOR_LOOP } @@ -373,7 +373,7 @@ func (c *MConnection) sendMsgPacket() bool { // Make & send a msgPacket from this channel n, err := leastChannel.writeMsgPacketTo(c.bufWriter) if err != nil { - c.Logger.Error("Failed to write msgPacket", "error", err) + c.Logger.Error("Failed to write msgPacket", "err", err) c.stopForError(err) return true } @@ -401,7 +401,7 @@ FOR_LOOP: if err == nil { return bytes } else { - log.Warn("Error peeking connection buffer", "error", err) + log.Warn("Error peeking connection buffer", "err", err) return nil } }}) @@ -415,7 +415,7 @@ FOR_LOOP: c.recvMonitor.Update(int(n)) if err != nil { if c.IsRunning() { - c.Logger.Error("Connection failed @ recvRoutine (reading byte)", "conn", c, "error", err) + c.Logger.Error("Connection failed @ recvRoutine (reading byte)", "conn", c, "err", err) c.stopForError(err) } break FOR_LOOP @@ -436,7 +436,7 @@ FOR_LOOP: c.recvMonitor.Update(int(n)) if err != nil { if c.IsRunning() { - c.Logger.Error("Connection failed @ recvRoutine", "conn", c, "error", err) + c.Logger.Error("Connection failed @ recvRoutine", "conn", c, "err", err) c.stopForError(err) } break FOR_LOOP @@ -448,7 +448,7 @@ FOR_LOOP: msgBytes, err := channel.recvMsgPacket(pkt) if err != nil { if c.IsRunning() { - c.Logger.Error("Connection failed @ recvRoutine", "conn", c, "error", err) + c.Logger.Error("Connection failed @ recvRoutine", "conn", c, "err", err) c.stopForError(err) } break FOR_LOOP diff --git a/p2p/listener.go b/p2p/listener.go index d31f0de83..46ec1cdcd 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -171,13 +171,13 @@ func getUPNPExternalAddress(externalPort, internalPort int, logger log.Logger) * logger.Info("Getting UPNP external address") nat, err := upnp.Discover() if err != nil { - logger.Info("Could not perform UPNP discover", "error", err) + logger.Info("Could not perform UPNP discover", "err", err) return nil } ext, err := nat.GetExternalAddress() if err != nil { - logger.Info("Could not get UPNP external address", "error", err) + logger.Info("Could not get UPNP external address", "err", err) return nil } @@ -188,7 +188,7 @@ func getUPNPExternalAddress(externalPort, internalPort int, logger log.Logger) * externalPort, err = nat.AddPortMapping("tcp", externalPort, internalPort, "tendermint", 0) if err != nil { - logger.Info("Could not add UPNP port mapping", "error", err) + logger.Info("Could not add UPNP port mapping", "err", err) return nil } diff --git a/p2p/pex_reactor.go b/p2p/pex_reactor.go index 269a8d006..79ca21ab1 100644 --- a/p2p/pex_reactor.go +++ b/p2p/pex_reactor.go @@ -105,7 +105,7 @@ func (r *PEXReactor) AddPeer(p *Peer) { addr, err := NewNetAddressString(p.ListenAddr) if err != nil { // this should never happen - r.Logger.Error("Error in AddPeer: invalid peer address", "addr", p.ListenAddr, "error", err) + r.Logger.Error("Error in AddPeer: invalid peer address", "addr", p.ListenAddr, "err", err) return } r.book.AddAddress(addr, addr) @@ -132,7 +132,7 @@ func (r *PEXReactor) Receive(chID byte, src *Peer, msgBytes []byte) { _, msg, err := DecodeMessage(msgBytes) if err != nil { - r.Logger.Error("Error decoding message", "error", err) + r.Logger.Error("Error decoding message", "err", err) return } r.Logger.Info("Received message", "msg", msg) diff --git a/p2p/switch.go b/p2p/switch.go index 5ccdc114e..2e9d213df 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -309,7 +309,7 @@ func (sw *Switch) DialSeeds(addrBook *AddrBook, seeds []string) error { func (sw *Switch) dialSeed(addr *NetAddress) { peer, err := sw.DialPeerWithAddress(addr, true) if err != nil { - sw.Logger.Error("Error dialing seed", "error", err) + sw.Logger.Error("Error dialing seed", "err", err) } else { sw.Logger.Info("Connected to seed", "peer", peer) } @@ -322,7 +322,7 @@ func (sw *Switch) DialPeerWithAddress(addr *NetAddress, persistent bool) (*Peer, sw.Logger.Info("Dialing peer", "address", addr) peer, err := newOutboundPeerWithConfig(addr, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError, sw.nodePrivKey, sw.peerConfig) if err != nil { - sw.Logger.Error("Failed to dial peer", "address", addr, "error", err) + sw.Logger.Error("Failed to dial peer", "address", addr, "err", err) return nil, err } peer.SetLogger(sw.Logger.With("peer", addr)) @@ -331,7 +331,7 @@ func (sw *Switch) DialPeerWithAddress(addr *NetAddress, persistent bool) (*Peer, } err = sw.AddPeer(peer) if err != nil { - sw.Logger.Error("Failed to add peer", "address", addr, "error", err) + sw.Logger.Error("Failed to add peer", "address", addr, "err", err) peer.CloseConn() return nil, err } @@ -381,7 +381,7 @@ func (sw *Switch) Peers() IPeerSet { // TODO: make record depending on reason. func (sw *Switch) StopPeerForError(peer *Peer, reason interface{}) { addr := NewNetAddress(peer.Addr()) - sw.Logger.Info("Stopping peer for error", "peer", peer, "error", reason) + sw.Logger.Info("Stopping peer for error", "peer", peer, "err", reason) sw.stopAndRemovePeer(peer, reason) if peer.IsPersistent() { @@ -395,10 +395,10 @@ func (sw *Switch) StopPeerForError(peer *Peer, reason interface{}) { peer, err := sw.DialPeerWithAddress(addr, true) if err != nil { if i == reconnectAttempts { - sw.Logger.Info("Error reconnecting to peer. Giving up", "tries", i, "error", err) + sw.Logger.Info("Error reconnecting to peer. Giving up", "tries", i, "err", err) return } - sw.Logger.Info("Error reconnecting to peer. Trying again", "tries", i, "error", err) + sw.Logger.Info("Error reconnecting to peer. Trying again", "tries", i, "err", err) time.Sleep(reconnectInterval) continue } @@ -442,7 +442,7 @@ func (sw *Switch) listenerRoutine(l Listener) { // New inbound connection! err := sw.addPeerWithConnectionAndConfig(inConn, sw.peerConfig) if err != nil { - sw.Logger.Info("Ignoring inbound connection: error while adding peer", "address", inConn.RemoteAddr().String(), "error", err) + sw.Logger.Info("Ignoring inbound connection: error while adding peer", "address", inConn.RemoteAddr().String(), "err", err) continue } diff --git a/rpc/lib/client/ws_client.go b/rpc/lib/client/ws_client.go index 1ad744e87..f018de67c 100644 --- a/rpc/lib/client/ws_client.go +++ b/rpc/lib/client/ws_client.go @@ -100,14 +100,14 @@ func (wsc *WSClient) receiveEventsRoutine() { for { _, data, err := wsc.ReadMessage() if err != nil { - wsc.Logger.Info("WSClient failed to read message", "error", err, "data", string(data)) + wsc.Logger.Info("WSClient failed to read message", "err", err, "data", string(data)) wsc.Stop() break } else { var response types.RPCResponse err := json.Unmarshal(data, &response) if err != nil { - wsc.Logger.Info("WSClient failed to parse message", "error", err, "data", string(data)) + wsc.Logger.Info("WSClient failed to parse message", "err", err, "data", string(data)) wsc.ErrorsCh <- err continue } diff --git a/rpc/lib/server/handlers.go b/rpc/lib/server/handlers.go index 5745f6fa1..a3dad8cdf 100644 --- a/rpc/lib/server/handlers.go +++ b/rpc/lib/server/handlers.go @@ -534,18 +534,18 @@ func (wsc *wsConnection) writeRoutine() { case <-wsc.pingTicker.C: err := wsc.baseConn.WriteMessage(websocket.PingMessage, []byte{}) if err != nil { - wsc.Logger.Error("Failed to write ping message on websocket", "error", err) + wsc.Logger.Error("Failed to write ping message on websocket", "err", err) wsc.Stop() return } case msg := <-wsc.writeChan: jsonBytes, err := json.MarshalIndent(msg, "", " ") if err != nil { - wsc.Logger.Error("Failed to marshal RPCResponse to JSON", "error", err) + wsc.Logger.Error("Failed to marshal RPCResponse to JSON", "err", err) } else { wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds)) if err = wsc.baseConn.WriteMessage(websocket.TextMessage, jsonBytes); err != nil { - wsc.Logger.Error("Failed to write response on websocket", "error", err) + wsc.Logger.Error("Failed to write response on websocket", "err", err) wsc.Stop() return } @@ -591,7 +591,7 @@ func (wm *WebsocketManager) WebsocketHandler(w http.ResponseWriter, r *http.Requ wsConn, err := wm.Upgrade(w, r, nil) if err != nil { // TODO - return http error - wm.logger.Error("Failed to upgrade to websocket connection", "error", err) + wm.logger.Error("Failed to upgrade to websocket connection", "err", err) return } diff --git a/rpc/lib/server/http_server.go b/rpc/lib/server/http_server.go index 3b856b5db..270321b4b 100644 --- a/rpc/lib/server/http_server.go +++ b/rpc/lib/server/http_server.go @@ -97,7 +97,7 @@ func RecoverAndLogHandler(handler http.Handler, logger log.Logger) http.Handler WriteRPCResponseHTTP(rww, res) } else { // For the rest, - logger.Error("Panic in RPC HTTP handler", "error", e, "stack", string(debug.Stack())) + logger.Error("Panic in RPC HTTP handler", "err", e, "stack", string(debug.Stack())) rww.WriteHeader(http.StatusInternalServerError) WriteRPCResponseHTTP(rww, types.NewRPCResponse("", nil, fmt.Sprintf("Internal Server Error: %v", e))) } diff --git a/state/execution.go b/state/execution.go index da39b369b..db2091804 100644 --- a/state/execution.go +++ b/state/execution.go @@ -85,7 +85,7 @@ func execBlockOnProxyApp(eventCache types.Fireable, proxyAppConn proxy.AppConnCo // Begin block err := proxyAppConn.BeginBlockSync(block.Hash(), types.TM2PB.Header(block.Header)) if err != nil { - logger.Error("Error in proxyAppConn.BeginBlock", "error", err) + logger.Error("Error in proxyAppConn.BeginBlock", "err", err) return nil, err } @@ -100,7 +100,7 @@ func execBlockOnProxyApp(eventCache types.Fireable, proxyAppConn proxy.AppConnCo // End block abciResponses.EndBlock, err = proxyAppConn.EndBlockSync(uint64(block.Height)) if err != nil { - logger.Error("Error in proxyAppConn.EndBlock", "error", err) + logger.Error("Error in proxyAppConn.EndBlock", "err", err) return nil, err } @@ -252,7 +252,7 @@ func (s *State) CommitStateUpdateMempool(proxyAppConn proxy.AppConnConsensus, bl // Commit block, get hash back res := proxyAppConn.CommitSync() if res.IsErr() { - s.logger.Error("Error in proxyAppConn.CommitSync", "error", res) + s.logger.Error("Error in proxyAppConn.CommitSync", "err", res) return res } if res.Log != "" { @@ -298,7 +298,7 @@ func ExecCommitBlock(appConnConsensus proxy.AppConnConsensus, block *types.Block // Commit block, get hash back res := appConnConsensus.CommitSync() if res.IsErr() { - logger.Error("Error in proxyAppConn.CommitSync", "error", res) + logger.Error("Error in proxyAppConn.CommitSync", "err", res) return nil, res } if res.Log != "" { diff --git a/state/state.go b/state/state.go index 808fcbe24..59d2d42bd 100644 --- a/state/state.go +++ b/state/state.go @@ -148,7 +148,7 @@ func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader typ // update the validator set with the latest abciResponses err := updateValidators(nextValSet, abciResponses.EndBlock.Diffs) if err != nil { - s.logger.Error("Error changing validator set", "error", err) + s.logger.Error("Error changing validator set", "err", err) // TODO: err or carry on? } From eaec0c8ea51ae7304fcce75e1c7431d0d0881806 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Fri, 26 May 2017 13:24:32 +0200 Subject: [PATCH 13/39] deduplicate tests in rpc/test and rpc/client (Refs #496) --- rpc/client/event_test.go | 67 +++++++- rpc/client/rpc_test.go | 91 ++++++++++ rpc/test/client_test.go | 352 --------------------------------------- rpc/test/grpc_test.go | 6 +- rpc/test/helpers.go | 92 ---------- 5 files changed, 159 insertions(+), 449 deletions(-) delete mode 100644 rpc/test/client_test.go diff --git a/rpc/client/event_test.go b/rpc/client/event_test.go index 1b99854cb..ad5522e49 100644 --- a/rpc/client/event_test.go +++ b/rpc/client/event_test.go @@ -31,7 +31,39 @@ func TestHeaderEvents(t *testing.T) { } } -func TestTxEvents(t *testing.T) { +func TestBlockEvents(t *testing.T) { + require := require.New(t) + for i, c := range GetClients() { + // start for this test it if it wasn't already running + if !c.IsRunning() { + // if so, then we start it, listen, and stop it. + st, err := c.Start() + require.Nil(err, "%d: %+v", i, err) + require.True(st, "%d", i) + defer c.Stop() + } + + // listen for a new block; ensure height increases by 1 + var firstBlockHeight int + for i := 0; i < 3; i++ { + evtTyp := types.EventStringNewBlock() + evt, err := client.WaitForOneEvent(c, evtTyp, 1*time.Second) + require.Nil(err, "%d: %+v", i, err) + blockEvent, ok := evt.Unwrap().(types.EventDataNewBlock) + require.True(ok, "%d: %#v", i, evt) + + block := blockEvent.Block + if i == 0 { + firstBlockHeight = block.Header.Height + continue + } + + require.Equal(block.Header.Height, firstBlockHeight+i) + } + } +} + +func TestTxEventsSentWithBroadcastTxAsync(t *testing.T) { require := require.New(t) for i, c := range GetClients() { // start for this test it if it wasn't already running @@ -63,3 +95,36 @@ func TestTxEvents(t *testing.T) { require.True(txe.Code.IsOK()) } } + +func TestTxEventsSentWithBroadcastTxSync(t *testing.T) { + require := require.New(t) + for i, c := range GetClients() { + // start for this test it if it wasn't already running + if !c.IsRunning() { + // if so, then we start it, listen, and stop it. + st, err := c.Start() + require.Nil(err, "%d: %+v", i, err) + require.True(st, "%d", i) + defer c.Stop() + } + + // make the tx + _, _, tx := merktest.MakeTxKV() + evtTyp := types.EventStringTx(types.Tx(tx)) + + // send async + txres, err := c.BroadcastTxSync(tx) + require.Nil(err, "%+v", err) + require.True(txres.Code.IsOK()) + + // and wait for confirmation + evt, err := client.WaitForOneEvent(c, evtTyp, 1*time.Second) + require.Nil(err, "%d: %+v", i, err) + // and make sure it has the proper info + txe, ok := evt.Unwrap().(types.EventDataTx) + require.True(ok, "%d: %#v", i, evt) + // make sure this is the proper tx + require.EqualValues(tx, txe.Tx) + require.True(txe.Code.IsOK()) + } +} diff --git a/rpc/client/rpc_test.go b/rpc/client/rpc_test.go index 13b440479..e82f8df42 100644 --- a/rpc/client/rpc_test.go +++ b/rpc/client/rpc_test.go @@ -10,6 +10,7 @@ import ( merktest "github.com/tendermint/merkleeyes/testutil" "github.com/tendermint/tendermint/rpc/client" rpctest "github.com/tendermint/tendermint/rpc/test" + "github.com/tendermint/tendermint/types" ) func getHTTPClient() *client.HTTP { @@ -182,3 +183,93 @@ func TestAppCalls(t *testing.T) { } } } + +func TestBroadcastTxSync(t *testing.T) { + require := require.New(t) + + mempool := node.MempoolReactor().Mempool + initMempoolSize := mempool.Size() + + for i, c := range GetClients() { + _, _, tx := merktest.MakeTxKV() + bres, err := c.BroadcastTxSync(tx) + require.Nil(err, "%d: %+v", i, err) + require.True(bres.Code.IsOK()) + + require.Equal(initMempoolSize+1, mempool.Size()) + + txs := mempool.Reap(1) + require.EqualValues(tx, txs[0]) + mempool.Flush() + } +} + +func TestBroadcastTxCommit(t *testing.T) { + require := require.New(t) + + mempool := node.MempoolReactor().Mempool + for i, c := range GetClients() { + _, _, tx := merktest.MakeTxKV() + bres, err := c.BroadcastTxCommit(tx) + require.Nil(err, "%d: %+v", i, err) + require.True(bres.CheckTx.Code.IsOK()) + require.True(bres.DeliverTx.Code.IsOK()) + + require.Equal(0, mempool.Size()) + } +} + +func TestTx(t *testing.T) { + assert, require := assert.New(t), require.New(t) + + // first we broadcast a tx + c := getHTTPClient() + _, _, tx := merktest.MakeTxKV() + bres, err := c.BroadcastTxCommit(tx) + require.Nil(err, "%+v", err) + + txHeight := bres.Height + txHash := bres.Hash + + anotherTxHash := types.Tx("a different tx").Hash() + + cases := []struct { + valid bool + hash []byte + prove bool + }{ + // only valid if correct hash provided + {true, txHash, false}, + {true, txHash, true}, + {false, anotherTxHash, false}, + {false, anotherTxHash, true}, + {false, nil, false}, + {false, nil, true}, + } + + for i, c := range GetClients() { + for j, tc := range cases { + t.Logf("client %d, case %d", i, j) + + // now we query for the tx. + // since there's only one tx, we know index=0. + ptx, err := c.Tx(tc.hash, tc.prove) + + if !tc.valid { + require.NotNil(err) + } else { + require.Nil(err, "%+v", err) + assert.Equal(txHeight, ptx.Height) + assert.EqualValues(tx, ptx.Tx) + assert.Equal(0, ptx.Index) + assert.True(ptx.TxResult.Code.IsOK()) + + // time to verify the proof + proof := ptx.Proof + if tc.prove && assert.EqualValues(tx, proof.Data) { + assert.True(proof.Proof.Verify(proof.Index, proof.Total, txHash, proof.RootHash)) + } + } + } + } +} diff --git a/rpc/test/client_test.go b/rpc/test/client_test.go deleted file mode 100644 index b7df67841..000000000 --- a/rpc/test/client_test.go +++ /dev/null @@ -1,352 +0,0 @@ -package rpctest - -import ( - "bytes" - crand "crypto/rand" - "fmt" - "math/rand" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - abci "github.com/tendermint/abci/types" - "github.com/tendermint/go-wire/data" - . "github.com/tendermint/tmlibs/common" - - "github.com/tendermint/tendermint/rpc/core" - ctypes "github.com/tendermint/tendermint/rpc/core/types" - rpc "github.com/tendermint/tendermint/rpc/lib/client" - "github.com/tendermint/tendermint/state/txindex/null" - "github.com/tendermint/tendermint/types" -) - -//-------------------------------------------------------------------------------- -// Test the HTTP client -// These tests assume the dummy app -//-------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------- -// status - -func TestURIStatus(t *testing.T) { - testStatus(t, GetURIClient()) -} - -func TestJSONStatus(t *testing.T) { - testStatus(t, GetJSONClient()) -} - -func testStatus(t *testing.T, client rpc.HTTPClient) { - moniker := GetConfig().Moniker - result := new(ctypes.ResultStatus) - _, err := client.Call("status", map[string]interface{}{}, result) - require.Nil(t, err) - assert.Equal(t, moniker, result.NodeInfo.Moniker) -} - -//-------------------------------------------------------------------------------- -// broadcast tx sync - -// random bytes (excluding byte('=')) -func randBytes(t *testing.T) []byte { - n := rand.Intn(10) + 2 - buf := make([]byte, n) - _, err := crand.Read(buf) - require.Nil(t, err) - return bytes.Replace(buf, []byte("="), []byte{100}, -1) -} - -func TestURIBroadcastTxSync(t *testing.T) { - testBroadcastTxSync(t, GetURIClient()) -} - -func TestJSONBroadcastTxSync(t *testing.T) { - testBroadcastTxSync(t, GetJSONClient()) -} - -func testBroadcastTxSync(t *testing.T, client rpc.HTTPClient) { - mem := node.MempoolReactor().Mempool - initMemSize := mem.Size() - result := new(ctypes.ResultBroadcastTx) - tx := randBytes(t) - _, err := client.Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, result) - require.Nil(t, err) - - require.Equal(t, abci.CodeType_OK, result.Code) - require.Equal(t, initMemSize+1, mem.Size()) - txs := mem.Reap(1) - require.EqualValues(t, tx, txs[0]) - mem.Flush() -} - -//-------------------------------------------------------------------------------- -// query - -func testTxKV(t *testing.T) ([]byte, []byte, types.Tx) { - k := randBytes(t) - v := randBytes(t) - return k, v, types.Tx(Fmt("%s=%s", k, v)) -} - -func sendTx(t *testing.T, client rpc.HTTPClient) ([]byte, []byte) { - result := new(ctypes.ResultBroadcastTxCommit) - k, v, tx := testTxKV(t) - _, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, result) - require.Nil(t, err) - require.NotNil(t, 0, result.DeliverTx, "%#v", result) - require.EqualValues(t, 0, result.CheckTx.Code, "%#v", result) - require.EqualValues(t, 0, result.DeliverTx.Code, "%#v", result) - return k, v -} - -func TestURIABCIQuery(t *testing.T) { - testABCIQuery(t, GetURIClient()) -} - -func TestJSONABCIQuery(t *testing.T) { - testABCIQuery(t, GetJSONClient()) -} - -func testABCIQuery(t *testing.T, client rpc.HTTPClient) { - k, _ := sendTx(t, client) - time.Sleep(time.Millisecond * 500) - result := new(ctypes.ResultABCIQuery) - _, err := client.Call("abci_query", - map[string]interface{}{"path": "", "data": data.Bytes(k), "prove": false}, result) - require.Nil(t, err) - - require.EqualValues(t, 0, result.Code) - - // XXX: specific to value returned by the dummy - require.NotEqual(t, 0, len(result.Value)) -} - -//-------------------------------------------------------------------------------- -// broadcast tx commit - -func TestURIBroadcastTxCommit(t *testing.T) { - testBroadcastTxCommit(t, GetURIClient()) -} - -func TestJSONBroadcastTxCommit(t *testing.T) { - testBroadcastTxCommit(t, GetJSONClient()) -} - -func testBroadcastTxCommit(t *testing.T, client rpc.HTTPClient) { - require := require.New(t) - - result := new(ctypes.ResultBroadcastTxCommit) - tx := randBytes(t) - _, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, result) - require.Nil(err) - - checkTx := result.CheckTx - require.Equal(abci.CodeType_OK, checkTx.Code) - deliverTx := result.DeliverTx - require.Equal(abci.CodeType_OK, deliverTx.Code) - mem := node.MempoolReactor().Mempool - require.Equal(0, mem.Size()) - // TODO: find tx in block -} - -//-------------------------------------------------------------------------------- -// query tx - -func TestURITx(t *testing.T) { - testTx(t, GetURIClient(), true) - - core.SetTxIndexer(&null.TxIndex{}) - defer core.SetTxIndexer(node.ConsensusState().GetState().TxIndexer) - - testTx(t, GetURIClient(), false) -} - -func TestJSONTx(t *testing.T) { - testTx(t, GetJSONClient(), true) - - core.SetTxIndexer(&null.TxIndex{}) - testTx(t, GetJSONClient(), false) - core.SetTxIndexer(node.ConsensusState().GetState().TxIndexer) -} - -func testTx(t *testing.T, client rpc.HTTPClient, withIndexer bool) { - assert, require := assert.New(t), require.New(t) - - // first we broadcast a tx - result := new(ctypes.ResultBroadcastTxCommit) - txBytes := randBytes(t) - tx := types.Tx(txBytes) - _, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": txBytes}, result) - require.Nil(err) - - checkTx := result.CheckTx - require.Equal(abci.CodeType_OK, checkTx.Code) - deliverTx := result.DeliverTx - require.Equal(abci.CodeType_OK, deliverTx.Code) - mem := node.MempoolReactor().Mempool - require.Equal(0, mem.Size()) - - txHash := tx.Hash() - txHash2 := types.Tx("a different tx").Hash() - - cases := []struct { - valid bool - hash []byte - prove bool - }{ - // only valid if correct hash provided - {true, txHash, false}, - {true, txHash, true}, - {false, txHash2, false}, - {false, txHash2, true}, - {false, nil, false}, - {false, nil, true}, - } - - for i, tc := range cases { - idx := fmt.Sprintf("%d", i) - - // now we query for the tx. - // since there's only one tx, we know index=0. - result2 := new(ctypes.ResultTx) - query := map[string]interface{}{ - "hash": tc.hash, - "prove": tc.prove, - } - _, err = client.Call("tx", query, result2) - valid := (withIndexer && tc.valid) - if !valid { - require.NotNil(err, idx) - } else { - require.Nil(err, idx) - assert.Equal(tx, result2.Tx, idx) - assert.Equal(result.Height, result2.Height, idx) - assert.Equal(0, result2.Index, idx) - assert.Equal(abci.CodeType_OK, result2.TxResult.Code, idx) - // time to verify the proof - proof := result2.Proof - if tc.prove && assert.Equal(tx, proof.Data, idx) { - assert.True(proof.Proof.Verify(proof.Index, proof.Total, tx.Hash(), proof.RootHash), idx) - } - } - } - -} - -//-------------------------------------------------------------------------------- -// Test the websocket service - -var wsTyp = "JSONRPC" - -// make a simple connection to the server -func TestWSConnect(t *testing.T) { - wsc := GetWSClient() - wsc.Stop() -} - -// receive a new block message -func TestWSNewBlock(t *testing.T) { - wsc := GetWSClient() - eid := types.EventStringNewBlock() - require.Nil(t, wsc.Subscribe(eid)) - - defer func() { - require.Nil(t, wsc.Unsubscribe(eid)) - wsc.Stop() - }() - waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error { - // fmt.Println("Check:", b) - return nil - }) -} - -// receive a few new block messages in a row, with increasing height -func TestWSBlockchainGrowth(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - wsc := GetWSClient() - eid := types.EventStringNewBlock() - require.Nil(t, wsc.Subscribe(eid)) - - defer func() { - require.Nil(t, wsc.Unsubscribe(eid)) - wsc.Stop() - }() - - // listen for NewBlock, ensure height increases by 1 - - var initBlockN int - for i := 0; i < 3; i++ { - waitForEvent(t, wsc, eid, true, func() {}, func(eid string, eventData interface{}) error { - block := eventData.(types.TMEventData).Unwrap().(types.EventDataNewBlock).Block - if i == 0 { - initBlockN = block.Header.Height - } else { - if block.Header.Height != initBlockN+i { - return fmt.Errorf("Expected block %d, got block %d", initBlockN+i, block.Header.Height) - } - } - - return nil - }) - } -} - -func TestWSTxEvent(t *testing.T) { - require := require.New(t) - wsc := GetWSClient() - tx := randBytes(t) - - // listen for the tx I am about to submit - eid := types.EventStringTx(types.Tx(tx)) - require.Nil(wsc.Subscribe(eid)) - - defer func() { - require.Nil(wsc.Unsubscribe(eid)) - wsc.Stop() - }() - - // send an tx - result := new(ctypes.ResultBroadcastTx) - _, err := GetJSONClient().Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, result) - require.Nil(err) - - waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error { - evt, ok := b.(types.TMEventData).Unwrap().(types.EventDataTx) - require.True(ok, "Got wrong event type: %#v", b) - require.Equal(tx, []byte(evt.Tx), "Returned different tx") - require.Equal(abci.CodeType_OK, evt.Code) - return nil - }) -} - -/* TODO: this with dummy app.. -func TestWSDoubleFire(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - con := newWSCon(t) - eid := types.EventStringAccInput(user[0].Address) - subscribe(t, con, eid) - defer func() { - unsubscribe(t, con, eid) - con.Close() - }() - amt := int64(100) - toAddr := user[1].Address - // broadcast the transaction, wait to hear about it - waitForEvent(t, con, eid, true, func() { - tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt) - broadcastTx(t, wsTyp, tx) - }, func(eid string, b []byte) error { - return nil - }) - // but make sure we don't hear about it twice - waitForEvent(t, con, eid, false, func() { - }, func(eid string, b []byte) error { - return nil - }) -}*/ diff --git a/rpc/test/grpc_test.go b/rpc/test/grpc_test.go index 4935a09d9..5ca40a3b0 100644 --- a/rpc/test/grpc_test.go +++ b/rpc/test/grpc_test.go @@ -6,15 +6,13 @@ import ( "golang.org/x/net/context" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/rpc/grpc" + core_grpc "github.com/tendermint/tendermint/rpc/grpc" ) -//------------------------------------------- - func TestBroadcastTx(t *testing.T) { require := require.New(t) res, err := GetGRPCClient().BroadcastTx(context.Background(), &core_grpc.RequestBroadcastTx{[]byte("this is a tx")}) - require.Nil(err) + require.Nil(err, "%+v", err) require.EqualValues(0, res.CheckTx.Code) require.EqualValues(0, res.DeliverTx.Code) } diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index 51bb0b8fe..14da15c94 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -1,25 +1,19 @@ package rpctest import ( - "encoding/json" "fmt" "math/rand" "os" "path/filepath" "strings" - "testing" - "time" - "github.com/stretchr/testify/require" "github.com/tendermint/tmlibs/log" abci "github.com/tendermint/abci/types" cfg "github.com/tendermint/tendermint/config" nm "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/proxy" - ctypes "github.com/tendermint/tendermint/rpc/core/types" core_grpc "github.com/tendermint/tendermint/rpc/grpc" - client "github.com/tendermint/tendermint/rpc/lib/client" "github.com/tendermint/tendermint/types" ) @@ -65,32 +59,11 @@ func GetConfig() *cfg.Config { return config } -// GetURIClient gets a uri client pointing to the test tendermint rpc -func GetURIClient() *client.URIClient { - rpcAddr := GetConfig().RPC.ListenAddress - return client.NewURIClient(rpcAddr) -} - -// GetJSONClient gets a http/json client pointing to the test tendermint rpc -func GetJSONClient() *client.JSONRPCClient { - rpcAddr := GetConfig().RPC.ListenAddress - return client.NewJSONRPCClient(rpcAddr) -} - func GetGRPCClient() core_grpc.BroadcastAPIClient { grpcAddr := config.RPC.GRPCListenAddress return core_grpc.StartGRPCClient(grpcAddr) } -func GetWSClient() *client.WSClient { - rpcAddr := GetConfig().RPC.ListenAddress - wsc := client.NewWSClient(rpcAddr, "/websocket") - if _, err := wsc.Start(); err != nil { - panic(err) - } - return wsc -} - // StartTendermint starts a test tendermint server in a go routine and returns when it is initialized func StartTendermint(app abci.Application) *nm.Node { node := NewTendermint(app) @@ -111,68 +84,3 @@ func NewTendermint(app abci.Application) *nm.Node { node := nm.NewNode(config, privValidator, papp, logger) return node } - -//-------------------------------------------------------------------------------- -// Utilities for testing the websocket service - -// wait for an event; do things that might trigger events, and check them when they are received -// the check function takes an event id and the byte slice read off the ws -func waitForEvent(t *testing.T, wsc *client.WSClient, eventid string, dieOnTimeout bool, f func(), check func(string, interface{}) error) { - // go routine to wait for webscoket msg - goodCh := make(chan interface{}) - errCh := make(chan error) - - // Read message - go func() { - var err error - LOOP: - for { - select { - case r := <-wsc.ResultsCh: - result := new(ctypes.ResultEvent) - err = json.Unmarshal(r, result) - if err != nil { - // cant distinguish between error and wrong type ... - continue - } - if result.Name == eventid { - goodCh <- result.Data - break LOOP - } - case err := <-wsc.ErrorsCh: - errCh <- err - break LOOP - case <-wsc.Quit: - break LOOP - } - } - }() - - // do stuff (transactions) - f() - - // wait for an event or timeout - timeout := time.NewTimer(10 * time.Second) - select { - case <-timeout.C: - if dieOnTimeout { - wsc.Stop() - require.True(t, false, "%s event was not received in time", eventid) - } - // else that's great, we didn't hear the event - // and we shouldn't have - case eventData := <-goodCh: - if dieOnTimeout { - // message was received and expected - // run the check - require.Nil(t, check(eventid, eventData)) - } else { - wsc.Stop() - require.True(t, false, "%s event was not expected", eventid) - } - case err := <-errCh: - panic(err) // Show the stack trace. - } -} - -//-------------------------------------------------------------------------------- From df934c1707c64f2752c35ee5068b4ff9716f1920 Mon Sep 17 00:00:00 2001 From: Adrian Brink Date: Mon, 19 Jun 2017 15:46:15 +0200 Subject: [PATCH 14/39] Add Code of Conduct --- CODE_OF_CONDUCT.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++ README.md | 3 +++ 2 files changed, 59 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..d47c0f15e --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,56 @@ +# The Tendermint Code of Conduct +This code of conduct applies to all projects run by the Tendermint/COSMOS team and hence to tendermint. + + +---- + + +# Conduct +## Contact: adrian@tendermint.com + +* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. + +* On Slack, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. + +* Please be kind and courteous. There’s no need to be mean or rude. + +* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. + +* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. + +* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behaviour. We interpret the term “harassment” as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don’t tolerate behavior that excludes people in socially marginalized groups. + +* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel admins or the person mentioned above immediately. Whether you’re a regular contributor or a newcomer, we care about making this community a safe place for you and we’ve got your back. + +* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behaviour is not welcome. + + +---- + + +# Moderation +These are the policies for upholding our community’s standards of conduct. If you feel that a thread needs moderation, please contact the above mentioned person. + +1. Remarks that violate the Tendermint/COSMOS standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) + +2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. + +3. Moderators will first respond to such remarks with a warning. + +4. If the warning is unheeded, the user will be “kicked,” i.e., kicked out of the communication channel to cool off. + +5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. + +6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. + +7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, in private. Complaints about bans in-channel are not allowed. + +8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. + +In the Tendermint/COSMOS community we strive to go the extra step to look out for each other. Don’t just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they’re off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. + +And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could’ve communicated better — remember that it’s your responsibility to make your fellow Cosmonauts comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. + +The enforcement policies listed above apply to all official Tendermint/COSMOS venues.For other projects adopting the Tendermint/COSMOS Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. + +*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling), the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/) and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). diff --git a/README.md b/README.md index d37ef6357..ba99b620e 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,9 @@ For more background, see the [introduction](https://tendermint.com/intro). To get started developing applications, see the [application developers guide](https://tendermint.com/docs/guides/app-development). +### Code of Conduct +Please read, understand and adhere to our [code of conduct](CODE_OF_CONDUCT.md). + ## Install To download pre-built binaries, see our [downloads page](https://tendermint.com/intro/getting-started/download). From aac85a14f0a79b37e87f41b6fb66a39d7131b08b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Thu, 22 Jun 2017 20:56:57 +0200 Subject: [PATCH 15/39] httpDialer accepts no prefix or http:// as tcp:// --- rpc/lib/client/http_client.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/rpc/lib/client/http_client.go b/rpc/lib/client/http_client.go index 12cf793a6..755c3e79c 100644 --- a/rpc/lib/client/http_client.go +++ b/rpc/lib/client/http_client.go @@ -13,7 +13,6 @@ import ( "github.com/pkg/errors" types "github.com/tendermint/tendermint/rpc/lib/types" - cmn "github.com/tendermint/tmlibs/common" ) // HTTPClient is a common interface for JSONRPCClient and URIClient. @@ -23,13 +22,23 @@ type HTTPClient interface { // TODO: Deprecate support for IP:PORT or /path/to/socket func makeHTTPDialer(remoteAddr string) (string, func(string, string) (net.Conn, error)) { - parts := strings.SplitN(remoteAddr, "://", 2) var protocol, address string - if len(parts) != 2 { - cmn.PanicSanity(fmt.Sprintf("Expected fully formed listening address, including the tcp:// or unix:// prefix, given %s", remoteAddr)) - } else { + if len(parts) == 1 { + // default to tcp if nothing specified + protocol, address = "tcp", remoteAddr + } else if len(parts) == 2 { protocol, address = parts[0], parts[1] + } else { + // return a invalid message + msg := fmt.Sprintf("Invalid addr: %s", remoteAddr) + return msg, func(_ string, _ string) (net.Conn, error) { + return nil, errors.New(msg) + } + } + // accept http as an alias for tcp + if protocol == "http" { + protocol = "tcp" } trimmedAddress := strings.Replace(address, "/", ".", -1) // replace / with . for http requests (dummy domain) From 3c0128a680023324c3c936be8a0f10d76c8b6f33 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 23 Jun 2017 21:36:47 -0400 Subject: [PATCH 16/39] undo some megacheck suggestions --- blockchain/pool.go | 10 +++++----- blockchain/reactor.go | 3 +-- consensus/state.go | 20 ++++++++++---------- p2p/connection.go | 6 +++--- state/execution.go | 4 ++-- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/blockchain/pool.go b/blockchain/pool.go index 49e255883..a95589987 100644 --- a/blockchain/pool.go +++ b/blockchain/pool.go @@ -212,9 +212,9 @@ func (pool *BlockPool) AddBlock(peerID string, block *types.Block, blockSize int pool.numPending-- peer := pool.peers[peerID] peer.decrPending(blockSize) - } // else { - // Bad peer? - // } + } else { + // Bad peer? + } } // Sets the peer's alleged blockchain height. @@ -303,7 +303,7 @@ func (pool *BlockPool) sendTimeout(peerID string) { } // unused by tendermint; left for debugging purposes -/*func (pool *BlockPool) debug() string { +func (pool *BlockPool) debug() string { pool.mtx.Lock() // Lock defer pool.mtx.Unlock() @@ -317,7 +317,7 @@ func (pool *BlockPool) sendTimeout(peerID string) { } } return str -}*/ +} //------------------------------------- diff --git a/blockchain/reactor.go b/blockchain/reactor.go index 670396b02..8e8b49403 100644 --- a/blockchain/reactor.go +++ b/blockchain/reactor.go @@ -132,8 +132,7 @@ func (bcR *BlockchainReactor) Receive(chID byte, src *p2p.Peer, msgBytes []byte) bcR.Logger.Debug("Receive", "src", src, "chID", chID, "msg", msg) - // [zr] note: the `megacheck` tool (go vet on steroids) - // really dislikes the logic in this switch + // TODO: improve logic to satisfy megacheck switch msg := msg.(type) { case *bcBlockRequestMessage: // Got a request for a block. Respond with block if we have it. diff --git a/consensus/state.go b/consensus/state.go index 9d9c75851..c398eb312 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -649,9 +649,9 @@ func (cs *ConsensusState) handleMsg(mi msgInfo, rs RoundState) { // attempt to add the vote and dupeout the validator if its a duplicate signature // if the vote gives us a 2/3-any or 2/3-one, we transition _ = cs.tryAddVote(msg.Vote, peerKey) - //if err == ErrAddingVote { - // TODO: punish peer - //} + if err == ErrAddingVote { + // TODO: punish peer + } // NOTE: the vote is broadcast to peers by the reactor listening // for vote events @@ -897,10 +897,10 @@ func (cs *ConsensusState) enterPrevote(height int, round int) { // fire event for how we got here if cs.isProposalComplete() { types.FireEventCompleteProposal(cs.evsw, cs.RoundStateEvent()) - } // else { - // we received +2/3 prevotes for a future round - // TODO: catchup event? - //} + } else { + // we received +2/3 prevotes for a future round + // TODO: catchup event? + } cs.Logger.Info(cmn.Fmt("enterPrevote(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) @@ -1122,9 +1122,9 @@ func (cs *ConsensusState) enterCommit(height int, commitRound int) { // Set up ProposalBlockParts and keep waiting. cs.ProposalBlock = nil cs.ProposalBlockParts = types.NewPartSetFromHeader(blockID.PartsHeader) - } // else { - // We just need to keep waiting. - //} + } else { + // We just need to keep waiting. + } } } diff --git a/p2p/connection.go b/p2p/connection.go index 1e3da1778..e167c7740 100644 --- a/p2p/connection.go +++ b/p2p/connection.go @@ -366,9 +366,9 @@ func (c *MConnection) sendMsgPacket() bool { // Nothing to send? if leastChannel == nil { return true - } // else { - // c.Logger.Info("Found a msgPacket to send") - //} + } else { + // c.Logger.Info("Found a msgPacket to send") + } // Make & send a msgPacket from this channel n, err := leastChannel.writeMsgPacketTo(c.bufWriter) diff --git a/state/execution.go b/state/execution.go index 2a64f1885..768a0b1de 100644 --- a/state/execution.go +++ b/state/execution.go @@ -157,7 +157,7 @@ func updateValidators(validators *types.ValidatorSet, changedValidators []*abci. // return a bit array of validators that signed the last commit // NOTE: assumes commits have already been authenticated -/*func commitBitArrayFromBlock(block *types.Block) *cmn.BitArray { +func commitBitArrayFromBlock(block *types.Block) *cmn.BitArray { signed := cmn.NewBitArray(len(block.LastCommit.Precommits)) for i, precommit := range block.LastCommit.Precommits { if precommit != nil { @@ -165,7 +165,7 @@ func updateValidators(validators *types.ValidatorSet, changedValidators []*abci. } } return signed -}*/ +} //----------------------------------------------------- // Validate block From 468982ffe4012f02bbef6024e4970cce9c61c571 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 23 Jun 2017 22:12:45 -0400 Subject: [PATCH 17/39] fixes --- consensus/replay.go | 3 --- consensus/state.go | 2 +- glide.lock | 26 +++++++++++++------------- glide.yaml | 2 +- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/consensus/replay.go b/consensus/replay.go index f14fa42f0..c4ed684c7 100644 --- a/consensus/replay.go +++ b/consensus/replay.go @@ -104,9 +104,6 @@ func (cs *ConsensusState) catchupReplay(csHeight int) error { // NOTE: This is just a sanity check. As far as we know things work fine without it, // and Handshake could reuse ConsensusState if it weren't for this check (since we can crash after writing ENDHEIGHT). gr, found, err := cs.wal.group.Search("#ENDHEIGHT: ", makeHeightSearchFunc(csHeight)) - if err != nil { - return err - } if gr != nil { gr.Close() } diff --git a/consensus/state.go b/consensus/state.go index 86111cc14..5a4737733 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -648,7 +648,7 @@ func (cs *ConsensusState) handleMsg(mi msgInfo, rs RoundState) { case *VoteMessage: // attempt to add the vote and dupeout the validator if its a duplicate signature // if the vote gives us a 2/3-any or 2/3-one, we transition - _ = cs.tryAddVote(msg.Vote, peerKey) + err := cs.tryAddVote(msg.Vote, peerKey) if err == ErrAddingVote { // TODO: punish peer } diff --git a/glide.lock b/glide.lock index 575f6a33f..592df5a97 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 74281881f3abf6e6c95e5aa5fe15e1891298c985f6c0584e658c8a03b4a5f7e1 -updated: 2017-06-12T15:23:33.311059702Z +hash: 7b6edafcc8b8aad7c697bf745121afa3ae37402d8ae3e8f6193d1fabed619997 +updated: 2017-06-23T22:11:01.311106426-04:00 imports: - name: github.com/btcsuite/btcd version: b8df516b4b267acf2de46be593a9d948d1d2c420 @@ -7,10 +7,6 @@ imports: - btcec - name: github.com/btcsuite/fastsha256 version: 637e656429416087660c84436a2a035d69d54e2e -- name: github.com/davecgh/go-spew - version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 - subpackages: - - spew - name: github.com/ebuchman/fail-test version: 95f809107225be108efcf10a3509e4ea6ceef3c4 - name: github.com/fsnotify/fsnotify @@ -65,10 +61,6 @@ imports: version: 5c26a6ff6fd178719e15decac1c8196da0d7d6d1 - name: github.com/pkg/errors version: ff09b135c25aae272398c51a07235b90a75aa4f0 -- name: github.com/pmezard/go-difflib - version: d8ed2627bdf02c080bf22230dbb337003b7aba2d - subpackages: - - difflib - name: github.com/spf13/afero version: 9be650865eab0c12963d8753212f4f9c66cdcf12 subpackages: @@ -124,14 +116,14 @@ imports: - data - data/base58 - name: github.com/tendermint/merkleeyes - version: feb2c3fadac8221f96fbfce65a63af034327f972 + version: ce7de05896f560ddcc9207f65fea9901835dd238 subpackages: - app - client - iavl - testutil - name: github.com/tendermint/tmlibs - version: 6b619742ac69388dd591c30f55aaee46197b086e + version: 7ce4da1eee6004d627e780c8fe91e96d9b99e459 subpackages: - autofile - cli @@ -198,4 +190,12 @@ imports: - transport - name: gopkg.in/yaml.v2 version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b -testImports: [] +testImports: +- name: github.com/davecgh/go-spew + version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 + subpackages: + - spew +- name: github.com/pmezard/go-difflib + version: d8ed2627bdf02c080bf22230dbb337003b7aba2d + subpackages: + - difflib diff --git a/glide.yaml b/glide.yaml index f36ad9440..a86672e0f 100644 --- a/glide.yaml +++ b/glide.yaml @@ -27,7 +27,7 @@ import: subpackages: - data - package: github.com/tendermint/tmlibs - version: v0.2.1 + version: v0.2.2 subpackages: - autofile - cli From 77a3d03385c5512777b2749eaead3e243f6eab73 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 23 Jun 2017 22:34:38 -0400 Subject: [PATCH 18/39] blockchain: explain isCaughtUp logic --- blockchain/pool.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/blockchain/pool.go b/blockchain/pool.go index a95589987..48a258c79 100644 --- a/blockchain/pool.go +++ b/blockchain/pool.go @@ -28,7 +28,7 @@ var peerTimeoutSeconds = time.Duration(15) // not const so we can override with Every so often we ask peers what height they're on so we can keep going. Requests are continuously made for blocks of higher heights until - the limits. If most of the requests have no available peers, and we + we reach 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 */ @@ -129,8 +129,6 @@ func (pool *BlockPool) IsCaughtUp() bool { pool.mtx.Lock() defer pool.mtx.Unlock() - height := pool.height - // Need at least 1 peer to be considered caught up. if len(pool.peers) == 0 { pool.Logger.Debug("Blockpool has no peers") @@ -142,8 +140,11 @@ func (pool *BlockPool) IsCaughtUp() bool { maxPeerHeight = MaxInt(maxPeerHeight, peer.height) } - isCaughtUp := (height > 0 || time.Since(pool.startTime) > 5*time.Second) && (maxPeerHeight == 0 || height >= maxPeerHeight) - pool.Logger.Info(Fmt("IsCaughtUp: %v", isCaughtUp), "height", height, "maxPeerHeight", maxPeerHeight) + // 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) return isCaughtUp } From 5c29d7aba93a207e2fae6b07a7bc651adc91ad65 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 24 Jun 2017 21:27:16 -0400 Subject: [PATCH 19/39] rpc/lib: test tcp and unix --- rpc/lib/rpc_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/lib/rpc_test.go b/rpc/lib/rpc_test.go index c7bed052f..a79a5270e 100644 --- a/rpc/lib/rpc_test.go +++ b/rpc/lib/rpc_test.go @@ -245,11 +245,11 @@ func TestServersAndClientsBasic(t *testing.T) { fmt.Printf("=== testing server on %s using %v client", addr, cl1) testWithHTTPClient(t, cl1) - cl2 := client.NewJSONRPCClient(tcpAddr) + cl2 := client.NewJSONRPCClient(addr) fmt.Printf("=== testing server on %s using %v client", addr, cl2) testWithHTTPClient(t, cl2) - cl3 := client.NewWSClient(tcpAddr, websocketEndpoint) + cl3 := client.NewWSClient(addr, websocketEndpoint) _, err := cl3.Start() require.Nil(t, err) fmt.Printf("=== testing server on %s using %v client", addr, cl3) From b6031d5f4b34de64cb0fba82fad49632d61ae8b5 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 24 Jun 2017 21:55:31 -0400 Subject: [PATCH 20/39] rpc/lib: set logger on ws conn --- rpc/lib/server/handlers.go | 1 + 1 file changed, 1 insertion(+) diff --git a/rpc/lib/server/handlers.go b/rpc/lib/server/handlers.go index a3dad8cdf..bafc88546 100644 --- a/rpc/lib/server/handlers.go +++ b/rpc/lib/server/handlers.go @@ -597,6 +597,7 @@ func (wm *WebsocketManager) WebsocketHandler(w http.ResponseWriter, r *http.Requ // register connection con := NewWSConnection(wsConn, wm.funcMap, wm.evsw) + con.SetLogger(wm.logger) wm.logger.Info("New websocket connection", "remote", con.remoteAddr) con.Start() // Blocking } From 10828ad063973839e867da6744751c70febbb6d4 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 24 Jun 2017 22:55:48 -0400 Subject: [PATCH 21/39] changelog --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cf90ba87..45b93b342 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 0.10.1 (TBD) + +FEATURES: +- Use `--trace` to get stack traces for logged errors + +IMPROVEMENTS: +- Add a Code of Conduct +- Variety of improvements as suggested by `megacheck` tool +- rpc: deduplicate tests between rpc/client and rpc/tests +- rpc: addresses without a protocol prefix default to `tcp://`. `http://` is also accepted as an alias for `tcp://` + +BUG FIXES: +- Fix log statements using keys with spaces (logger does not currently support spaces) +- rpc: set logger on websocket connection + ## 0.10.0 (June 2, 2017) Includes major updates to configuration, logging, and json serialization. From 4f5b6528a1e5b5b4e6848cebccb3ec1a3c9e4ed9 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 24 Jun 2017 22:56:31 -0400 Subject: [PATCH 22/39] version bump --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index 494b6a895..e77f0e40c 100644 --- a/version/version.go +++ b/version/version.go @@ -2,11 +2,11 @@ package version const Maj = "0" const Min = "10" -const Fix = "0" +const Fix = "1" var ( // The full version string - Version = "0.10.0" + Version = "0.10.1" // GitCommit is set with --ldflags "-X main.gitCommit=$(git rev-parse HEAD)" GitCommit string From e2fe4a6e9b4c9205dfc0bdf1c7d17b3b491fd951 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 26 Jun 2017 10:57:46 +0400 Subject: [PATCH 23/39] [docker] bump alpine version [ci skip] --- DOCKER/Dockerfile | 2 +- DOCKER/Dockerfile.develop | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DOCKER/Dockerfile b/DOCKER/Dockerfile index 09b25f732..98a1db4e7 100644 --- a/DOCKER/Dockerfile +++ b/DOCKER/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.5 +FROM alpine:3.6 # This is the release of tendermint to pull in. ENV TM_VERSION 0.10.0 diff --git a/DOCKER/Dockerfile.develop b/DOCKER/Dockerfile.develop index 82cd884ae..2ffb68281 100644 --- a/DOCKER/Dockerfile.develop +++ b/DOCKER/Dockerfile.develop @@ -1,4 +1,4 @@ -FROM alpine:3.5 +FROM alpine:3.6 ENV DATA_ROOT /tendermint ENV TMHOME $DATA_ROOT From 24a1b130f9ff32704c5b2d8d508db70123ce60a0 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 26 Jun 2017 10:58:19 +0400 Subject: [PATCH 24/39] [docker] build and push scripts [ci skip] --- DOCKER/Makefile | 8 ++------ DOCKER/build.sh | 20 ++++++++++++++++++++ DOCKER/push.sh | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 6 deletions(-) create mode 100755 DOCKER/build.sh create mode 100755 DOCKER/push.sh diff --git a/DOCKER/Makefile b/DOCKER/Makefile index 612b9a694..10c972502 100644 --- a/DOCKER/Makefile +++ b/DOCKER/Makefile @@ -1,12 +1,8 @@ build: - # TAG=0.8.0 TAG_NO_PATCH=0.8 - docker build -t "tendermint/tendermint" -t "tendermint/tendermint:$(TAG)" -t "tendermint/tendermint:$(TAG_NO_PATCH)" . + @sh -c "'$(CURDIR)/build.sh'" push: - # TAG=0.8.0 TAG_NO_PATCH=0.8 - docker push "tendermint/tendermint:latest" - docker push "tendermint/tendermint:$(TAG)" - docker push "tendermint/tendermint:$(TAG_NO_PATCH)" + @sh -c "'$(CURDIR)/push.sh'" build_develop: docker build -t "tendermint/tendermint:develop" -f Dockerfile.develop . diff --git a/DOCKER/build.sh b/DOCKER/build.sh new file mode 100755 index 000000000..ee617cc63 --- /dev/null +++ b/DOCKER/build.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -e + +# Get the tag from the version, or try to figure it out. +if [ -z "$TAG" ]; then + TAG=$(awk -F\" '/Version =/ { print $2; exit }' < ../version/version.go) +fi +if [ -z "$TAG" ]; then + echo "Please specify a tag." + exit 1 +fi + +TAG_NO_PATCH=${TAG%.*} + +read -p "==> Build 3 docker images with the following tags (latest, $TAG, $TAG_NO_PATCH)? y/n" -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]] +then + docker build -t "tendermint/tendermint" -t "tendermint/tendermint:$TAG" -t "tendermint/tendermint:$TAG_NO_PATCH" . +fi diff --git a/DOCKER/push.sh b/DOCKER/push.sh new file mode 100755 index 000000000..32741dce8 --- /dev/null +++ b/DOCKER/push.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -e + +# Get the tag from the version, or try to figure it out. +if [ -z "$TAG" ]; then + TAG=$(awk -F\" '/Version =/ { print $2; exit }' < ../version/version.go) +fi +if [ -z "$TAG" ]; then + echo "Please specify a tag." + exit 1 +fi + +TAG_NO_PATCH=${TAG%.*} + +read -p "==> Push 3 docker images with the following tags (latest, $TAG, $TAG_NO_PATCH)? y/n" -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]] +then + docker push "tendermint/tendermint:latest" + docker push "tendermint/tendermint:$TAG" + docker push "tendermint/tendermint:$TAG_NO_PATCH" +fi From 9a80730f38b9aa99157bf8f9f3ab3767d25b5bf4 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 26 Jun 2017 11:09:24 +0400 Subject: [PATCH 25/39] [docker] fix link to 0.10.0 Dockerfile [ci skip] --- DOCKER/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCKER/README.md b/DOCKER/README.md index 2bd2b27ea..d8e78396b 100644 --- a/DOCKER/README.md +++ b/DOCKER/README.md @@ -1,6 +1,6 @@ # Supported tags and respective `Dockerfile` links -- `0.10.0`, `latest` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/v0.10.0/DOCKER/Dockerfile) +- `0.10.0`, `latest` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/e5342f4054ab784b2cd6150e14f01053d7c8deb2/DOCKER/Dockerfile) - `0.9.1`, `0.9`, [(Dockerfile)](https://github.com/tendermint/tendermint/blob/809e0e8c5933604ba8b2d096803ada7c5ec4dfd3/DOCKER/Dockerfile) - `0.9.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/d474baeeea6c22b289e7402449572f7c89ee21da/DOCKER/Dockerfile) - `0.8.0`, `0.8` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/bf64dd21fdb193e54d8addaaaa2ecf7ac371de8c/DOCKER/Dockerfile) From 852375be00debf61577d4eb54146c37fecc497e9 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 26 Jun 2017 11:17:50 +0400 Subject: [PATCH 26/39] [docker] update link to mintnet-k8s [ci skip] --- DOCKER/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCKER/README.md b/DOCKER/README.md index d8e78396b..b3afa481d 100644 --- a/DOCKER/README.md +++ b/DOCKER/README.md @@ -29,7 +29,7 @@ docker run -it --rm -v "/tmp:/tendermint" tendermint/tendermint ## mintnet-kubernetes -If you want to see many containers talking to each other, consider using [mintnet-kubernetes](https://github.com/tendermint/mintnet-kubernetes), which is a tool for running Tendermint-based applications on a Kubernetes cluster. +If you want to see many containers talking to each other, consider using [mintnet-kubernetes](https://github.com/tendermint/tools/tree/master/mintnet-kubernetes), which is a tool for running Tendermint-based applications on a Kubernetes cluster. # Supported Docker versions From aa7b3a73f52fca7a7332b8977a6570a9651cd646 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 26 Jun 2017 12:05:08 +0400 Subject: [PATCH 27/39] [docker] remove dummy app as default [ci skip] --- DOCKER/Dockerfile | 3 +-- DOCKER/README.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/DOCKER/Dockerfile b/DOCKER/Dockerfile index 98a1db4e7..55f2e14ab 100644 --- a/DOCKER/Dockerfile +++ b/DOCKER/Dockerfile @@ -42,5 +42,4 @@ EXPOSE 46657 ENTRYPOINT ["tendermint"] -# By default you'll get the dummy app -CMD ["node", "--moniker=`hostname`", "--proxy_app=dummy"] +CMD ["node", "--moniker=`hostname`"] diff --git a/DOCKER/README.md b/DOCKER/README.md index b3afa481d..e191abc39 100644 --- a/DOCKER/README.md +++ b/DOCKER/README.md @@ -24,7 +24,7 @@ A very simple example of a built-in app and Tendermint core in one container. ``` docker run -it --rm -v "/tmp:/tendermint" tendermint/tendermint init -docker run -it --rm -v "/tmp:/tendermint" tendermint/tendermint +docker run -it --rm -v "/tmp:/tendermint" tendermint/tendermint node --proxy_app=dummy ``` ## mintnet-kubernetes From d0b1bf4e26b6aadb2fc9dc04cf28cfc8a70246f6 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 26 Jun 2017 12:08:38 +0400 Subject: [PATCH 28/39] [docker] bump golang version to 1.8.3 --- scripts/tendermint-builder/Dockerfile | 2 +- test/docker/Dockerfile | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/tendermint-builder/Dockerfile b/scripts/tendermint-builder/Dockerfile index 84c198ee0..daf931715 100644 --- a/scripts/tendermint-builder/Dockerfile +++ b/scripts/tendermint-builder/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.7.4 +FROM golang:1.8.3 RUN apt-get update && apt-get install -y --no-install-recommends \ zip \ diff --git a/test/docker/Dockerfile b/test/docker/Dockerfile index 7c322976d..8a2702fc8 100644 --- a/test/docker/Dockerfile +++ b/test/docker/Dockerfile @@ -1,5 +1,4 @@ -# Pull base image. -FROM golang:1.7.4 +FROM golang:1.8.3 # Add testing deps for curl RUN echo 'deb http://httpredir.debian.org/debian testing main non-free contrib' >> /etc/apt/sources.list @@ -9,7 +8,7 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends \ jq bsdmainutils vim-common psmisc netcat curl -# Setup tendermint repo +# Setup tendermint repo ENV REPO $GOPATH/src/github.com/tendermint/tendermint WORKDIR $REPO From 58105dbd4e438bf43892a44c5bccf84726df56db Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 23 Jun 2017 17:16:03 +0200 Subject: [PATCH 29/39] Refactored some commands to be more reusable --- cmd/tendermint/commands/root.go | 18 +++++++-- cmd/tendermint/commands/run_node.go | 57 ++++++++++++++++++----------- 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go index a02cd92bd..a63d9e46b 100644 --- a/cmd/tendermint/commands/root.go +++ b/cmd/tendermint/commands/root.go @@ -21,16 +21,26 @@ func init() { RootCmd.PersistentFlags().String("log_level", config.LogLevel, "Log level") } +// ParseConfig will setup the tendermint configuration properly +func ParseConfig() (*cfg.Config, error) { + conf := cfg.DefaultConfig() + err := viper.Unmarshal(conf) + if err != nil { + return nil, err + } + conf.SetRoot(conf.RootDir) + cfg.EnsureRoot(conf.RootDir) + return conf, err +} + var RootCmd = &cobra.Command{ Use: "tendermint", Short: "Tendermint Core (BFT Consensus) in Go", - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - err := viper.Unmarshal(config) + PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { + config, err = ParseConfig() if err != nil { return err } - config.SetRoot(config.RootDir) - cfg.EnsureRoot(config.RootDir) logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel()) if err != nil { return err diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go index d476ccd57..fd05abe5b 100644 --- a/cmd/tendermint/commands/run_node.go +++ b/cmd/tendermint/commands/run_node.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "time" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/tendermint/tendermint/node" @@ -19,28 +20,49 @@ var runNodeCmd = &cobra.Command{ } func init() { + AddNodeFlags(runNodeCmd) + RootCmd.AddCommand(runNodeCmd) +} + +// AddNodeFlags exposes some common configuration options on the command-line +// These are exposed for convenience of commands embedding a tendermint node +func AddNodeFlags(cmd *cobra.Command) { // bind flags - runNodeCmd.Flags().String("moniker", config.Moniker, "Node Name") + cmd.Flags().String("moniker", config.Moniker, "Node Name") // node flags - runNodeCmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing") + cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing") // abci flags - runNodeCmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'dummy' for local testing.") - runNodeCmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)") + cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'dummy' for local testing.") + cmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)") // rpc flags - runNodeCmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") - runNodeCmd.Flags().String("rpc.grpc_laddr", config.RPC.GRPCListenAddress, "GRPC listen address (BroadcastTx only). Port required") - runNodeCmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "Enabled unsafe rpc methods") + cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") + cmd.Flags().String("rpc.grpc_laddr", config.RPC.GRPCListenAddress, "GRPC listen address (BroadcastTx only). Port required") + cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "Enabled unsafe rpc methods") // p2p flags - runNodeCmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)") - runNodeCmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma delimited host:port seed nodes") - runNodeCmd.Flags().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration") - runNodeCmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable Peer-Exchange (dev feature)") + cmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)") + cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma delimited host:port seed nodes") + cmd.Flags().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration") + cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable Peer-Exchange (dev feature)") +} - RootCmd.AddCommand(runNodeCmd) +func ParseGenesisFile() (*types.GenesisDoc, error) { + genDocFile := config.GenesisFile() + jsonBlob, err := ioutil.ReadFile(genDocFile) + if err != nil { + return nil, errors.Wrap(err, "Couldn't read GenesisDoc file") + } + genDoc, err := types.GenesisDocFromJSON(jsonBlob) + if err != nil { + return nil, errors.Wrap(err, "Error reading GenesisDoc") + } + if genDoc.ChainID == "" { + return nil, errors.Errorf("Genesis doc %v must include non-empty chain_id", genDocFile) + } + return genDoc, nil } // Users wishing to: @@ -63,16 +85,9 @@ func runNode(cmd *cobra.Command, args []string) error { if !cmn.FileExists(genDocFile) { continue } - jsonBlob, err := ioutil.ReadFile(genDocFile) + genDoc, err := ParseGenesisFile() if err != nil { - return fmt.Errorf("Couldn't read GenesisDoc file: %v", err) - } - genDoc, err := types.GenesisDocFromJSON(jsonBlob) - if err != nil { - return fmt.Errorf("Error reading GenesisDoc: %v", err) - } - if genDoc.ChainID == "" { - return fmt.Errorf("Genesis doc %v must include non-empty chain_id", genDocFile) + return err } config.ChainID = genDoc.ChainID } From 6b38abd57bd9d35b219227552262787076bfdd53 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 23 Jun 2017 17:25:53 +0200 Subject: [PATCH 30/39] Cleanup for loop in genesis file load --- cmd/tendermint/commands/run_node.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go index fd05abe5b..997da4d7a 100644 --- a/cmd/tendermint/commands/run_node.go +++ b/cmd/tendermint/commands/run_node.go @@ -78,21 +78,17 @@ func runNode(cmd *cobra.Command, args []string) error { // TODO: If Mintnet gets deprecated or genesis_file is // always available, remove. genDocFile := config.GenesisFile() - if !cmn.FileExists(genDocFile) { + for !cmn.FileExists(genDocFile) { logger.Info(cmn.Fmt("Waiting for genesis file %v...", genDocFile)) - for { - time.Sleep(time.Second) - if !cmn.FileExists(genDocFile) { - continue - } - genDoc, err := ParseGenesisFile() - if err != nil { - return err - } - config.ChainID = genDoc.ChainID - } + time.Sleep(time.Second) } + genDoc, err := ParseGenesisFile() + if err != nil { + return err + } + config.ChainID = genDoc.ChainID + // Create & start node n := node.NewNodeDefault(config, logger.With("module", "node")) if _, err := n.Start(); err != nil { From 10982f4d8f9422f9e4290aa1a0d226561ec5e439 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 26 Jun 2017 16:56:51 +0200 Subject: [PATCH 31/39] Add argument to ParseGenesis to use in light-client --- cmd/tendermint/commands/run_node.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go index 997da4d7a..ddf67b98f 100644 --- a/cmd/tendermint/commands/run_node.go +++ b/cmd/tendermint/commands/run_node.go @@ -49,8 +49,7 @@ func AddNodeFlags(cmd *cobra.Command) { cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable Peer-Exchange (dev feature)") } -func ParseGenesisFile() (*types.GenesisDoc, error) { - genDocFile := config.GenesisFile() +func ParseGenesisFile(genDocFile string) (*types.GenesisDoc, error) { jsonBlob, err := ioutil.ReadFile(genDocFile) if err != nil { return nil, errors.Wrap(err, "Couldn't read GenesisDoc file") @@ -83,7 +82,7 @@ func runNode(cmd *cobra.Command, args []string) error { time.Sleep(time.Second) } - genDoc, err := ParseGenesisFile() + genDoc, err := ParseGenesisFile(genDocFile) if err != nil { return err } From e4caf96bcb1ab80fc3b5dca4c9a8f0648653929b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 26 Jun 2017 17:06:49 +0200 Subject: [PATCH 32/39] Calculate validator hash from genesis doc --- types/genesis.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/types/genesis.go b/types/genesis.go index 75999f631..721bc098a 100644 --- a/types/genesis.go +++ b/types/genesis.go @@ -39,6 +39,15 @@ func (genDoc *GenesisDoc) SaveAs(file string) error { return cmn.WriteFile(file, genDocBytes, 0644) } +func (genDoc *GenesisDoc) ValidatorHash() []byte { + vals := make([]*Validator, len(genDoc.Validators)) + for i, v := range genDoc.Validators { + vals[i] = NewValidator(v.PubKey, v.Amount) + } + vset := NewValidatorSet(vals) + return vset.Hash() +} + //------------------------------------------------------------ // Make genesis state from file From 12c084c8c0fc6446971fc5c47f32769aefa5557c Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 26 Jun 2017 16:16:54 -0400 Subject: [PATCH 33/39] ParseGenesisFile -> types.GenesisDocFromFile --- cmd/tendermint/commands/run_node.go | 19 +------------------ types/genesis.go | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go index ddf67b98f..e99b8609a 100644 --- a/cmd/tendermint/commands/run_node.go +++ b/cmd/tendermint/commands/run_node.go @@ -2,10 +2,8 @@ package commands import ( "fmt" - "io/ioutil" "time" - "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/tendermint/tendermint/node" @@ -49,21 +47,6 @@ func AddNodeFlags(cmd *cobra.Command) { cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable Peer-Exchange (dev feature)") } -func ParseGenesisFile(genDocFile string) (*types.GenesisDoc, error) { - jsonBlob, err := ioutil.ReadFile(genDocFile) - if err != nil { - return nil, errors.Wrap(err, "Couldn't read GenesisDoc file") - } - genDoc, err := types.GenesisDocFromJSON(jsonBlob) - if err != nil { - return nil, errors.Wrap(err, "Error reading GenesisDoc") - } - if genDoc.ChainID == "" { - return nil, errors.Errorf("Genesis doc %v must include non-empty chain_id", genDocFile) - } - return genDoc, nil -} - // Users wishing to: // * Use an external signer for their validators // * Supply an in-proc abci app @@ -82,7 +65,7 @@ func runNode(cmd *cobra.Command, args []string) error { time.Sleep(time.Second) } - genDoc, err := ParseGenesisFile(genDocFile) + genDoc, err := types.GenesisDocFromFile(genDocFile) if err != nil { return err } diff --git a/types/genesis.go b/types/genesis.go index 721bc098a..8698dacb3 100644 --- a/types/genesis.go +++ b/types/genesis.go @@ -2,8 +2,11 @@ package types import ( "encoding/json" + "io/ioutil" "time" + "github.com/pkg/errors" + "github.com/tendermint/go-crypto" "github.com/tendermint/go-wire/data" cmn "github.com/tendermint/tmlibs/common" @@ -51,8 +54,25 @@ func (genDoc *GenesisDoc) ValidatorHash() []byte { //------------------------------------------------------------ // Make genesis state from file +// GenesisDocFromJSON unmarshalls JSON data into a GenesisDoc. func GenesisDocFromJSON(jsonBlob []byte) (*GenesisDoc, error) { genDoc := GenesisDoc{} err := json.Unmarshal(jsonBlob, &genDoc) return &genDoc, err } + +// GenesisDocFromFile reads JSON data from a file and unmarshalls it into a GenesisDoc. +func GenesisDocFromFile(genDocFile string) (*GenesisDoc, error) { + jsonBlob, err := ioutil.ReadFile(genDocFile) + if err != nil { + return nil, errors.Wrap(err, "Couldn't read GenesisDoc file") + } + genDoc, err := GenesisDocFromJSON(jsonBlob) + if err != nil { + return nil, errors.Wrap(err, "Error reading GenesisDoc") + } + if genDoc.ChainID == "" { + return nil, errors.Errorf("Genesis doc %v must include non-empty chain_id", genDocFile) + } + return genDoc, nil +} From e2ed15fa02e684ff07f094b7c325996a34929ccb Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 26 Jun 2017 17:12:52 -0400 Subject: [PATCH 34/39] rpc: SetWriteDeadline for ws ping. fixes #553 --- rpc/lib/server/handlers.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rpc/lib/server/handlers.go b/rpc/lib/server/handlers.go index bafc88546..1538f08a7 100644 --- a/rpc/lib/server/handlers.go +++ b/rpc/lib/server/handlers.go @@ -510,7 +510,10 @@ func (wsc *wsConnection) readRoutine() { continue } returns := rpcFunc.f.Call(args) - wsc.Logger.Info("WSJSONRPC", "method", request.Method, "args", args, "returns", returns) + + // TODO: Need to encode args/returns to string if we want to log them + wsc.Logger.Info("WSJSONRPC", "method", request.Method) + result, err := unreflectResult(returns) if err != nil { wsc.WriteRPCResponse(types.NewRPCResponse(request.ID, nil, err.Error())) @@ -532,6 +535,7 @@ func (wsc *wsConnection) writeRoutine() { case <-wsc.Quit: return case <-wsc.pingTicker.C: + wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds)) err := wsc.baseConn.WriteMessage(websocket.PingMessage, []byte{}) if err != nil { wsc.Logger.Error("Failed to write ping message on websocket", "err", err) From 3065059da7bb57714f08c7a6fcb97e4b36be0194 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 26 Jun 2017 17:20:27 -0400 Subject: [PATCH 35/39] update changelog --- CHANGELOG.md | 6 +++++- types/genesis.go | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b93b342..7c14c2f79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,17 +3,21 @@ ## 0.10.1 (TBD) FEATURES: -- Use `--trace` to get stack traces for logged errors +- types: GenesisDoc.ValidatorHash returns the hash of the genesis validator set +- types: GenesisDocFromFile parses a GenesiDoc from a JSON file IMPROVEMENTS: - Add a Code of Conduct - Variety of improvements as suggested by `megacheck` tool - rpc: deduplicate tests between rpc/client and rpc/tests - rpc: addresses without a protocol prefix default to `tcp://`. `http://` is also accepted as an alias for `tcp://` +- cmd: commands are more easily reuseable from other tools +- DOCKER: automate build/push BUG FIXES: - Fix log statements using keys with spaces (logger does not currently support spaces) - rpc: set logger on websocket connection +- rpc: fix ws connection stability by setting write deadline on pings ## 0.10.0 (June 2, 2017) diff --git a/types/genesis.go b/types/genesis.go index 8698dacb3..23b14c9e9 100644 --- a/types/genesis.go +++ b/types/genesis.go @@ -20,12 +20,14 @@ var GenDocKey = []byte("GenDocKey") //------------------------------------------------------------ // core types for a genesis definition +// GenesisValidator is an initial validator. type GenesisValidator struct { PubKey crypto.PubKey `json:"pub_key"` Amount int64 `json:"amount"` Name string `json:"name"` } +// GenesisDoc defines the initial conditions for a tendermint blockchain, in particular its validator set. type GenesisDoc struct { GenesisTime time.Time `json:"genesis_time"` ChainID string `json:"chain_id"` @@ -33,7 +35,7 @@ type GenesisDoc struct { AppHash data.Bytes `json:"app_hash"` } -// Utility method for saving GenensisDoc as JSON file. +// SaveAs is a utility method for saving GenensisDoc as a JSON file. func (genDoc *GenesisDoc) SaveAs(file string) error { genDocBytes, err := json.Marshal(genDoc) if err != nil { @@ -42,6 +44,7 @@ func (genDoc *GenesisDoc) SaveAs(file string) error { return cmn.WriteFile(file, genDocBytes, 0644) } +// ValidatorHash returns the hash of the validator set contained in the GenesisDoc func (genDoc *GenesisDoc) ValidatorHash() []byte { vals := make([]*Validator, len(genDoc.Validators)) for i, v := range genDoc.Validators { From b284d39e055d501f2064b09217efa022867d9d72 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 26 Jun 2017 17:29:39 -0400 Subject: [PATCH 36/39] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c14c2f79..5181f1746 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 0.10.1 (TBD) FEATURES: +- Use `--trace` to get stack traces for logged errors - types: GenesisDoc.ValidatorHash returns the hash of the genesis validator set - types: GenesisDocFromFile parses a GenesiDoc from a JSON file From bfecb5a1352a7128d127449ce2016701f46b8ba0 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 27 Jun 2017 16:05:21 -0400 Subject: [PATCH 37/39] some fixes from review --- CHANGELOG.md | 2 +- glide.yaml | 2 +- state/txindex/kv/kv_test.go | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5181f1746..850721728 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.10.1 (TBD) +## 0.10.1 (June 28, 2017) FEATURES: - Use `--trace` to get stack traces for logged errors diff --git a/glide.yaml b/glide.yaml index a86672e0f..705079ceb 100644 --- a/glide.yaml +++ b/glide.yaml @@ -49,7 +49,7 @@ import: - package: google.golang.org/grpc testImport: - package: github.com/tendermint/merkleeyes - version: develop + version: v0.2.4 subpackages: - app - iavl diff --git a/state/txindex/kv/kv_test.go b/state/txindex/kv/kv_test.go index 734a17b3e..903189c2b 100644 --- a/state/txindex/kv/kv_test.go +++ b/state/txindex/kv/kv_test.go @@ -45,14 +45,17 @@ func benchmarkTxIndex(txsCount int, b *testing.B) { batch := txindex.NewBatch(txsCount) for i := 0; i < txsCount; i++ { - txResult.Index += 1 batch.Add(*txResult) + txResult.Index += 1 } b.ResetTimer() for n := 0; n < b.N; n++ { - _ = indexer.AddBatch(batch) + err = indexer.AddBatch(batch) + } + if err != nil { + b.Fatal(err) } } From 2e0a4aafa7c2d9a7d855b93adf0b63f1fe2eed76 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 28 Jun 2017 13:05:51 +0200 Subject: [PATCH 38/39] Update glide files to proper versions --- glide.lock | 22 +++++++++++----------- glide.yaml | 26 +++++++++++++++----------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/glide.lock b/glide.lock index 592df5a97..c1bf21c14 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 7b6edafcc8b8aad7c697bf745121afa3ae37402d8ae3e8f6193d1fabed619997 -updated: 2017-06-23T22:11:01.311106426-04:00 +hash: 2c988aae9517b386ee911e4da5deb9f5034359b7e2ccf448952a3ddb9771222d +updated: 2017-06-28T13:04:20.907047164+02:00 imports: - name: github.com/btcsuite/btcd version: b8df516b4b267acf2de46be593a9d948d1d2c420 @@ -58,9 +58,9 @@ imports: - name: github.com/pelletier/go-buffruneio version: c37440a7cf42ac63b919c752ca73a85067e05992 - name: github.com/pelletier/go-toml - version: 5c26a6ff6fd178719e15decac1c8196da0d7d6d1 + version: 5ccdfb18c776b740aecaf085c4d9a2779199c279 - name: github.com/pkg/errors - version: ff09b135c25aae272398c51a07235b90a75aa4f0 + version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/spf13/afero version: 9be650865eab0c12963d8753212f4f9c66cdcf12 subpackages: @@ -75,11 +75,6 @@ imports: version: e57e3eeb33f795204c1ca35f56c44f83227c6e66 - name: github.com/spf13/viper version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2 -- name: github.com/stretchr/testify - version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 - subpackages: - - assert - - require - name: github.com/syndtr/goleveldb version: 8c81ea47d4c41a385645e133e15510fc6a2a74b4 subpackages: @@ -109,14 +104,14 @@ imports: - edwards25519 - extra25519 - name: github.com/tendermint/go-crypto - version: 7dff40942a64cdeefefa9446b2d104750b349f8a + version: 95b7c9e09c49b91bfbb71bb63dd514eb55450f16 - name: github.com/tendermint/go-wire version: 5f88da3dbc1a72844e6dfaf274ce87f851d488eb subpackages: - data - data/base58 - name: github.com/tendermint/merkleeyes - version: ce7de05896f560ddcc9207f65fea9901835dd238 + version: 102aaf5a8ffda1846413fb22805a94def2045b9f subpackages: - app - client @@ -199,3 +194,8 @@ testImports: version: d8ed2627bdf02c080bf22230dbb337003b7aba2d subpackages: - difflib +- name: github.com/stretchr/testify + version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 + subpackages: + - assert + - require diff --git a/glide.yaml b/glide.yaml index 705079ceb..9bf95b508 100644 --- a/glide.yaml +++ b/glide.yaml @@ -7,13 +7,13 @@ import: - package: github.com/golang/protobuf subpackages: - proto +- package: github.com/pelletier/go-toml + version: ^1.0.0 - package: github.com/gorilla/websocket - package: github.com/pkg/errors + version: ~0.8.0 - package: github.com/spf13/cobra - package: github.com/spf13/viper -- package: github.com/stretchr/testify - subpackages: - - require - package: github.com/tendermint/abci version: v0.5.0 subpackages: @@ -21,13 +21,19 @@ import: - example/dummy - types - package: github.com/tendermint/go-crypto - version: v0.2.0 + version: ~0.2.2 - package: github.com/tendermint/go-wire - version: v0.6.2 + version: ~0.6.2 subpackages: - data +- package: github.com/tendermint/merkleeyes + version: ~0.2.4 + subpackages: + - app + - iavl + - testutil - package: github.com/tendermint/tmlibs - version: v0.2.2 + version: ~0.2.2 subpackages: - autofile - cli @@ -48,9 +54,7 @@ import: - context - package: google.golang.org/grpc testImport: -- package: github.com/tendermint/merkleeyes - version: v0.2.4 +- package: github.com/stretchr/testify subpackages: - - app - - iavl - - testutil + - assert + - require From 0d1fa8e8842250b7e4e850c553118e95c5a10978 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 28 Jun 2017 11:12:45 -0400 Subject: [PATCH 39/39] fixes from review --- blockchain/pool.go | 2 +- consensus/common.go | 6 ++++++ consensus/state.go | 2 +- consensus/state_test.go | 15 ++++----------- p2p/switch.go | 2 +- rpc/lib/server/handlers.go | 15 ++++++++++----- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/blockchain/pool.go b/blockchain/pool.go index 48a258c79..e1288c9fa 100644 --- a/blockchain/pool.go +++ b/blockchain/pool.go @@ -28,7 +28,7 @@ var peerTimeoutSeconds = time.Duration(15) // not const so we can override with Every so often we ask peers what height they're on so we can keep going. Requests are continuously made for blocks of higher heights until - we reach the limits. If most of the requests have no available peers, and we + the limit is reached. If most of the requests have no available peers, and we are not at peer limits, we can probably switch to consensus reactor */ diff --git a/consensus/common.go b/consensus/common.go index 6f76d1887..1e16c4dab 100644 --- a/consensus/common.go +++ b/consensus/common.go @@ -27,3 +27,9 @@ func subscribeToEventRespond(evsw types.EventSwitch, receiver, eventID string) c }) return ch } + +func discardFromChan(ch chan interface{}, n int) { + for i := 0; i < n; i++ { + <-ch + } +} diff --git a/consensus/state.go b/consensus/state.go index 5a4737733..cc9cd51e7 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -1357,7 +1357,7 @@ func (cs *ConsensusState) tryAddVote(vote *types.Vote, peerKey string) error { //----------------------------------------------------------------------------- func (cs *ConsensusState) addVote(vote *types.Vote, peerKey string) (added bool, err error) { - cs.Logger.Debug("addVote", "voteHeight", vote.Height, "voteType", vote.Type, "csHeight", cs.Height) + cs.Logger.Debug("addVote", "voteHeight", vote.Height, "voteType", vote.Type, "valIndex", vote.ValidatorIndex, "csHeight", cs.Height) // A precommit for the previous height? // These come in while we wait timeoutCommit diff --git a/consensus/state_test.go b/consensus/state_test.go index ee88ac258..81ef016be 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -524,9 +524,7 @@ func TestLockPOLRelock(t *testing.T) { signAddVotes(cs1, types.VoteTypePrevote, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vs2, vs3, vs4) // prevotes - <-voteCh - <-voteCh - <-voteCh + discardFromChan(voteCh, 3) <-voteCh // our precommit // the proposed block should now be locked and our precommit added @@ -536,9 +534,7 @@ func TestLockPOLRelock(t *testing.T) { signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2, vs4) signAddVotes(cs1, types.VoteTypePrecommit, cs1.ProposalBlock.Hash(), cs1.ProposalBlockParts.Header(), vs3) // precommites - <-voteCh - <-voteCh - <-voteCh + discardFromChan(voteCh, 3) // before we timeout to the new round set the new proposal prop, propBlock := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) @@ -577,9 +573,7 @@ func TestLockPOLRelock(t *testing.T) { // now lets add prevotes from everyone else for the new block signAddVotes(cs1, types.VoteTypePrevote, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) // prevotes - <-voteCh - <-voteCh - <-voteCh + discardFromChan(voteCh, 3) // now either we go to PrevoteWait or Precommit select { @@ -594,8 +588,7 @@ func TestLockPOLRelock(t *testing.T) { validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash) signAddVotes(cs1, types.VoteTypePrecommit, propBlockHash, propBlockParts.Header(), vs2, vs3) - <-voteCh - <-voteCh + discardFromChan(voteCh, 2) be := <-newBlockCh b := be.(types.TMEventData).Unwrap().(types.EventDataNewBlockHeader) diff --git a/p2p/switch.go b/p2p/switch.go index 2e9d213df..2d8d34357 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -381,7 +381,7 @@ func (sw *Switch) Peers() IPeerSet { // TODO: make record depending on reason. func (sw *Switch) StopPeerForError(peer *Peer, reason interface{}) { addr := NewNetAddress(peer.Addr()) - sw.Logger.Info("Stopping peer for error", "peer", peer, "err", reason) + sw.Logger.Error("Stopping peer for error", "peer", peer, "err", reason) sw.stopAndRemovePeer(peer, reason) if peer.IsPersistent() { diff --git a/rpc/lib/server/handlers.go b/rpc/lib/server/handlers.go index 1538f08a7..b6431a1ec 100644 --- a/rpc/lib/server/handlers.go +++ b/rpc/lib/server/handlers.go @@ -338,7 +338,7 @@ func nonJsonToArg(ty reflect.Type, arg string) (reflect.Value, error, bool) { const ( writeChanCapacity = 1000 - wsWriteTimeoutSeconds = 30 // each write times out after this + 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. ) @@ -535,8 +535,7 @@ func (wsc *wsConnection) writeRoutine() { case <-wsc.Quit: return case <-wsc.pingTicker.C: - wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds)) - err := wsc.baseConn.WriteMessage(websocket.PingMessage, []byte{}) + err := wsc.writeMessageWithDeadline(websocket.PingMessage, []byte{}) if err != nil { wsc.Logger.Error("Failed to write ping message on websocket", "err", err) wsc.Stop() @@ -547,8 +546,7 @@ func (wsc *wsConnection) writeRoutine() { if err != nil { wsc.Logger.Error("Failed to marshal RPCResponse to JSON", "err", err) } else { - wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds)) - if err = wsc.baseConn.WriteMessage(websocket.TextMessage, jsonBytes); err != nil { + if err = wsc.writeMessageWithDeadline(websocket.TextMessage, jsonBytes); err != nil { wsc.Logger.Error("Failed to write response on websocket", "err", err) wsc.Stop() return @@ -558,6 +556,13 @@ func (wsc *wsConnection) writeRoutine() { } } +// All writes to the websocket must (re)set the write deadline. +// If some writes don't set it while others do, they may timeout incorrectly (https://github.com/tendermint/tendermint/issues/553) +func (wsc *wsConnection) writeMessageWithDeadline(msgType int, msg []byte) error { + wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds)) + return wsc.baseConn.WriteMessage(msgType, msg) +} + //---------------------------------------- // Main manager for all websocket connections