eth, p2p: remove EncodeMsg from p2p.MsgWriter
...and make it a top-level function instead. The original idea behind having EncodeMsg in the interface was that implementations might be able to encode RLP data to their underlying writer directly instead of buffering the encoded data. The encoder will buffer anyway, so that doesn't matter anymore. Given the recent problems with EncodeMsg (copy-pasted implementation bug) I'd rather implement once, correctly.
This commit is contained in:
parent
36e1e5f151
commit
eb0e7b1b81
|
@ -140,7 +140,7 @@ func (self *ethProtocol) handle() error {
|
||||||
return self.protoError(ErrDecode, "->msg %v: %v", msg, err)
|
return self.protoError(ErrDecode, "->msg %v: %v", msg, err)
|
||||||
}
|
}
|
||||||
hashes := self.chainManager.GetBlockHashesFromHash(request.Hash, request.Amount)
|
hashes := self.chainManager.GetBlockHashesFromHash(request.Hash, request.Amount)
|
||||||
return self.rw.EncodeMsg(BlockHashesMsg, ethutil.ByteSliceToInterface(hashes)...)
|
return p2p.EncodeMsg(self.rw, BlockHashesMsg, ethutil.ByteSliceToInterface(hashes)...)
|
||||||
|
|
||||||
case BlockHashesMsg:
|
case BlockHashesMsg:
|
||||||
// TODO: redo using lazy decode , this way very inefficient on known chains
|
// TODO: redo using lazy decode , this way very inefficient on known chains
|
||||||
|
@ -185,7 +185,7 @@ func (self *ethProtocol) handle() error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self.rw.EncodeMsg(BlocksMsg, blocks...)
|
return p2p.EncodeMsg(self.rw, BlocksMsg, blocks...)
|
||||||
|
|
||||||
case BlocksMsg:
|
case BlocksMsg:
|
||||||
msgStream := rlp.NewStream(msg.Payload)
|
msgStream := rlp.NewStream(msg.Payload)
|
||||||
|
@ -298,12 +298,12 @@ func (self *ethProtocol) handleStatus() error {
|
||||||
|
|
||||||
func (self *ethProtocol) requestBlockHashes(from []byte) error {
|
func (self *ethProtocol) requestBlockHashes(from []byte) error {
|
||||||
self.peer.Debugf("fetching hashes (%d) %x...\n", blockHashesBatchSize, from[0:4])
|
self.peer.Debugf("fetching hashes (%d) %x...\n", blockHashesBatchSize, from[0:4])
|
||||||
return self.rw.EncodeMsg(GetBlockHashesMsg, interface{}(from), uint64(blockHashesBatchSize))
|
return p2p.EncodeMsg(self.rw, GetBlockHashesMsg, interface{}(from), uint64(blockHashesBatchSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ethProtocol) requestBlocks(hashes [][]byte) error {
|
func (self *ethProtocol) requestBlocks(hashes [][]byte) error {
|
||||||
self.peer.Debugf("fetching %v blocks", len(hashes))
|
self.peer.Debugf("fetching %v blocks", len(hashes))
|
||||||
return self.rw.EncodeMsg(GetBlocksMsg, ethutil.ByteSliceToInterface(hashes)...)
|
return p2p.EncodeMsg(self.rw, GetBlocksMsg, ethutil.ByteSliceToInterface(hashes)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ethProtocol) protoError(code int, format string, params ...interface{}) (err *protocolError) {
|
func (self *ethProtocol) protoError(code int, format string, params ...interface{}) (err *protocolError) {
|
||||||
|
|
|
@ -41,10 +41,6 @@ func (self *testMsgReadWriter) WriteMsg(msg p2p.Msg) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *testMsgReadWriter) EncodeMsg(code uint64, data ...interface{}) error {
|
|
||||||
return self.WriteMsg(p2p.NewMsg(code, data...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *testMsgReadWriter) ReadMsg() (p2p.Msg, error) {
|
func (self *testMsgReadWriter) ReadMsg() (p2p.Msg, error) {
|
||||||
msg, ok := <-self.in
|
msg, ok := <-self.in
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -71,14 +71,11 @@ type MsgReader interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type MsgWriter interface {
|
type MsgWriter interface {
|
||||||
// WriteMsg sends an existing message.
|
// WriteMsg sends a message. It will block until the message's
|
||||||
// The Payload reader of the message is consumed.
|
// Payload has been consumed by the other end.
|
||||||
|
//
|
||||||
// Note that messages can be sent only once.
|
// Note that messages can be sent only once.
|
||||||
WriteMsg(Msg) error
|
WriteMsg(Msg) error
|
||||||
|
|
||||||
// EncodeMsg writes an RLP-encoded message with the given
|
|
||||||
// code and data elements.
|
|
||||||
EncodeMsg(code uint64, data ...interface{}) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgReadWriter provides reading and writing of encoded messages.
|
// MsgReadWriter provides reading and writing of encoded messages.
|
||||||
|
@ -87,6 +84,12 @@ type MsgReadWriter interface {
|
||||||
MsgWriter
|
MsgWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncodeMsg writes an RLP-encoded message with the given code and
|
||||||
|
// data elements.
|
||||||
|
func EncodeMsg(w MsgWriter, code uint64, data ...interface{}) error {
|
||||||
|
return w.WriteMsg(NewMsg(code, data...))
|
||||||
|
}
|
||||||
|
|
||||||
var magicToken = []byte{34, 64, 8, 145}
|
var magicToken = []byte{34, 64, 8, 145}
|
||||||
|
|
||||||
func writeMsg(w io.Writer, msg Msg) error {
|
func writeMsg(w io.Writer, msg Msg) error {
|
||||||
|
@ -209,11 +212,6 @@ func (p *MsgPipeRW) WriteMsg(msg Msg) error {
|
||||||
return ErrPipeClosed
|
return ErrPipeClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeMsg is a convenient shorthand for sending an RLP-encoded message.
|
|
||||||
func (p *MsgPipeRW) EncodeMsg(code uint64, data ...interface{}) error {
|
|
||||||
return p.WriteMsg(NewMsg(code, data...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadMsg returns a message sent on the other end of the pipe.
|
// ReadMsg returns a message sent on the other end of the pipe.
|
||||||
func (p *MsgPipeRW) ReadMsg() (Msg, error) {
|
func (p *MsgPipeRW) ReadMsg() (Msg, error) {
|
||||||
if atomic.LoadInt32(p.closed) == 0 {
|
if atomic.LoadInt32(p.closed) == 0 {
|
||||||
|
|
|
@ -75,8 +75,8 @@ func TestDecodeRealMsg(t *testing.T) {
|
||||||
func ExampleMsgPipe() {
|
func ExampleMsgPipe() {
|
||||||
rw1, rw2 := MsgPipe()
|
rw1, rw2 := MsgPipe()
|
||||||
go func() {
|
go func() {
|
||||||
rw1.EncodeMsg(8, []byte{0, 0})
|
EncodeMsg(rw1, 8, []byte{0, 0})
|
||||||
rw1.EncodeMsg(5, []byte{1, 1})
|
EncodeMsg(rw1, 5, []byte{1, 1})
|
||||||
rw1.Close()
|
rw1.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ loop:
|
||||||
rw1, rw2 := MsgPipe()
|
rw1, rw2 := MsgPipe()
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
if err := rw1.EncodeMsg(1); err == nil {
|
if err := EncodeMsg(rw1, 1); err == nil {
|
||||||
t.Error("EncodeMsg returned nil error")
|
t.Error("EncodeMsg returned nil error")
|
||||||
} else if err != ErrPipeClosed {
|
} else if err != ErrPipeClosed {
|
||||||
t.Error("EncodeMsg returned wrong error: got %v, want %v", err, ErrPipeClosed)
|
t.Error("EncodeMsg returned wrong error: got %v, want %v", err, ErrPipeClosed)
|
||||||
|
|
|
@ -126,10 +126,10 @@ func TestPeerProtoEncodeMsg(t *testing.T) {
|
||||||
Name: "a",
|
Name: "a",
|
||||||
Length: 2,
|
Length: 2,
|
||||||
Run: func(peer *Peer, rw MsgReadWriter) error {
|
Run: func(peer *Peer, rw MsgReadWriter) error {
|
||||||
if err := rw.EncodeMsg(2); err == nil {
|
if err := EncodeMsg(rw, 2); err == nil {
|
||||||
t.Error("expected error for out-of-range msg code, got nil")
|
t.Error("expected error for out-of-range msg code, got nil")
|
||||||
}
|
}
|
||||||
if err := rw.EncodeMsg(1, "foo", "bar"); err != nil {
|
if err := EncodeMsg(rw, 1, "foo", "bar"); err != nil {
|
||||||
t.Errorf("write error: %v", err)
|
t.Errorf("write error: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -119,14 +119,14 @@ func (bp *baseProtocol) loop(quit <-chan error) error {
|
||||||
|
|
||||||
getPeersTick := time.NewTicker(10 * time.Second)
|
getPeersTick := time.NewTicker(10 * time.Second)
|
||||||
defer getPeersTick.Stop()
|
defer getPeersTick.Stop()
|
||||||
err := bp.rw.EncodeMsg(getPeersMsg)
|
err := EncodeMsg(bp.rw, getPeersMsg)
|
||||||
|
|
||||||
for err == nil {
|
for err == nil {
|
||||||
select {
|
select {
|
||||||
case err = <-quit:
|
case err = <-quit:
|
||||||
return err
|
return err
|
||||||
case <-getPeersTick.C:
|
case <-getPeersTick.C:
|
||||||
err = bp.rw.EncodeMsg(getPeersMsg)
|
err = EncodeMsg(bp.rw, getPeersMsg)
|
||||||
case event := <-activity.Chan():
|
case event := <-activity.Chan():
|
||||||
ping.Reset(pingTimeout)
|
ping.Reset(pingTimeout)
|
||||||
lastActive = event.(time.Time)
|
lastActive = event.(time.Time)
|
||||||
|
@ -134,7 +134,7 @@ func (bp *baseProtocol) loop(quit <-chan error) error {
|
||||||
if lastActive.Add(pingTimeout * 2).Before(t) {
|
if lastActive.Add(pingTimeout * 2).Before(t) {
|
||||||
err = newPeerError(errPingTimeout, "")
|
err = newPeerError(errPingTimeout, "")
|
||||||
} else if lastActive.Add(pingTimeout).Before(t) {
|
} else if lastActive.Add(pingTimeout).Before(t) {
|
||||||
err = bp.rw.EncodeMsg(pingMsg)
|
err = EncodeMsg(bp.rw, pingMsg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ func (bp *baseProtocol) handle(rw MsgReadWriter) error {
|
||||||
return discRequestedError(reason[0])
|
return discRequestedError(reason[0])
|
||||||
|
|
||||||
case pingMsg:
|
case pingMsg:
|
||||||
return bp.rw.EncodeMsg(pongMsg)
|
return EncodeMsg(bp.rw, pongMsg)
|
||||||
|
|
||||||
case pongMsg:
|
case pongMsg:
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ func (bp *baseProtocol) handle(rw MsgReadWriter) error {
|
||||||
//
|
//
|
||||||
// TODO: add event mechanism to notify baseProtocol for new peers
|
// TODO: add event mechanism to notify baseProtocol for new peers
|
||||||
if len(peers) > 0 {
|
if len(peers) > 0 {
|
||||||
return bp.rw.EncodeMsg(peersMsg, peers...)
|
return EncodeMsg(bp.rw, peersMsg, peers...)
|
||||||
}
|
}
|
||||||
|
|
||||||
case peersMsg:
|
case peersMsg:
|
||||||
|
|
|
@ -93,7 +93,7 @@ func TestBaseProtocolDisconnect(t *testing.T) {
|
||||||
if err := expectMsg(rw2, handshakeMsg); err != nil {
|
if err := expectMsg(rw2, handshakeMsg); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
err := rw2.EncodeMsg(handshakeMsg,
|
err := EncodeMsg(rw2, handshakeMsg,
|
||||||
baseProtocolVersion,
|
baseProtocolVersion,
|
||||||
"",
|
"",
|
||||||
[]interface{}{},
|
[]interface{}{},
|
||||||
|
@ -106,7 +106,7 @@ func TestBaseProtocolDisconnect(t *testing.T) {
|
||||||
if err := expectMsg(rw2, getPeersMsg); err != nil {
|
if err := expectMsg(rw2, getPeersMsg); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
if err := rw2.EncodeMsg(discMsg, DiscQuitting); err != nil {
|
if err := EncodeMsg(rw2, discMsg, DiscQuitting); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue