mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-26 15:22:15 +00:00
P2P now works with Amino
This commit is contained in:
parent
ced74251e9
commit
901b456151
34
Gopkg.lock
generated
34
Gopkg.lock
generated
@ -229,7 +229,6 @@
|
|||||||
revision = "169b1b37be738edb2813dab48c97a549bcf99bb5"
|
revision = "169b1b37be738edb2813dab48c97a549bcf99bb5"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "develop"
|
|
||||||
name = "github.com/tendermint/abci"
|
name = "github.com/tendermint/abci"
|
||||||
packages = [
|
packages = [
|
||||||
"client",
|
"client",
|
||||||
@ -239,7 +238,8 @@
|
|||||||
"server",
|
"server",
|
||||||
"types"
|
"types"
|
||||||
]
|
]
|
||||||
revision = "4e0218467649fecf17ebc5e8161f1c888fc8ff22"
|
revision = "c62aed95f2ce399ec815b0cafe478af002cdc4e6"
|
||||||
|
version = "v0.10.3-dev"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -252,16 +252,16 @@
|
|||||||
revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057"
|
revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "develop"
|
|
||||||
name = "github.com/tendermint/go-amino"
|
name = "github.com/tendermint/go-amino"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "b1f32ee20e73716d8bfe695365c0a812b2bd8ef9"
|
revision = "f55c3351f30e5987500020631f00e87a035ed415"
|
||||||
|
version = "0.9.3"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "develop"
|
|
||||||
name = "github.com/tendermint/go-crypto"
|
name = "github.com/tendermint/go-crypto"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "a3800da0a15c8272cbd3c155e024bff28fe9692c"
|
revision = "a04f2ae5c6ba037014531241ed973116290b029e"
|
||||||
|
version = "v0.6.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/tendermint/go-wire"
|
name = "github.com/tendermint/go-wire"
|
||||||
@ -273,7 +273,6 @@
|
|||||||
version = "v0.7.3"
|
version = "v0.7.3"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "develop"
|
|
||||||
name = "github.com/tendermint/tmlibs"
|
name = "github.com/tendermint/tmlibs"
|
||||||
packages = [
|
packages = [
|
||||||
"autofile",
|
"autofile",
|
||||||
@ -289,7 +288,8 @@
|
|||||||
"pubsub/query",
|
"pubsub/query",
|
||||||
"test"
|
"test"
|
||||||
]
|
]
|
||||||
revision = "4e5c655944c9a636eaed549e6ad8fd8011fb4d42"
|
revision = "e9cf47606cfcbdc28a7c16671b4a70b459e9d4cc"
|
||||||
|
version = "v0.8.0-dev"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -304,7 +304,7 @@
|
|||||||
"ripemd160",
|
"ripemd160",
|
||||||
"salsa20/salsa"
|
"salsa20/salsa"
|
||||||
]
|
]
|
||||||
revision = "c3a3ad6d03f7a915c0f7e194b7152974bb73d287"
|
revision = "88942b9c40a4c9d203b82b3731787b672d6e809b"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -324,7 +324,7 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/sys"
|
name = "golang.org/x/sys"
|
||||||
packages = ["unix"]
|
packages = ["unix"]
|
||||||
revision = "7ceb54c8418b8f9cdf0177b511d5cbb06e9fae39"
|
revision = "91ee8cde435411ca3f1cd365e8f20131aed4d0a1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "golang.org/x/text"
|
name = "golang.org/x/text"
|
||||||
@ -351,20 +351,16 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "google.golang.org/genproto"
|
name = "google.golang.org/genproto"
|
||||||
packages = ["googleapis/rpc/status"]
|
packages = ["googleapis/rpc/status"]
|
||||||
revision = "f8c8703595236ae70fdf8789ecb656ea0bcdcf46"
|
revision = "ab0870e398d5dd054b868c0db1481ab029b9a9f2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "google.golang.org/grpc"
|
name = "google.golang.org/grpc"
|
||||||
packages = [
|
packages = [
|
||||||
".",
|
".",
|
||||||
"balancer",
|
"balancer",
|
||||||
"balancer/base",
|
|
||||||
"balancer/roundrobin",
|
|
||||||
"codes",
|
"codes",
|
||||||
"connectivity",
|
"connectivity",
|
||||||
"credentials",
|
"credentials",
|
||||||
"encoding",
|
|
||||||
"encoding/proto",
|
|
||||||
"grpclb/grpc_lb_v1/messages",
|
"grpclb/grpc_lb_v1/messages",
|
||||||
"grpclog",
|
"grpclog",
|
||||||
"internal",
|
"internal",
|
||||||
@ -373,15 +369,13 @@
|
|||||||
"naming",
|
"naming",
|
||||||
"peer",
|
"peer",
|
||||||
"resolver",
|
"resolver",
|
||||||
"resolver/dns",
|
|
||||||
"resolver/passthrough",
|
|
||||||
"stats",
|
"stats",
|
||||||
"status",
|
"status",
|
||||||
"tap",
|
"tap",
|
||||||
"transport"
|
"transport"
|
||||||
]
|
]
|
||||||
revision = "8e4536a86ab602859c20df5ebfd0bd4228d08655"
|
revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e"
|
||||||
version = "v1.10.0"
|
version = "v1.7.5"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "gopkg.in/yaml.v2"
|
name = "gopkg.in/yaml.v2"
|
||||||
@ -392,6 +386,6 @@
|
|||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "6da81f319b092e227b5d2c9de3b10296e9bb7287c02adb38fe547147e9e5e447"
|
inputs-digest = "9aace7a292e5402f97327860531e13b77f036c19843b698566ee958773404f48"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
14
Gopkg.toml
14
Gopkg.toml
@ -26,12 +26,12 @@
|
|||||||
|
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/ebuchman/fail-test"
|
name = "github.com/ebuchman/fail-test"
|
||||||
|
branch = "master"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/fortytw2/leaktest"
|
name = "github.com/fortytw2/leaktest"
|
||||||
|
branch = "master"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/go-kit/kit"
|
name = "github.com/go-kit/kit"
|
||||||
@ -54,8 +54,8 @@
|
|||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/rcrowley/go-metrics"
|
name = "github.com/rcrowley/go-metrics"
|
||||||
|
branch = "master"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/spf13/cobra"
|
name = "github.com/spf13/cobra"
|
||||||
@ -71,19 +71,19 @@
|
|||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/tendermint/abci"
|
name = "github.com/tendermint/abci"
|
||||||
branch = "develop"
|
version = "0.10.3-dev"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/tendermint/go-crypto"
|
name = "github.com/tendermint/go-crypto"
|
||||||
branch = "develop"
|
version = "0.6.0"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/tendermint/go-amino"
|
name = "github.com/tendermint/go-amino"
|
||||||
branch = "develop"
|
version = "0.9.3"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/tendermint/tmlibs"
|
name = "github.com/tendermint/tmlibs"
|
||||||
branch = "develop"
|
version = "0.8.0-dev"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "google.golang.org/grpc"
|
name = "google.golang.org/grpc"
|
||||||
|
@ -270,7 +270,7 @@ type P2PConfig struct {
|
|||||||
FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"`
|
FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"`
|
||||||
|
|
||||||
// Maximum size of a message packet payload, in bytes
|
// Maximum size of a message packet payload, in bytes
|
||||||
MaxMsgPacketPayloadSize int `mapstructure:"max_msg_packet_payload_size"`
|
MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"`
|
||||||
|
|
||||||
// Rate at which packets can be sent, in bytes/second
|
// Rate at which packets can be sent, in bytes/second
|
||||||
SendRate int64 `mapstructure:"send_rate"`
|
SendRate int64 `mapstructure:"send_rate"`
|
||||||
@ -299,7 +299,7 @@ func DefaultP2PConfig() *P2PConfig {
|
|||||||
AddrBookStrict: true,
|
AddrBookStrict: true,
|
||||||
MaxNumPeers: 50,
|
MaxNumPeers: 50,
|
||||||
FlushThrottleTimeout: 100,
|
FlushThrottleTimeout: 100,
|
||||||
MaxMsgPacketPayloadSize: 1024, // 1 kB
|
MaxPacketMsgPayloadSize: 1024, // 1 kB
|
||||||
SendRate: 512000, // 500 kB/s
|
SendRate: 512000, // 500 kB/s
|
||||||
RecvRate: 512000, // 500 kB/s
|
RecvRate: 512000, // 500 kB/s
|
||||||
PexReactor: true,
|
PexReactor: true,
|
||||||
|
@ -142,7 +142,7 @@ flush_throttle_timeout = {{ .P2P.FlushThrottleTimeout }}
|
|||||||
max_num_peers = {{ .P2P.MaxNumPeers }}
|
max_num_peers = {{ .P2P.MaxNumPeers }}
|
||||||
|
|
||||||
# Maximum size of a message packet payload, in bytes
|
# Maximum size of a message packet payload, in bytes
|
||||||
max_msg_packet_payload_size = {{ .P2P.MaxMsgPacketPayloadSize }}
|
max_packet_msg_payload_size = {{ .P2P.MaxPacketMsgPayloadSize }}
|
||||||
|
|
||||||
# Rate at which packets can be sent, in bytes/second
|
# Rate at which packets can be sent, in bytes/second
|
||||||
send_rate = {{ .P2P.SendRate }}
|
send_rate = {{ .P2P.SendRate }}
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime/debug"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -19,8 +18,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
packetMsgMaxPayloadSizeDefault = 1024
|
maxPacketMsgPayloadSizeDefault = 1024
|
||||||
packetMsgMaxOverheadSize = 10 // It's actually lower but good enough
|
maxPacketMsgOverheadSize = 14
|
||||||
|
|
||||||
numBatchPacketMsgs = 10
|
numBatchPacketMsgs = 10
|
||||||
minReadBufferSize = 1024
|
minReadBufferSize = 1024
|
||||||
@ -57,15 +56,15 @@ The byte id and the relative priorities of each `Channel` are configured upon
|
|||||||
initialization of the connection.
|
initialization of the connection.
|
||||||
|
|
||||||
There are two methods for sending messages:
|
There are two methods for sending messages:
|
||||||
func (m MConnection) Send(chID byte, msg interface{}) bool {}
|
func (m MConnection) Send(chID byte, msgBytes []byte) bool {}
|
||||||
func (m MConnection) TrySend(chID byte, msg interface{}) bool {}
|
func (m MConnection) TrySend(chID byte, msgBytes []byte}) bool {}
|
||||||
|
|
||||||
`Send(chID, msg)` is a blocking call that waits until `msg` is successfully queued
|
`Send(chID, msgBytes)` is a blocking call that waits until `msg` is
|
||||||
for the channel with the given id byte `chID`, or until the request times out.
|
successfully queued for the channel with the given id byte `chID`, or until the
|
||||||
The message `msg` is serialized using Go-Amino.
|
request times out. The message `msg` is serialized using Go-Amino.
|
||||||
|
|
||||||
`TrySend(chID, msg)` is a nonblocking call that returns false if the channel's
|
`TrySend(chID, msgBytes)` is a nonblocking call that returns false if the
|
||||||
queue is full.
|
channel's queue is full.
|
||||||
|
|
||||||
Inbound message bytes are handled with an onReceive callback function.
|
Inbound message bytes are handled with an onReceive callback function.
|
||||||
*/
|
*/
|
||||||
@ -105,7 +104,7 @@ type MConnConfig struct {
|
|||||||
RecvRate int64 `mapstructure:"recv_rate"`
|
RecvRate int64 `mapstructure:"recv_rate"`
|
||||||
|
|
||||||
// Maximum payload size
|
// Maximum payload size
|
||||||
PacketMsgMaxPayloadSize int `mapstructure:"packet_msg_max_payload_size"`
|
MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"`
|
||||||
|
|
||||||
// Interval to flush writes (throttled)
|
// Interval to flush writes (throttled)
|
||||||
FlushThrottle time.Duration `mapstructure:"flush_throttle"`
|
FlushThrottle time.Duration `mapstructure:"flush_throttle"`
|
||||||
@ -118,7 +117,7 @@ type MConnConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *MConnConfig) maxPacketMsgTotalSize() int {
|
func (cfg *MConnConfig) maxPacketMsgTotalSize() int {
|
||||||
return cfg.PacketMsgMaxPayloadSize + packetMsgMaxOverheadSize
|
return cfg.MaxPacketMsgPayloadSize + maxPacketMsgOverheadSize
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultMConnConfig returns the default config.
|
// DefaultMConnConfig returns the default config.
|
||||||
@ -126,7 +125,7 @@ func DefaultMConnConfig() *MConnConfig {
|
|||||||
return &MConnConfig{
|
return &MConnConfig{
|
||||||
SendRate: defaultSendRate,
|
SendRate: defaultSendRate,
|
||||||
RecvRate: defaultRecvRate,
|
RecvRate: defaultRecvRate,
|
||||||
PacketMsgMaxPayloadSize: packetMsgMaxPayloadSizeDefault,
|
MaxPacketMsgPayloadSize: maxPacketMsgPayloadSizeDefault,
|
||||||
FlushThrottle: defaultFlushThrottle,
|
FlushThrottle: defaultFlushThrottle,
|
||||||
PingInterval: defaultPingInterval,
|
PingInterval: defaultPingInterval,
|
||||||
PongTimeout: defaultPongTimeout,
|
PongTimeout: defaultPongTimeout,
|
||||||
@ -233,8 +232,7 @@ func (c *MConnection) flush() {
|
|||||||
// Catch panics, usually caused by remote disconnects.
|
// Catch panics, usually caused by remote disconnects.
|
||||||
func (c *MConnection) _recover() {
|
func (c *MConnection) _recover() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
stack := debug.Stack()
|
err := cmn.ErrorWrap(r, "recovered panic in MConnection")
|
||||||
err := cmn.StackError{r, stack}
|
|
||||||
c.stopForError(err)
|
c.stopForError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,12 +247,12 @@ func (c *MConnection) stopForError(r interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Queues a message to be sent to channel.
|
// Queues a message to be sent to channel.
|
||||||
func (c *MConnection) Send(chID byte, msg interface{}) bool {
|
func (c *MConnection) Send(chID byte, msgBytes []byte) bool {
|
||||||
if !c.IsRunning() {
|
if !c.IsRunning() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Logger.Debug("Send", "channel", chID, "conn", c, "msg", msg)
|
c.Logger.Debug("Send", "channel", chID, "conn", c, "msgBytes", fmt.Sprintf("%X", msgBytes))
|
||||||
|
|
||||||
// Send message to channel.
|
// Send message to channel.
|
||||||
channel, ok := c.channelsIdx[chID]
|
channel, ok := c.channelsIdx[chID]
|
||||||
@ -263,7 +261,7 @@ func (c *MConnection) Send(chID byte, msg interface{}) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
success := channel.sendBytes(cdc.MustMarshalBinary(msg))
|
success := channel.sendBytes(msgBytes)
|
||||||
if success {
|
if success {
|
||||||
// Wake up sendRoutine if necessary
|
// Wake up sendRoutine if necessary
|
||||||
select {
|
select {
|
||||||
@ -271,19 +269,19 @@ func (c *MConnection) Send(chID byte, msg interface{}) bool {
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.Logger.Error("Send failed", "channel", chID, "conn", c, "msg", msg)
|
c.Logger.Error("Send failed", "channel", chID, "conn", c, "msgBytes", fmt.Sprintf("%X", msgBytes))
|
||||||
}
|
}
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queues a message to be sent to channel.
|
// Queues a message to be sent to channel.
|
||||||
// Nonblocking, returns true if successful.
|
// Nonblocking, returns true if successful.
|
||||||
func (c *MConnection) TrySend(chID byte, msg interface{}) bool {
|
func (c *MConnection) TrySend(chID byte, msgBytes []byte) bool {
|
||||||
if !c.IsRunning() {
|
if !c.IsRunning() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Logger.Debug("TrySend", "channel", chID, "conn", c, "msg", msg)
|
c.Logger.Debug("TrySend", "channel", chID, "conn", c, "msgBytes", fmt.Sprintf("%X", msgBytes))
|
||||||
|
|
||||||
// Send message to channel.
|
// Send message to channel.
|
||||||
channel, ok := c.channelsIdx[chID]
|
channel, ok := c.channelsIdx[chID]
|
||||||
@ -292,7 +290,7 @@ func (c *MConnection) TrySend(chID byte, msg interface{}) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = channel.trySendBytes(cdc.MustMarshalBinary(msg))
|
ok = channel.trySendBytes(msgBytes)
|
||||||
if ok {
|
if ok {
|
||||||
// Wake up sendRoutine if necessary
|
// Wake up sendRoutine if necessary
|
||||||
select {
|
select {
|
||||||
@ -462,18 +460,17 @@ FOR_LOOP:
|
|||||||
// Block until .recvMonitor says we can read.
|
// Block until .recvMonitor says we can read.
|
||||||
c.recvMonitor.Limit(c.config.maxPacketMsgTotalSize(), atomic.LoadInt64(&c.config.RecvRate), true)
|
c.recvMonitor.Limit(c.config.maxPacketMsgTotalSize(), atomic.LoadInt64(&c.config.RecvRate), true)
|
||||||
|
|
||||||
|
// Peek into bufConnReader for debugging
|
||||||
/*
|
/*
|
||||||
// Peek into bufConnReader for debugging
|
|
||||||
if numBytes := c.bufConnReader.Buffered(); numBytes > 0 {
|
if numBytes := c.bufConnReader.Buffered(); numBytes > 0 {
|
||||||
log.Info("Peek connection buffer", "numBytes", numBytes, "bytes", log15.Lazy{func() []byte {
|
bz, err := c.bufConnReader.Peek(cmn.MinInt(numBytes, 100))
|
||||||
bytes, err := c.bufConnReader.Peek(cmn.MinInt(numBytes, 100))
|
if err == nil {
|
||||||
if err == nil {
|
// return
|
||||||
return bytes
|
} else {
|
||||||
} else {
|
c.Logger.Debug("Error peeking connection buffer", "err", err)
|
||||||
log.Warn("Error peeking connection buffer", "err", err)
|
// return nil
|
||||||
return nil
|
}
|
||||||
}
|
c.Logger.Info("Peek connection buffer", "numBytes", numBytes, "bz", bz)
|
||||||
}})
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -639,7 +636,7 @@ func newChannel(conn *MConnection, desc ChannelDescriptor) *Channel {
|
|||||||
desc: desc,
|
desc: desc,
|
||||||
sendQueue: make(chan []byte, desc.SendQueueCapacity),
|
sendQueue: make(chan []byte, desc.SendQueueCapacity),
|
||||||
recving: make([]byte, 0, desc.RecvBufferCapacity),
|
recving: make([]byte, 0, desc.RecvBufferCapacity),
|
||||||
maxPacketMsgPayloadSize: conn.config.PacketMsgMaxPayloadSize,
|
maxPacketMsgPayloadSize: conn.config.MaxPacketMsgPayloadSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,7 +716,6 @@ func (ch *Channel) nextPacketMsg() PacketMsg {
|
|||||||
// Not goroutine-safe
|
// Not goroutine-safe
|
||||||
func (ch *Channel) writePacketMsgTo(w io.Writer) (n int64, err error) {
|
func (ch *Channel) writePacketMsgTo(w io.Writer) (n int64, err error) {
|
||||||
var packet = ch.nextPacketMsg()
|
var packet = ch.nextPacketMsg()
|
||||||
ch.Logger.Debug("Write Msg Packet", "conn", ch.conn, "packet", packet)
|
|
||||||
n, err = cdc.MarshalBinaryWriter(w, packet)
|
n, err = cdc.MarshalBinaryWriter(w, packet)
|
||||||
ch.recentlySent += n
|
ch.recentlySent += n
|
||||||
return
|
return
|
||||||
@ -729,7 +725,7 @@ func (ch *Channel) writePacketMsgTo(w io.Writer) (n int64, err error) {
|
|||||||
// complete. NOTE message bytes may change on next call to recvPacketMsg.
|
// complete. NOTE message bytes may change on next call to recvPacketMsg.
|
||||||
// Not goroutine-safe
|
// Not goroutine-safe
|
||||||
func (ch *Channel) recvPacketMsg(packet PacketMsg) ([]byte, error) {
|
func (ch *Channel) recvPacketMsg(packet PacketMsg) ([]byte, error) {
|
||||||
ch.Logger.Debug("Read Msg Packet", "conn", ch.conn, "packet", packet)
|
ch.Logger.Debug("Read PacketMsg", "conn", ch.conn, "packet", packet)
|
||||||
var recvCap, recvReceived = ch.desc.RecvMessageCapacity, len(ch.recving) + len(packet.Bytes)
|
var recvCap, recvReceived = ch.desc.RecvMessageCapacity, len(ch.recving) + len(packet.Bytes)
|
||||||
if recvCap < recvReceived {
|
if recvCap < recvReceived {
|
||||||
return nil, fmt.Errorf("Received message exceeds available capacity: %v < %v", recvCap, recvReceived)
|
return nil, fmt.Errorf("Received message exceeds available capacity: %v < %v", recvCap, recvReceived)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package conn
|
package conn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -41,7 +42,7 @@ func TestMConnectionSend(t *testing.T) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
defer mconn.Stop()
|
defer mconn.Stop()
|
||||||
|
|
||||||
msg := "Ant-Man"
|
msg := []byte("Ant-Man")
|
||||||
assert.True(t, mconn.Send(0x01, msg))
|
assert.True(t, mconn.Send(0x01, msg))
|
||||||
// Note: subsequent Send/TrySend calls could pass because we are reading from
|
// Note: subsequent Send/TrySend calls could pass because we are reading from
|
||||||
// the send queue in a separate goroutine.
|
// the send queue in a separate goroutine.
|
||||||
@ -51,7 +52,7 @@ func TestMConnectionSend(t *testing.T) {
|
|||||||
}
|
}
|
||||||
assert.True(t, mconn.CanSend(0x01))
|
assert.True(t, mconn.CanSend(0x01))
|
||||||
|
|
||||||
msg = "Spider-Man"
|
msg = []byte("Spider-Man")
|
||||||
assert.True(t, mconn.TrySend(0x01, msg))
|
assert.True(t, mconn.TrySend(0x01, msg))
|
||||||
_, err = server.Read(make([]byte, len(msg)))
|
_, err = server.Read(make([]byte, len(msg)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,7 +60,7 @@ func TestMConnectionSend(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert.False(t, mconn.CanSend(0x05), "CanSend should return false because channel is unknown")
|
assert.False(t, mconn.CanSend(0x05), "CanSend should return false because channel is unknown")
|
||||||
assert.False(t, mconn.Send(0x05, "Absorbing Man"), "Send should return false because channel is unknown")
|
assert.False(t, mconn.Send(0x05, []byte("Absorbing Man")), "Send should return false because channel is unknown")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMConnectionReceive(t *testing.T) {
|
func TestMConnectionReceive(t *testing.T) {
|
||||||
@ -85,12 +86,12 @@ func TestMConnectionReceive(t *testing.T) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
defer mconn2.Stop()
|
defer mconn2.Stop()
|
||||||
|
|
||||||
msg := "Cyclops"
|
msg := []byte("Cyclops")
|
||||||
assert.True(t, mconn2.Send(0x01, msg))
|
assert.True(t, mconn2.Send(0x01, msg))
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case receivedBytes := <-receivedCh:
|
case receivedBytes := <-receivedCh:
|
||||||
assert.Equal(t, []byte(msg), receivedBytes[2:]) // first 3 bytes are internal
|
assert.Equal(t, []byte(msg), receivedBytes)
|
||||||
case err := <-errorsCh:
|
case err := <-errorsCh:
|
||||||
t.Fatalf("Expected %s, got %+v", msg, err)
|
t.Fatalf("Expected %s, got %+v", msg, err)
|
||||||
case <-time.After(500 * time.Millisecond):
|
case <-time.After(500 * time.Millisecond):
|
||||||
@ -386,7 +387,7 @@ func TestMConnectionReadErrorUnknownChannel(t *testing.T) {
|
|||||||
defer mconnClient.Stop()
|
defer mconnClient.Stop()
|
||||||
defer mconnServer.Stop()
|
defer mconnServer.Stop()
|
||||||
|
|
||||||
msg := "Ant-Man"
|
msg := []byte("Ant-Man")
|
||||||
|
|
||||||
// fail to send msg on channel unknown by client
|
// fail to send msg on channel unknown by client
|
||||||
assert.False(t, mconnClient.Send(0x03, msg))
|
assert.False(t, mconnClient.Send(0x03, msg))
|
||||||
@ -413,23 +414,40 @@ func TestMConnectionReadErrorLongMessage(t *testing.T) {
|
|||||||
|
|
||||||
// send msg thats just right
|
// send msg thats just right
|
||||||
var err error
|
var err error
|
||||||
|
var buf = new(bytes.Buffer)
|
||||||
|
// - Uvarint length of MustMarshalBinary(packet) = 1 or 2 bytes
|
||||||
|
// (as long as it's less than 16,384 bytes)
|
||||||
|
// - Prefix bytes = 4 bytes
|
||||||
|
// - ChannelID field key + byte = 2 bytes
|
||||||
|
// - EOF field key + byte = 2 bytes
|
||||||
|
// - Bytes field key = 1 bytes
|
||||||
|
// - Uvarint length of MustMarshalBinary(bytes) = 1 or 2 bytes
|
||||||
|
// - Struct terminator = 1 byte
|
||||||
|
// = up to 14 bytes overhead for the packet.
|
||||||
var packet = PacketMsg{
|
var packet = PacketMsg{
|
||||||
ChannelID: 0x01,
|
ChannelID: 0x01,
|
||||||
Bytes: make([]byte, mconnClient.config.maxPacketMsgTotalSize()-12),
|
|
||||||
EOF: 1,
|
EOF: 1,
|
||||||
|
Bytes: make([]byte, mconnClient.config.MaxPacketMsgPayloadSize),
|
||||||
}
|
}
|
||||||
_, err = cdc.MarshalBinaryWriter(client, packet)
|
_, err = cdc.MarshalBinaryWriter(buf, packet)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
_, err = client.Write(buf.Bytes())
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.True(t, expectSend(chOnRcv), "msg just right")
|
assert.True(t, expectSend(chOnRcv), "msg just right")
|
||||||
|
assert.False(t, expectSend(chOnErr), "msg just right")
|
||||||
|
|
||||||
// send msg thats too long
|
// send msg thats too long
|
||||||
|
buf = new(bytes.Buffer)
|
||||||
packet = PacketMsg{
|
packet = PacketMsg{
|
||||||
ChannelID: 0x01,
|
ChannelID: 0x01,
|
||||||
Bytes: make([]byte, mconnClient.config.maxPacketMsgTotalSize()-11),
|
|
||||||
EOF: 1,
|
EOF: 1,
|
||||||
|
Bytes: make([]byte, mconnClient.config.MaxPacketMsgPayloadSize+1),
|
||||||
}
|
}
|
||||||
_, err = cdc.MarshalBinaryWriter(client, packet)
|
_, err = cdc.MarshalBinaryWriter(buf, packet)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
_, err = client.Write(buf.Bytes())
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.False(t, expectSend(chOnRcv), "msg too long")
|
||||||
assert.True(t, expectSend(chOnErr), "msg too long")
|
assert.True(t, expectSend(chOnErr), "msg too long")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +476,7 @@ func TestMConnectionTrySend(t *testing.T) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
defer mconn.Stop()
|
defer mconn.Stop()
|
||||||
|
|
||||||
msg := "Semicolon-Woman"
|
msg := []byte("Semicolon-Woman")
|
||||||
resultCh := make(chan string, 2)
|
resultCh := make(chan string, 2)
|
||||||
assert.True(t, mconn.TrySend(0x01, msg))
|
assert.True(t, mconn.TrySend(0x01, msg))
|
||||||
server.Read(make([]byte, len(msg)))
|
server.Read(make([]byte, len(msg)))
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
@ -145,8 +144,8 @@ func (sc *SecretConnection) Write(data []byte) (n int, err error) {
|
|||||||
// CONTRACT: data smaller than dataMaxSize is read atomically.
|
// CONTRACT: data smaller than dataMaxSize is read atomically.
|
||||||
func (sc *SecretConnection) Read(data []byte) (n int, err error) {
|
func (sc *SecretConnection) Read(data []byte) (n int, err error) {
|
||||||
if 0 < len(sc.recvBuffer) {
|
if 0 < len(sc.recvBuffer) {
|
||||||
n_ := copy(data, sc.recvBuffer)
|
n = copy(data, sc.recvBuffer)
|
||||||
sc.recvBuffer = sc.recvBuffer[n_:]
|
sc.recvBuffer = sc.recvBuffer[n:]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +192,7 @@ func genEphKeys() (ephPub, ephPriv *[32]byte) {
|
|||||||
var err error
|
var err error
|
||||||
ephPub, ephPriv, err = box.GenerateKey(crand.Reader)
|
ephPub, ephPriv, err = box.GenerateKey(crand.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmn.PanicCrisis("Could not generate ephemeral keypairs")
|
panic("Could not generate ephemeral keypairs")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -225,9 +224,6 @@ func shareEphPubKey(conn io.ReadWriteCloser, locEphPub *[32]byte) (remEphPub *[3
|
|||||||
if trs.FirstError() != nil {
|
if trs.FirstError() != nil {
|
||||||
err = trs.FirstError()
|
err = trs.FirstError()
|
||||||
return
|
return
|
||||||
} else if trs.FirstPanic() != nil {
|
|
||||||
err = fmt.Errorf("Panic: %v", trs.FirstPanic())
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise:
|
// Otherwise:
|
||||||
@ -309,9 +305,6 @@ func shareAuthSignature(sc *SecretConnection, pubKey crypto.PubKey, signature cr
|
|||||||
if trs.FirstError() != nil {
|
if trs.FirstError() != nil {
|
||||||
err = trs.FirstError()
|
err = trs.FirstError()
|
||||||
return
|
return
|
||||||
} else if trs.FirstPanic() != nil {
|
|
||||||
err = fmt.Errorf("Panic: %v", trs.FirstPanic())
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _recvMsg = trs.FirstValue().(authSigMessage)
|
var _recvMsg = trs.FirstValue().(authSigMessage)
|
||||||
|
@ -73,7 +73,6 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection
|
|||||||
return nil, nil, false
|
return nil, nil, false
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
require.Nil(tb, trs.FirstPanic())
|
|
||||||
require.Nil(tb, trs.FirstError())
|
require.Nil(tb, trs.FirstError())
|
||||||
require.True(tb, ok, "Unexpected task abortion")
|
require.True(tb, ok, "Unexpected task abortion")
|
||||||
|
|
||||||
@ -158,9 +157,6 @@ func TestSecretConnectionReadWrite(t *testing.T) {
|
|||||||
// If error:
|
// If error:
|
||||||
if trs.FirstError() != nil {
|
if trs.FirstError() != nil {
|
||||||
return nil, trs.FirstError(), true
|
return nil, trs.FirstError(), true
|
||||||
} else if trs.FirstPanic() != nil {
|
|
||||||
err = fmt.Errorf("Panic in task: %v", trs.FirstPanic())
|
|
||||||
return nil, err, true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise:
|
// Otherwise:
|
||||||
@ -173,7 +169,6 @@ func TestSecretConnectionReadWrite(t *testing.T) {
|
|||||||
genNodeRunner("foo", fooConn, fooWrites, &fooReads),
|
genNodeRunner("foo", fooConn, fooWrites, &fooReads),
|
||||||
genNodeRunner("bar", barConn, barWrites, &barReads),
|
genNodeRunner("bar", barConn, barWrites, &barReads),
|
||||||
)
|
)
|
||||||
require.Nil(t, trs.FirstPanic())
|
|
||||||
require.Nil(t, trs.FirstError())
|
require.Nil(t, trs.FirstError())
|
||||||
require.True(t, ok, "unexpected task abortion")
|
require.True(t, ok, "unexpected task abortion")
|
||||||
|
|
||||||
|
@ -5,10 +5,9 @@ import (
|
|||||||
"github.com/tendermint/go-crypto"
|
"github.com/tendermint/go-crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cdc *amino.Codec
|
var cdc *amino.Codec = amino.NewCodec()
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cdc = amino.NewCodec()
|
|
||||||
crypto.RegisterAmino(cdc)
|
crypto.RegisterAmino(cdc)
|
||||||
RegisterPacket(cdc)
|
RegisterPacket(cdc)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package p2p
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
@ -64,7 +63,7 @@ func loadNodeKey(filePath string) (*NodeKey, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
nodeKey := new(NodeKey)
|
nodeKey := new(NodeKey)
|
||||||
err = json.Unmarshal(jsonBytes, nodeKey)
|
err = cdc.UnmarshalJSON(jsonBytes, nodeKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error reading NodeKey from %v: %v\n", filePath, err)
|
return nil, fmt.Errorf("Error reading NodeKey from %v: %v\n", filePath, err)
|
||||||
}
|
}
|
||||||
@ -72,12 +71,12 @@ func loadNodeKey(filePath string) (*NodeKey, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func genNodeKey(filePath string) (*NodeKey, error) {
|
func genNodeKey(filePath string) (*NodeKey, error) {
|
||||||
privKey := crypto.GenPrivKeyEd25519().Wrap()
|
privKey := crypto.GenPrivKeyEd25519()
|
||||||
nodeKey := &NodeKey{
|
nodeKey := &NodeKey{
|
||||||
PrivKey: privKey,
|
PrivKey: privKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonBytes, err := json.Marshal(nodeKey)
|
jsonBytes, err := cdc.MarshalJSON(nodeKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -66,7 +65,7 @@ func NewNetAddressString(addr string) (*NetAddress, error) {
|
|||||||
idStr := spl[0]
|
idStr := spl[0]
|
||||||
idBytes, err := hex.DecodeString(idStr)
|
idBytes, err := hex.DecodeString(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, fmt.Sprintf("Address (%s) contains invalid ID", addr))
|
return nil, cmn.ErrorWrap(err, fmt.Sprintf("Address (%s) contains invalid ID", addr))
|
||||||
}
|
}
|
||||||
if len(idBytes) != IDByteLength {
|
if len(idBytes) != IDByteLength {
|
||||||
return nil, fmt.Errorf("Address (%s) contains ID of invalid length (%d). Should be %d hex-encoded bytes",
|
return nil, fmt.Errorf("Address (%s) contains ID of invalid length (%d). Should be %d hex-encoded bytes",
|
||||||
|
63
p2p/peer.go
63
p2p/peer.go
@ -5,10 +5,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/tendermint/go-crypto"
|
||||||
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
|
||||||
wire "github.com/tendermint/go-wire"
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
@ -25,8 +22,8 @@ type Peer interface {
|
|||||||
NodeInfo() NodeInfo // peer's info
|
NodeInfo() NodeInfo // peer's info
|
||||||
Status() tmconn.ConnectionStatus
|
Status() tmconn.ConnectionStatus
|
||||||
|
|
||||||
Send(byte, interface{}) bool
|
Send(byte, []byte) bool
|
||||||
TrySend(byte, interface{}) bool
|
TrySend(byte, []byte) bool
|
||||||
|
|
||||||
Set(string, interface{})
|
Set(string, interface{})
|
||||||
Get(string) interface{}
|
Get(string) interface{}
|
||||||
@ -114,13 +111,13 @@ func newOutboundPeerConn(addr *NetAddress, config *PeerConfig, persistent bool,
|
|||||||
|
|
||||||
conn, err := dial(addr, config)
|
conn, err := dial(addr, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pc, errors.Wrap(err, "Error creating peer")
|
return pc, cmn.ErrorWrap(err, "Error creating peer")
|
||||||
}
|
}
|
||||||
|
|
||||||
pc, err = newPeerConn(conn, config, true, persistent, ourNodePrivKey)
|
pc, err = newPeerConn(conn, config, true, persistent, ourNodePrivKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err2 := conn.Close(); err2 != nil {
|
if err2 := conn.Close(); err2 != nil {
|
||||||
return pc, errors.Wrap(err, err2.Error())
|
return pc, cmn.ErrorWrap(err, err2.Error())
|
||||||
}
|
}
|
||||||
return pc, err
|
return pc, err
|
||||||
}
|
}
|
||||||
@ -128,7 +125,7 @@ func newOutboundPeerConn(addr *NetAddress, config *PeerConfig, persistent bool,
|
|||||||
// ensure dialed ID matches connection ID
|
// ensure dialed ID matches connection ID
|
||||||
if config.AuthEnc && addr.ID != pc.ID() {
|
if config.AuthEnc && addr.ID != pc.ID() {
|
||||||
if err2 := conn.Close(); err2 != nil {
|
if err2 := conn.Close(); err2 != nil {
|
||||||
return pc, errors.Wrap(err, err2.Error())
|
return pc, cmn.ErrorWrap(err, err2.Error())
|
||||||
}
|
}
|
||||||
return pc, ErrSwitchAuthenticationFailure{addr, pc.ID()}
|
return pc, ErrSwitchAuthenticationFailure{addr, pc.ID()}
|
||||||
}
|
}
|
||||||
@ -157,13 +154,13 @@ func newPeerConn(rawConn net.Conn,
|
|||||||
if config.AuthEnc {
|
if config.AuthEnc {
|
||||||
// Set deadline for secret handshake
|
// Set deadline for secret handshake
|
||||||
if err := conn.SetDeadline(time.Now().Add(config.HandshakeTimeout * time.Second)); err != nil {
|
if err := conn.SetDeadline(time.Now().Add(config.HandshakeTimeout * time.Second)); err != nil {
|
||||||
return pc, errors.Wrap(err, "Error setting deadline while encrypting connection")
|
return pc, cmn.ErrorWrap(err, "Error setting deadline while encrypting connection")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt connection
|
// Encrypt connection
|
||||||
conn, err = tmconn.MakeSecretConnection(conn, ourNodePrivKey)
|
conn, err = tmconn.MakeSecretConnection(conn, ourNodePrivKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pc, errors.Wrap(err, "Error creating peer")
|
return pc, cmn.ErrorWrap(err, "Error creating peer")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,9 +225,9 @@ func (p *peer) Status() tmconn.ConnectionStatus {
|
|||||||
return p.mconn.Status()
|
return p.mconn.Status()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send msg to the channel identified by chID byte. Returns false if the send
|
// Send msg bytes to the channel identified by chID byte. Returns false if the
|
||||||
// queue is full after timeout, specified by MConnection.
|
// send queue is full after timeout, specified by MConnection.
|
||||||
func (p *peer) Send(chID byte, msg interface{}) bool {
|
func (p *peer) Send(chID byte, msgBytes []byte) bool {
|
||||||
if !p.IsRunning() {
|
if !p.IsRunning() {
|
||||||
// see Switch#Broadcast, where we fetch the list of peers and loop over
|
// see Switch#Broadcast, where we fetch the list of peers and loop over
|
||||||
// them - while we're looping, one peer may be removed and stopped.
|
// them - while we're looping, one peer may be removed and stopped.
|
||||||
@ -238,18 +235,18 @@ func (p *peer) Send(chID byte, msg interface{}) bool {
|
|||||||
} else if !p.hasChannel(chID) {
|
} else if !p.hasChannel(chID) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return p.mconn.Send(chID, msg)
|
return p.mconn.Send(chID, msgBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrySend msg to the channel identified by chID byte. Immediately returns
|
// TrySend msg bytes to the channel identified by chID byte. Immediately returns
|
||||||
// false if the send queue is full.
|
// false if the send queue is full.
|
||||||
func (p *peer) TrySend(chID byte, msg interface{}) bool {
|
func (p *peer) TrySend(chID byte, msgBytes []byte) bool {
|
||||||
if !p.IsRunning() {
|
if !p.IsRunning() {
|
||||||
return false
|
return false
|
||||||
} else if !p.hasChannel(chID) {
|
} else if !p.hasChannel(chID) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return p.mconn.TrySend(chID, msg)
|
return p.mconn.TrySend(chID, msgBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the data for a given key.
|
// Get the data for a given key.
|
||||||
@ -290,30 +287,26 @@ func (pc *peerConn) CloseConn() {
|
|||||||
func (pc *peerConn) HandshakeTimeout(ourNodeInfo NodeInfo, timeout time.Duration) (peerNodeInfo NodeInfo, err error) {
|
func (pc *peerConn) HandshakeTimeout(ourNodeInfo NodeInfo, timeout time.Duration) (peerNodeInfo NodeInfo, err error) {
|
||||||
// Set deadline for handshake so we don't block forever on conn.ReadFull
|
// Set deadline for handshake so we don't block forever on conn.ReadFull
|
||||||
if err := pc.conn.SetDeadline(time.Now().Add(timeout)); err != nil {
|
if err := pc.conn.SetDeadline(time.Now().Add(timeout)); err != nil {
|
||||||
return peerNodeInfo, errors.Wrap(err, "Error setting deadline")
|
return peerNodeInfo, cmn.ErrorWrap(err, "Error setting deadline")
|
||||||
}
|
}
|
||||||
|
|
||||||
var err1 error
|
var trs, _ = cmn.Parallel(
|
||||||
var err2 error
|
func(_ int) (val interface{}, err error, abort bool) {
|
||||||
cmn.Parallel(
|
_, err = cdc.MarshalBinaryWriter(pc.conn, ourNodeInfo)
|
||||||
func() {
|
return
|
||||||
var n int
|
|
||||||
wire.WriteBinary(&ourNodeInfo, pc.conn, &n, &err1)
|
|
||||||
},
|
},
|
||||||
func() {
|
func(_ int) (val interface{}, err error, abort bool) {
|
||||||
var n int
|
_, err = cdc.UnmarshalBinaryReader(pc.conn, &peerNodeInfo, int64(MaxNodeInfoSize()))
|
||||||
wire.ReadBinary(&peerNodeInfo, pc.conn, MaxNodeInfoSize(), &n, &err2)
|
return
|
||||||
})
|
},
|
||||||
if err1 != nil {
|
)
|
||||||
return peerNodeInfo, errors.Wrap(err1, "Error during handshake/write")
|
if err := trs.FirstError(); err != nil {
|
||||||
}
|
return peerNodeInfo, cmn.ErrorWrap(err, "Error during handshake")
|
||||||
if err2 != nil {
|
|
||||||
return peerNodeInfo, errors.Wrap(err2, "Error during handshake/read")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove deadline
|
// Remove deadline
|
||||||
if err := pc.conn.SetDeadline(time.Time{}); err != nil {
|
if err := pc.conn.SetDeadline(time.Time{}); err != nil {
|
||||||
return peerNodeInfo, errors.Wrap(err, "Error removing deadline")
|
return peerNodeInfo, cmn.ErrorWrap(err, "Error removing deadline")
|
||||||
}
|
}
|
||||||
|
|
||||||
return peerNodeInfo, nil
|
return peerNodeInfo, nil
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
// Returns an empty kvstore peer
|
// Returns an empty kvstore peer
|
||||||
func randPeer() *peer {
|
func randPeer() *peer {
|
||||||
pubKey := crypto.GenPrivKeyEd25519().Wrap().PubKey()
|
pubKey := crypto.GenPrivKeyEd25519().PubKey()
|
||||||
return &peer{
|
return &peer{
|
||||||
nodeInfo: NodeInfo{
|
nodeInfo: NodeInfo{
|
||||||
ListenAddr: cmn.Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256),
|
ListenAddr: cmn.Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256),
|
||||||
|
@ -20,7 +20,7 @@ func TestPeerBasic(t *testing.T) {
|
|||||||
assert, require := assert.New(t), require.New(t)
|
assert, require := assert.New(t), require.New(t)
|
||||||
|
|
||||||
// simulate remote peer
|
// simulate remote peer
|
||||||
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519().Wrap(), Config: DefaultPeerConfig()}
|
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: DefaultPeerConfig()}
|
||||||
rp.Start()
|
rp.Start()
|
||||||
defer rp.Stop()
|
defer rp.Stop()
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ func TestPeerWithoutAuthEnc(t *testing.T) {
|
|||||||
config.AuthEnc = false
|
config.AuthEnc = false
|
||||||
|
|
||||||
// simulate remote peer
|
// simulate remote peer
|
||||||
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519().Wrap(), Config: config}
|
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: config}
|
||||||
rp.Start()
|
rp.Start()
|
||||||
defer rp.Stop()
|
defer rp.Stop()
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ func TestPeerSend(t *testing.T) {
|
|||||||
config.AuthEnc = false
|
config.AuthEnc = false
|
||||||
|
|
||||||
// simulate remote peer
|
// simulate remote peer
|
||||||
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519().Wrap(), Config: config}
|
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: config}
|
||||||
rp.Start()
|
rp.Start()
|
||||||
defer rp.Stop()
|
defer rp.Stop()
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ func TestPeerSend(t *testing.T) {
|
|||||||
defer p.Stop()
|
defer p.Stop()
|
||||||
|
|
||||||
assert.True(p.CanSend(testCh))
|
assert.True(p.CanSend(testCh))
|
||||||
assert.True(p.Send(testCh, "Asylum"))
|
assert.True(p.Send(testCh, []byte("Asylum")))
|
||||||
}
|
}
|
||||||
|
|
||||||
func createOutboundPeerAndPerformHandshake(addr *NetAddress, config *PeerConfig) (*peer, error) {
|
func createOutboundPeerAndPerformHandshake(addr *NetAddress, config *PeerConfig) (*peer, error) {
|
||||||
@ -89,7 +89,7 @@ func createOutboundPeerAndPerformHandshake(addr *NetAddress, config *PeerConfig)
|
|||||||
{ID: testCh, Priority: 1},
|
{ID: testCh, Priority: 1},
|
||||||
}
|
}
|
||||||
reactorsByCh := map[byte]Reactor{testCh: NewTestReactor(chDescs, true)}
|
reactorsByCh := map[byte]Reactor{testCh: NewTestReactor(chDescs, true)}
|
||||||
pk := crypto.GenPrivKeyEd25519().Wrap()
|
pk := crypto.GenPrivKeyEd25519()
|
||||||
pc, err := newOutboundPeerConn(addr, config, false, pk)
|
pc, err := newOutboundPeerConn(addr, config, false, pk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package pex
|
package pex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -9,8 +8,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/tendermint/go-amino"
|
||||||
wire "github.com/tendermint/go-wire"
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/p2p"
|
"github.com/tendermint/tendermint/p2p"
|
||||||
@ -165,7 +163,7 @@ func (r *PEXReactor) RemovePeer(p Peer, reason interface{}) {
|
|||||||
|
|
||||||
// Receive implements Reactor by handling incoming PEX messages.
|
// Receive implements Reactor by handling incoming PEX messages.
|
||||||
func (r *PEXReactor) Receive(chID byte, src Peer, msgBytes []byte) {
|
func (r *PEXReactor) Receive(chID byte, src Peer, msgBytes []byte) {
|
||||||
_, msg, err := DecodeMessage(msgBytes)
|
msg, err := DecodeMessage(msgBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Logger.Error("Error decoding message", "src", src, "chId", chID, "msg", msg, "err", err, "bytes", msgBytes)
|
r.Logger.Error("Error decoding message", "src", src, "chId", chID, "msg", msg, "err", err, "bytes", msgBytes)
|
||||||
r.Switch.StopPeerForError(src, err)
|
r.Switch.StopPeerForError(src, err)
|
||||||
@ -235,7 +233,7 @@ func (r *PEXReactor) RequestAddrs(p Peer) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.requestsSent.Set(id, struct{}{})
|
r.requestsSent.Set(id, struct{}{})
|
||||||
p.Send(PexChannel, struct{ PexMessage }{&pexRequestMessage{}})
|
p.Send(PexChannel, cdc.MustMarshalBinary(&pexRequestMessage{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveAddrs adds the given addrs to the addrbook if theres an open
|
// ReceiveAddrs adds the given addrs to the addrbook if theres an open
|
||||||
@ -245,7 +243,7 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error {
|
|||||||
id := string(src.ID())
|
id := string(src.ID())
|
||||||
|
|
||||||
if !r.requestsSent.Has(id) {
|
if !r.requestsSent.Has(id) {
|
||||||
return errors.New("Received unsolicited pexAddrsMessage")
|
return cmn.NewError("Received unsolicited pexAddrsMessage")
|
||||||
}
|
}
|
||||||
|
|
||||||
r.requestsSent.Delete(id)
|
r.requestsSent.Delete(id)
|
||||||
@ -261,7 +259,7 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error {
|
|||||||
|
|
||||||
// SendAddrs sends addrs to the peer.
|
// SendAddrs sends addrs to the peer.
|
||||||
func (r *PEXReactor) SendAddrs(p Peer, netAddrs []*p2p.NetAddress) {
|
func (r *PEXReactor) SendAddrs(p Peer, netAddrs []*p2p.NetAddress) {
|
||||||
p.Send(PexChannel, struct{ PexMessage }{&pexAddrsMessage{Addrs: netAddrs}})
|
p.Send(PexChannel, cdc.MustMarshalBinary(&pexAddrsMessage{Addrs: netAddrs}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetEnsurePeersPeriod sets period to ensure peers connected.
|
// SetEnsurePeersPeriod sets period to ensure peers connected.
|
||||||
@ -583,27 +581,19 @@ func (r *PEXReactor) attemptDisconnects() {
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Messages
|
// Messages
|
||||||
|
|
||||||
const (
|
|
||||||
msgTypeRequest = byte(0x01)
|
|
||||||
msgTypeAddrs = byte(0x02)
|
|
||||||
)
|
|
||||||
|
|
||||||
// PexMessage is a primary type for PEX messages. Underneath, it could contain
|
// PexMessage is a primary type for PEX messages. Underneath, it could contain
|
||||||
// either pexRequestMessage, or pexAddrsMessage messages.
|
// either pexRequestMessage, or pexAddrsMessage messages.
|
||||||
type PexMessage interface{}
|
type PexMessage interface{}
|
||||||
|
|
||||||
var _ = wire.RegisterInterface(
|
func RegisterPexMessage(cdc *amino.Codec) {
|
||||||
struct{ PexMessage }{},
|
cdc.RegisterInterface((*PexMessage)(nil), nil)
|
||||||
wire.ConcreteType{&pexRequestMessage{}, msgTypeRequest},
|
cdc.RegisterConcrete(&pexRequestMessage{}, "tendermint/p2p/PexRequestMessage", nil)
|
||||||
wire.ConcreteType{&pexAddrsMessage{}, msgTypeAddrs},
|
cdc.RegisterConcrete(&pexAddrsMessage{}, "tendermint/p2p/PexAddrsMessage", nil)
|
||||||
)
|
}
|
||||||
|
|
||||||
// DecodeMessage implements interface registered above.
|
// DecodeMessage implements interface registered above.
|
||||||
func DecodeMessage(bz []byte) (msgType byte, msg PexMessage, err error) {
|
func DecodeMessage(bz []byte) (msg PexMessage, err error) {
|
||||||
msgType = bz[0]
|
err = cdc.UnmarshalBinary(bz, &msg)
|
||||||
n := new(int)
|
|
||||||
r := bytes.NewReader(bz)
|
|
||||||
msg = wire.ReadBinary(struct{ PexMessage }{}, r, maxPexMessageSize, n, &err).(struct{ PexMessage }).PexMessage
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
wire "github.com/tendermint/go-wire"
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
"github.com/tendermint/tendermint/p2p"
|
"github.com/tendermint/tendermint/p2p"
|
||||||
"github.com/tendermint/tendermint/p2p/conn"
|
"github.com/tendermint/tendermint/p2p/conn"
|
||||||
@ -114,12 +113,12 @@ func TestPEXReactorReceive(t *testing.T) {
|
|||||||
|
|
||||||
size := book.Size()
|
size := book.Size()
|
||||||
addrs := []*p2p.NetAddress{peer.NodeInfo().NetAddress()}
|
addrs := []*p2p.NetAddress{peer.NodeInfo().NetAddress()}
|
||||||
msg := wire.BinaryBytes(struct{ PexMessage }{&pexAddrsMessage{Addrs: addrs}})
|
msg := cdc.MustMarshalBinary(&pexAddrsMessage{Addrs: addrs})
|
||||||
r.Receive(PexChannel, peer, msg)
|
r.Receive(PexChannel, peer, msg)
|
||||||
assert.Equal(t, size+1, book.Size())
|
assert.Equal(t, size+1, book.Size())
|
||||||
|
|
||||||
msg = wire.BinaryBytes(struct{ PexMessage }{&pexRequestMessage{}})
|
msg = cdc.MustMarshalBinary(&pexRequestMessage{})
|
||||||
r.Receive(PexChannel, peer, msg)
|
r.Receive(PexChannel, peer, msg) // should not panic.
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPEXReactorRequestMessageAbuse(t *testing.T) {
|
func TestPEXReactorRequestMessageAbuse(t *testing.T) {
|
||||||
@ -133,7 +132,7 @@ func TestPEXReactorRequestMessageAbuse(t *testing.T) {
|
|||||||
assert.True(t, sw.Peers().Has(peer.ID()))
|
assert.True(t, sw.Peers().Has(peer.ID()))
|
||||||
|
|
||||||
id := string(peer.ID())
|
id := string(peer.ID())
|
||||||
msg := wire.BinaryBytes(struct{ PexMessage }{&pexRequestMessage{}})
|
msg := cdc.MustMarshalBinary(&pexRequestMessage{})
|
||||||
|
|
||||||
// first time creates the entry
|
// first time creates the entry
|
||||||
r.Receive(PexChannel, peer, msg)
|
r.Receive(PexChannel, peer, msg)
|
||||||
@ -169,7 +168,7 @@ func TestPEXReactorAddrsMessageAbuse(t *testing.T) {
|
|||||||
assert.True(t, sw.Peers().Has(peer.ID()))
|
assert.True(t, sw.Peers().Has(peer.ID()))
|
||||||
|
|
||||||
addrs := []*p2p.NetAddress{peer.NodeInfo().NetAddress()}
|
addrs := []*p2p.NetAddress{peer.NodeInfo().NetAddress()}
|
||||||
msg := wire.BinaryBytes(struct{ PexMessage }{&pexAddrsMessage{Addrs: addrs}})
|
msg := cdc.MustMarshalBinary(&pexAddrsMessage{Addrs: addrs})
|
||||||
|
|
||||||
// receive some addrs. should clear the request
|
// receive some addrs. should clear the request
|
||||||
r.Receive(PexChannel, peer, msg)
|
r.Receive(PexChannel, peer, msg)
|
||||||
@ -302,7 +301,7 @@ func newMockPeer() mockPeer {
|
|||||||
_, netAddr := p2p.CreateRoutableAddr()
|
_, netAddr := p2p.CreateRoutableAddr()
|
||||||
mp := mockPeer{
|
mp := mockPeer{
|
||||||
addr: netAddr,
|
addr: netAddr,
|
||||||
pubKey: crypto.GenPrivKeyEd25519().Wrap().PubKey(),
|
pubKey: crypto.GenPrivKeyEd25519().PubKey(),
|
||||||
}
|
}
|
||||||
mp.BaseService = cmn.NewBaseService(nil, "MockPeer", mp)
|
mp.BaseService = cmn.NewBaseService(nil, "MockPeer", mp)
|
||||||
mp.Start()
|
mp.Start()
|
||||||
@ -318,11 +317,11 @@ func (mp mockPeer) NodeInfo() p2p.NodeInfo {
|
|||||||
ListenAddr: mp.addr.DialString(),
|
ListenAddr: mp.addr.DialString(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (mp mockPeer) Status() conn.ConnectionStatus { return conn.ConnectionStatus{} }
|
func (mp mockPeer) Status() conn.ConnectionStatus { return conn.ConnectionStatus{} }
|
||||||
func (mp mockPeer) Send(byte, interface{}) bool { return false }
|
func (mp mockPeer) Send(byte, []byte) bool { return false }
|
||||||
func (mp mockPeer) TrySend(byte, interface{}) bool { return false }
|
func (mp mockPeer) TrySend(byte, []byte) bool { return false }
|
||||||
func (mp mockPeer) Set(string, interface{}) {}
|
func (mp mockPeer) Set(string, interface{}) {}
|
||||||
func (mp mockPeer) Get(string) interface{} { return nil }
|
func (mp mockPeer) Get(string) interface{} { return nil }
|
||||||
|
|
||||||
func assertPeersWithTimeout(
|
func assertPeersWithTimeout(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
|
11
p2p/pex/wire.go
Normal file
11
p2p/pex/wire.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package pex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tendermint/go-amino"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cdc *amino.Codec = amino.NewCodec()
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterPexMessage(cdc)
|
||||||
|
}
|
@ -8,8 +8,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
"github.com/tendermint/tendermint/p2p/conn"
|
"github.com/tendermint/tendermint/p2p/conn"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
@ -85,7 +83,7 @@ func NewSwitch(config *cfg.P2PConfig) *Switch {
|
|||||||
sw.peerConfig.MConfig.FlushThrottle = time.Duration(config.FlushThrottleTimeout) * time.Millisecond
|
sw.peerConfig.MConfig.FlushThrottle = time.Duration(config.FlushThrottleTimeout) * time.Millisecond
|
||||||
sw.peerConfig.MConfig.SendRate = config.SendRate
|
sw.peerConfig.MConfig.SendRate = config.SendRate
|
||||||
sw.peerConfig.MConfig.RecvRate = config.RecvRate
|
sw.peerConfig.MConfig.RecvRate = config.RecvRate
|
||||||
sw.peerConfig.MConfig.MaxMsgPacketPayloadSize = config.MaxMsgPacketPayloadSize
|
sw.peerConfig.MConfig.MaxPacketMsgPayloadSize = config.MaxPacketMsgPayloadSize
|
||||||
sw.peerConfig.AuthEnc = config.AuthEnc
|
sw.peerConfig.AuthEnc = config.AuthEnc
|
||||||
|
|
||||||
sw.BaseService = *cmn.NewBaseService(nil, "P2P Switch", sw)
|
sw.BaseService = *cmn.NewBaseService(nil, "P2P Switch", sw)
|
||||||
@ -171,7 +169,7 @@ func (sw *Switch) OnStart() error {
|
|||||||
for _, reactor := range sw.reactors {
|
for _, reactor := range sw.reactors {
|
||||||
err := reactor.Start()
|
err := reactor.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to start %v", reactor)
|
return cmn.ErrorWrap(err, "failed to start %v", reactor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Start listeners
|
// Start listeners
|
||||||
@ -206,18 +204,18 @@ func (sw *Switch) OnStop() {
|
|||||||
// Broadcast runs a go routine for each attempted send, which will block trying
|
// Broadcast runs a go routine for each attempted send, which will block trying
|
||||||
// to send for defaultSendTimeoutSeconds. Returns a channel which receives
|
// to send for defaultSendTimeoutSeconds. Returns a channel which receives
|
||||||
// success values for each attempted send (false if times out). Channel will be
|
// success values for each attempted send (false if times out). Channel will be
|
||||||
// closed once msg send to all peers.
|
// closed once msg bytes are sent to all peers (or time out).
|
||||||
//
|
//
|
||||||
// NOTE: Broadcast uses goroutines, so order of broadcast may not be preserved.
|
// NOTE: Broadcast uses goroutines, so order of broadcast may not be preserved.
|
||||||
func (sw *Switch) Broadcast(chID byte, msg interface{}) chan bool {
|
func (sw *Switch) Broadcast(chID byte, msgBytes []byte) chan bool {
|
||||||
successChan := make(chan bool, len(sw.peers.List()))
|
successChan := make(chan bool, len(sw.peers.List()))
|
||||||
sw.Logger.Debug("Broadcast", "channel", chID, "msg", msg)
|
sw.Logger.Debug("Broadcast", "channel", chID, "msgBytes", fmt.Sprintf("%X", msgBytes))
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for _, peer := range sw.peers.List() {
|
for _, peer := range sw.peers.List() {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(peer Peer) {
|
go func(peer Peer) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
success := peer.Send(chID, msg)
|
success := peer.Send(chID, msgBytes)
|
||||||
successChan <- success
|
successChan <- success
|
||||||
}(peer)
|
}(peer)
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
wire "github.com/tendermint/go-wire"
|
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
@ -125,9 +124,9 @@ func TestSwitches(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Lets send some messages
|
// Lets send some messages
|
||||||
ch0Msg := "channel zero"
|
ch0Msg := []byte("channel zero")
|
||||||
ch1Msg := "channel foo"
|
ch1Msg := []byte("channel foo")
|
||||||
ch2Msg := "channel bar"
|
ch2Msg := []byte("channel bar")
|
||||||
|
|
||||||
s1.Broadcast(byte(0x00), ch0Msg)
|
s1.Broadcast(byte(0x00), ch0Msg)
|
||||||
s1.Broadcast(byte(0x01), ch1Msg)
|
s1.Broadcast(byte(0x01), ch1Msg)
|
||||||
@ -138,15 +137,15 @@ func TestSwitches(t *testing.T) {
|
|||||||
assertMsgReceivedWithTimeout(t, ch2Msg, byte(0x02), s2.Reactor("bar").(*TestReactor), 10*time.Millisecond, 5*time.Second)
|
assertMsgReceivedWithTimeout(t, ch2Msg, byte(0x02), s2.Reactor("bar").(*TestReactor), 10*time.Millisecond, 5*time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertMsgReceivedWithTimeout(t *testing.T, msg string, channel byte, reactor *TestReactor, checkPeriod, timeout time.Duration) {
|
func assertMsgReceivedWithTimeout(t *testing.T, msgBytes []byte, channel byte, reactor *TestReactor, checkPeriod, timeout time.Duration) {
|
||||||
ticker := time.NewTicker(checkPeriod)
|
ticker := time.NewTicker(checkPeriod)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
msgs := reactor.getMsgs(channel)
|
msgs := reactor.getMsgs(channel)
|
||||||
if len(msgs) > 0 {
|
if len(msgs) > 0 {
|
||||||
if !bytes.Equal(msgs[0].Bytes, wire.BinaryBytes(msg)) {
|
if !bytes.Equal(msgs[0].Bytes, msgBytes) {
|
||||||
t.Fatalf("Unexpected message bytes. Wanted: %X, Got: %X", wire.BinaryBytes(msg), msgs[0].Bytes)
|
t.Fatalf("Unexpected message bytes. Wanted: %X, Got: %X", msgBytes, msgs[0].Bytes)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -238,7 +237,7 @@ func TestSwitchStopsNonPersistentPeerOnError(t *testing.T) {
|
|||||||
defer sw.Stop()
|
defer sw.Stop()
|
||||||
|
|
||||||
// simulate remote peer
|
// simulate remote peer
|
||||||
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519().Wrap(), Config: DefaultPeerConfig()}
|
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: DefaultPeerConfig()}
|
||||||
rp.Start()
|
rp.Start()
|
||||||
defer rp.Stop()
|
defer rp.Stop()
|
||||||
|
|
||||||
@ -268,7 +267,7 @@ func TestSwitchReconnectsToPersistentPeer(t *testing.T) {
|
|||||||
defer sw.Stop()
|
defer sw.Stop()
|
||||||
|
|
||||||
// simulate remote peer
|
// simulate remote peer
|
||||||
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519().Wrap(), Config: DefaultPeerConfig()}
|
rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: DefaultPeerConfig()}
|
||||||
rp.Start()
|
rp.Start()
|
||||||
defer rp.Stop()
|
defer rp.Stop()
|
||||||
|
|
||||||
@ -338,7 +337,7 @@ func BenchmarkSwitchBroadcast(b *testing.B) {
|
|||||||
// Send random message from foo channel to another
|
// Send random message from foo channel to another
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
chID := byte(i % 4)
|
chID := byte(i % 4)
|
||||||
successChan := s1.Broadcast(chID, "test data")
|
successChan := s1.Broadcast(chID, []byte("test data"))
|
||||||
for s := range successChan {
|
for s := range successChan {
|
||||||
if s {
|
if s {
|
||||||
numSuccess++
|
numSuccess++
|
||||||
|
@ -24,7 +24,7 @@ func CreateRandomPeer(outbound bool) *peer {
|
|||||||
},
|
},
|
||||||
nodeInfo: NodeInfo{
|
nodeInfo: NodeInfo{
|
||||||
ListenAddr: netAddr.DialString(),
|
ListenAddr: netAddr.DialString(),
|
||||||
PubKey: crypto.GenPrivKeyEd25519().Wrap().PubKey(),
|
PubKey: crypto.GenPrivKeyEd25519().PubKey(),
|
||||||
},
|
},
|
||||||
mconn: &conn.MConnection{},
|
mconn: &conn.MConnection{},
|
||||||
}
|
}
|
||||||
@ -131,7 +131,7 @@ func MakeSwitch(cfg *cfg.P2PConfig, i int, network, version string, initSwitch f
|
|||||||
// new switch, add reactors
|
// new switch, add reactors
|
||||||
// TODO: let the config be passed in?
|
// TODO: let the config be passed in?
|
||||||
nodeKey := &NodeKey{
|
nodeKey := &NodeKey{
|
||||||
PrivKey: crypto.GenPrivKeyEd25519().Wrap(),
|
PrivKey: crypto.GenPrivKeyEd25519(),
|
||||||
}
|
}
|
||||||
sw := NewSwitch(cfg)
|
sw := NewSwitch(cfg)
|
||||||
sw.SetLogger(log.TestingLogger())
|
sw.SetLogger(log.TestingLogger())
|
||||||
|
@ -5,8 +5,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
)
|
)
|
||||||
@ -19,26 +17,26 @@ type UPNPCapabilities struct {
|
|||||||
func makeUPNPListener(intPort int, extPort int, logger log.Logger) (NAT, net.Listener, net.IP, error) {
|
func makeUPNPListener(intPort int, extPort int, logger log.Logger) (NAT, net.Listener, net.IP, error) {
|
||||||
nat, err := Discover()
|
nat, err := Discover()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, errors.Errorf("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))
|
logger.Info(cmn.Fmt("ourIP: %v", nat.(*upnpNAT).ourIP))
|
||||||
|
|
||||||
ext, err := nat.GetExternalAddress()
|
ext, err := nat.GetExternalAddress()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nat, nil, nil, errors.Errorf("External address error: %v", err)
|
return nat, nil, nil, fmt.Errorf("External address error: %v", err)
|
||||||
}
|
}
|
||||||
logger.Info(cmn.Fmt("External address: %v", ext))
|
logger.Info(cmn.Fmt("External address: %v", ext))
|
||||||
|
|
||||||
port, err := nat.AddPortMapping("tcp", extPort, intPort, "Tendermint UPnP Probe", 0)
|
port, err := nat.AddPortMapping("tcp", extPort, intPort, "Tendermint UPnP Probe", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nat, nil, ext, errors.Errorf("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))
|
logger.Info(cmn.Fmt("Port mapping mapped: %v", port))
|
||||||
|
|
||||||
// also run the listener, open for all remote addresses.
|
// also run the listener, open for all remote addresses.
|
||||||
listener, err := net.Listen("tcp", fmt.Sprintf(":%v", intPort))
|
listener, err := net.Listen("tcp", fmt.Sprintf(":%v", intPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nat, nil, ext, errors.Errorf("Error establishing listener: %v", err)
|
return nat, nil, ext, fmt.Errorf("Error establishing listener: %v", err)
|
||||||
}
|
}
|
||||||
return nat, listener, ext, nil
|
return nat, listener, ext, nil
|
||||||
}
|
}
|
||||||
|
12
p2p/wire.go
Normal file
12
p2p/wire.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package p2p
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tendermint/go-amino"
|
||||||
|
"github.com/tendermint/go-crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cdc = amino.NewCodec()
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
crypto.RegisterAmino(cdc)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user