tendermint/p2p
Jae Kwon 9c1795a04d add mempool to consensus 2014-09-11 22:44:59 -07:00
..
upnp package rename peer -> p2p 2014-07-07 20:03:50 -07:00
README.md add mempool to consensus 2014-09-11 22:44:59 -07:00
addrbook.go saving development state... 2014-08-30 04:17:10 -07:00
addrbook_test.go addrbook cleanup 2014-07-10 02:19:50 -07:00
connection.go refactor from Binary centric model to global method model 2014-09-03 20:41:57 -07:00
listener.go refactor from Binary centric model to global method model 2014-09-03 20:41:57 -07:00
log.go fix test cases 2014-08-31 01:48:40 -07:00
netaddress.go refactor from Binary centric model to global method model 2014-09-03 20:41:57 -07:00
peer.go refactor from Binary centric model to global method model 2014-09-03 20:41:57 -07:00
peer_set.go implementing block_manager. currently only supports one datatype. 2014-07-29 23:53:35 -07:00
pex_agent.go s/Manager/Agent/g 2014-09-11 10:55:32 -07:00
switch.go saving development state... 2014-08-30 04:17:10 -07:00
switch_test.go refactor from Binary centric model to global method model 2014-09-03 20:41:57 -07:00
util.go cleanup 2014-07-09 14:27:32 -07:00

README.md

P2P Module

P2P provides an abstraction around peer-to-peer communication.
Communication happens via Agents that react to messages from peers.
Each Agent has one or more Channels of communication for each Peer.
Channels are multiplexed automatically and can be configured.
A Switch is started upon app start, and handles Peer management.
A PEXAgent implementation is provided to automate peer discovery.

Usage

MempoolAgent started from the following template code.
Modify the snippet below according to your needs.
Check out the ConsensusAgent for an example of tracking peer state.

package mempool

import (
	"bytes"
	"fmt"
	"io"
	"sync/atomic"

	. "github.com/tendermint/tendermint/binary"
	. "github.com/tendermint/tendermint/blocks"
	"github.com/tendermint/tendermint/p2p"
)

var (
	MempoolCh = byte(0x30)
)

// MempoolAgent handles mempool tx broadcasting amongst peers.
type MempoolAgent struct {
	sw       *p2p.Switch
	swEvents chan interface{}
	quit     chan struct{}
	started  uint32
	stopped  uint32
}

func NewMempoolAgent(sw *p2p.Switch) *MempoolAgent {
	swEvents := make(chan interface{})
	sw.AddEventListener("MempoolAgent.swEvents", swEvents)
	memA := &MempoolAgent{
		sw:       sw,
		swEvents: swEvents,
		quit:     make(chan struct{}),
	}
	return memA
}

func (memA *MempoolAgent) Start() {
	if atomic.CompareAndSwapUint32(&memA.started, 0, 1) {
		log.Info("Starting MempoolAgent")
		go memA.switchEventsRoutine()
		go memA.gossipTxRoutine()
	}
}

func (memA *MempoolAgent) Stop() {
	if atomic.CompareAndSwapUint32(&memA.stopped, 0, 1) {
		log.Info("Stopping MempoolAgent")
		close(memA.quit)
		close(memA.swEvents)
	}
}

// Handle peer new/done events
func (memA *MempoolAgent) switchEventsRoutine() {
	for {
		swEvent, ok := <-memA.swEvents
		if !ok {
			break
		}
		switch swEvent.(type) {
		case p2p.SwitchEventNewPeer:
			// event := swEvent.(p2p.SwitchEventNewPeer)
			// NOTE: set up peer state
		case p2p.SwitchEventDonePeer:
			// event := swEvent.(p2p.SwitchEventDonePeer)
			// NOTE: tear down peer state
		default:
			log.Warning("Unhandled switch event type")
		}
	}
}

func (memA *MempoolAgent) gossipTxRoutine() {
OUTER_LOOP:
	for {
		// Receive incoming message on MempoolCh
		inMsg, ok := memA.sw.Receive(MempoolCh)
		if !ok {
			break OUTER_LOOP // Client has stopped
		}
		_, msg_ := decodeMessage(inMsg.Bytes)
		log.Info("gossipMempoolRoutine received %v", msg_)

		switch msg_.(type) {
		case *TxMessage:
			// msg := msg_.(*TxMessage)
			// handle msg

		default:
			// Ignore unknown message
			// memA.sw.StopPeerForError(inMsg.MConn.Peer, errInvalidMessage)
		}
	}

	// Cleanup
}

Channels

Each peer connection is multiplexed into channels. The p2p module comes with a channel implementation used for peer discovery (called PEX, short for "peer exchange").

Channel "PEX"
Messages
  • pexRequestMsg
  • pexResponseMsg

Resources