diff --git a/peer/log.go b/peer/log.go index 31b18708f..9d3e0f4fc 100644 --- a/peer/log.go +++ b/peer/log.go @@ -132,12 +132,6 @@ func messageSummary(msg wire.Message) string { case *wire.MsgPong: // No summary - perhaps add nonce. - case *wire.MsgAlert: - // No summary. - - case *wire.MsgMemPool: - // No summary. - case *wire.MsgTx: return fmt.Sprintf("hash %s, %d inputs, %d outputs, lock %s", msg.TxID(), len(msg.TxIn), len(msg.TxOut), diff --git a/peer/peer.go b/peer/peer.go index 1ce739cc8..6a5ed3f52 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -111,12 +111,6 @@ type MessageListeners struct { // OnPong is invoked when a peer receives a pong bitcoin message. OnPong func(p *Peer, msg *wire.MsgPong) - // OnAlert is invoked when a peer receives an alert bitcoin message. - OnAlert func(p *Peer, msg *wire.MsgAlert) - - // OnMemPool is invoked when a peer receives a mempool bitcoin message. - OnMemPool func(p *Peer, msg *wire.MsgMemPool) - // OnTx is invoked when a peer receives a tx bitcoin message. OnTx func(p *Peer, msg *wire.MsgTx) @@ -1207,10 +1201,6 @@ func (p *Peer) maybeAddDeadline(pendingResponses map[string]time.Time, msgCmd st // Expects a verack message. pendingResponses[wire.CmdVerAck] = deadline - case wire.CmdMemPool: - // Expects an inv message. - pendingResponses[wire.CmdInv] = deadline - case wire.CmdGetBlockInvs: // Expects an inv message. pendingResponses[wire.CmdInv] = deadline @@ -1477,16 +1467,6 @@ out: p.cfg.Listeners.OnPong(p, msg) } - case *wire.MsgAlert: - if p.cfg.Listeners.OnAlert != nil { - p.cfg.Listeners.OnAlert(p, msg) - } - - case *wire.MsgMemPool: - if p.cfg.Listeners.OnMemPool != nil { - p.cfg.Listeners.OnMemPool(p, msg) - } - case *wire.MsgTx: if p.cfg.Listeners.OnTx != nil { p.cfg.Listeners.OnTx(p, msg) diff --git a/peer/peer_test.go b/peer/peer_test.go index 4076a8ac4..d79d896a3 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -351,12 +351,6 @@ func TestPeerListeners(t *testing.T) { OnPong: func(p *peer.Peer, msg *wire.MsgPong) { ok <- msg }, - OnAlert: func(p *peer.Peer, msg *wire.MsgAlert) { - ok <- msg - }, - OnMemPool: func(p *peer.Peer, msg *wire.MsgMemPool) { - ok <- msg - }, OnTx: func(p *peer.Peer, msg *wire.MsgTx) { ok <- msg }, @@ -479,14 +473,6 @@ func TestPeerListeners(t *testing.T) { "OnPong", wire.NewMsgPong(42), }, - { - "OnAlert", - wire.NewMsgAlert([]byte("payload"), []byte("signature")), - }, - { - "OnMemPool", - wire.NewMsgMemPool(), - }, { "OnTx", wire.NewNativeMsgTx(wire.TxVersion, nil, nil), @@ -692,7 +678,6 @@ func TestOutboundPeer(t *testing.T) { // Test Queue Messages p2.QueueMessage(wire.NewMsgGetAddr(false, nil), nil) p2.QueueMessage(wire.NewMsgPing(1), nil) - p2.QueueMessage(wire.NewMsgMemPool(), nil) p2.QueueMessage(wire.NewMsgGetData(), nil) p2.QueueMessage(wire.NewMsgGetHeaders(&daghash.ZeroHash, &daghash.ZeroHash), nil) p2.QueueMessage(wire.NewMsgFeeFilter(20000), nil) diff --git a/server/p2p/on_mempool.go b/server/p2p/on_mempool.go deleted file mode 100644 index b389d6207..000000000 --- a/server/p2p/on_mempool.go +++ /dev/null @@ -1,55 +0,0 @@ -package p2p - -import ( - "github.com/daglabs/btcd/peer" - "github.com/daglabs/btcd/util/daghash" - "github.com/daglabs/btcd/wire" -) - -// OnMemPool is invoked when a peer receives a mempool bitcoin message. -// It creates and sends an inventory message with the contents of the memory -// pool up to the maximum inventory allowed per message. When the peer has a -// bloom filter loaded, the contents are filtered accordingly. -func (sp *Peer) OnMemPool(_ *peer.Peer, msg *wire.MsgMemPool) { - // Only allow mempool requests if the server has bloom filtering - // enabled. - if sp.server.services&wire.SFNodeBloom != wire.SFNodeBloom { - peerLog.Debugf("peer %s sent mempool request with bloom "+ - "filtering disabled -- disconnecting", sp) - sp.Disconnect() - return - } - - // A decaying ban score increase is applied to prevent flooding. - // The ban score accumulates and passes the ban threshold if a burst of - // mempool messages comes from a peer. The score decays each minute to - // half of its value. - sp.addBanScore(0, 33, "mempool") - - // Generate inventory message with the available transactions in the - // transaction memory pool. Limit it to the max allowed inventory - // per message. The NewMsgInvSizeHint function automatically limits - // the passed hint to the maximum allowed, so it's safe to pass it - // without double checking it here. - txMemPool := sp.server.TxMemPool - txDescs := txMemPool.TxDescs() - invMsg := wire.NewMsgInvSizeHint(uint(len(txDescs))) - - for _, txDesc := range txDescs { - // Either add all transactions when there is no bloom filter, - // or only the transactions that match the filter when there is - // one. - if !sp.filter.IsLoaded() || sp.filter.MatchTxAndUpdate(txDesc.Tx) { - iv := wire.NewInvVect(wire.InvTypeTx, (*daghash.Hash)(txDesc.Tx.ID())) - invMsg.AddInvVect(iv) - if len(invMsg.InvList)+1 > wire.MaxInvPerMsg { - break - } - } - } - - // Send the inventory message if there is anything to send. - if len(invMsg.InvList) > 0 { - sp.QueueMessage(invMsg, nil) - } -} diff --git a/server/p2p/p2p.go b/server/p2p/p2p.go index 01ab892b2..9c9887745 100644 --- a/server/p2p/p2p.go +++ b/server/p2p/p2p.go @@ -1062,7 +1062,6 @@ func newPeerConfig(sp *Peer) *peer.Config { return &peer.Config{ Listeners: peer.MessageListeners{ OnVersion: sp.OnVersion, - OnMemPool: sp.OnMemPool, OnTx: sp.OnTx, OnBlock: sp.OnBlock, OnInv: sp.OnInv, @@ -1083,12 +1082,6 @@ func newPeerConfig(sp *Peer) *peer.Config { OnAddr: sp.OnAddr, OnRead: sp.OnRead, OnWrite: sp.OnWrite, - - // Note: The reference client currently bans peers that send alerts - // not signed with its key. We could verify against their key, but - // since the reference client is currently unwilling to support - // other implementations' alert messages, we will not relay theirs. - OnAlert: nil, }, SelectedTip: sp.selectedTip, BlockExists: sp.blockExists, diff --git a/wire/message.go b/wire/message.go index e64f92bc1..e2a481ef4 100644 --- a/wire/message.go +++ b/wire/message.go @@ -43,8 +43,6 @@ const ( CmdHeaders = "headers" CmdPing = "ping" CmdPong = "pong" - CmdAlert = "alert" - CmdMemPool = "mempool" CmdFilterAdd = "filteradd" CmdFilterClear = "filterclear" CmdFilterLoad = "filterload" @@ -126,12 +124,6 @@ func makeEmptyMessage(command string) (Message, error) { case CmdHeaders: msg = &MsgHeaders{} - case CmdAlert: - msg = &MsgAlert{} - - case CmdMemPool: - msg = &MsgMemPool{} - case CmdFilterAdd: msg = &MsgFilterAdd{} diff --git a/wire/message_test.go b/wire/message_test.go index 4107cde94..479409621 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -65,8 +65,6 @@ func TestMessage(t *testing.T) { msgSendHeaders := NewMsgSendHeaders() msgFeeFilter := NewMsgFeeFilter(123456) msgHeaders := NewMsgHeaders() - msgAlert := NewMsgAlert([]byte("payload"), []byte("signature")) - msgMemPool := NewMsgMemPool() msgFilterAdd := NewMsgFilterAdd([]byte{0x01}) msgFilterClear := NewMsgFilterClear() msgFilterLoad := NewMsgFilterLoad([]byte{0x01}, 10, 0, BloomUpdateNone) @@ -106,8 +104,6 @@ func TestMessage(t *testing.T) { {msgSendHeaders, msgSendHeaders, pver, MainNet, 24}, {msgFeeFilter, msgFeeFilter, pver, MainNet, 32}, {msgHeaders, msgHeaders, pver, MainNet, 25}, - {msgAlert, msgAlert, pver, MainNet, 42}, - {msgMemPool, msgMemPool, pver, MainNet, 24}, {msgFilterAdd, msgFilterAdd, pver, MainNet, 26}, {msgFilterClear, msgFilterClear, pver, MainNet, 24}, {msgFilterLoad, msgFilterLoad, pver, MainNet, 35}, diff --git a/wire/msgalert.go b/wire/msgalert.go deleted file mode 100644 index 78a2f4340..000000000 --- a/wire/msgalert.go +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright (c) 2013-2015 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "bytes" - "fmt" - "io" -) - -// MsgAlert contains a payload and a signature: -// -// =============================================== -// | Field | Data Type | Size | -// =============================================== -// | payload | []uchar | ? | -// ----------------------------------------------- -// | signature | []uchar | ? | -// ----------------------------------------------- -// -// Here payload is an Alert serialized into a byte array to ensure that -// versions using incompatible alert formats can still relay -// alerts among one another. -// -// An Alert is the payload deserialized as follows: -// -// =============================================== -// | Field | Data Type | Size | -// =============================================== -// | Version | int32 | 4 | -// ----------------------------------------------- -// | RelayUntil | int64 | 8 | -// ----------------------------------------------- -// | Expiration | int64 | 8 | -// ----------------------------------------------- -// | ID | int32 | 4 | -// ----------------------------------------------- -// | Cancel | int32 | 4 | -// ----------------------------------------------- -// | SetCancel | set | ? | -// ----------------------------------------------- -// | MinVer | int32 | 4 | -// ----------------------------------------------- -// | MaxVer | int32 | 4 | -// ----------------------------------------------- -// | SetSubVer | set | ? | -// ----------------------------------------------- -// | Priority | int32 | 4 | -// ----------------------------------------------- -// | Comment | string | ? | -// ----------------------------------------------- -// | StatusBar | string | ? | -// ----------------------------------------------- -// | Reserved | string | ? | -// ----------------------------------------------- -// | Total (Fixed) | 45 | -// ----------------------------------------------- -// -// NOTE: -// * string is a VarString i.e VarInt length followed by the string itself -// * set is a VarInt followed by as many number of strings -// * set is a VarInt followed by as many number of ints -// * fixedAlertSize = 40 + 5*min(VarInt) = 40 + 5*1 = 45 -// -// Now we can define bounds on Alert size, SetCancel and SetSubVer - -// Fixed size of the alert payload -const fixedAlertSize = 45 - -// maxSignatureSize is the max size of an ECDSA signature. -// NOTE: Since this size is fixed and < 255, the size of VarInt required = 1. -const maxSignatureSize = 72 - -// maxAlertSize is the maximum size an alert. -// -// MessagePayload = VarInt(Alert) + Alert + VarInt(Signature) + Signature -// MaxMessagePayload = maxAlertSize + max(VarInt) + maxSignatureSize + 1 -const maxAlertSize = MaxMessagePayload - maxSignatureSize - MaxVarIntPayload - 1 - -// maxCountSetCancel is the maximum number of cancel IDs that could possibly -// fit into a maximum size alert. -// -// maxAlertSize = fixedAlertSize + max(SetCancel) + max(SetSubVer) + 3*(string) -// for caculating maximum number of cancel IDs, set all other var sizes to 0 -// maxAlertSize = fixedAlertSize + (MaxVarIntPayload-1) + x*sizeOf(int32) -// x = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + 1) / 4 -const maxCountSetCancel = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + 1) / 4 - -// maxCountSetSubVer is the maximum number of subversions that could possibly -// fit into a maximum size alert. -// -// maxAlertSize = fixedAlertSize + max(SetCancel) + max(SetSubVer) + 3*(string) -// for caculating maximum number of subversions, set all other var sizes to 0 -// maxAlertSize = fixedAlertSize + (MaxVarIntPayload-1) + x*sizeOf(string) -// x = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + 1) / sizeOf(string) -// subversion would typically be something like "/Satoshi:0.7.2/" (15 bytes) -// so assuming < 255 bytes, sizeOf(string) = sizeOf(uint8) + 255 = 256 -const maxCountSetSubVer = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + 1) / 256 - -// Alert contains the data deserialized from the MsgAlert payload. -type Alert struct { - // Alert format version - Version int32 - - // Timestamp beyond which nodes should stop relaying this alert - RelayUntil int64 - - // Timestamp beyond which this alert is no longer in effect and - // should be ignored - Expiration int64 - - // A unique ID number for this alert - ID int32 - - // All alerts with an ID less than or equal to this number should - // cancelled, deleted and not accepted in the future - Cancel int32 - - // All alert IDs contained in this set should be cancelled as above - SetCancel []int32 - - // This alert only applies to versions greater than or equal to this - // version. Other versions should still relay it. - MinVer int32 - - // This alert only applies to versions less than or equal to this version. - // Other versions should still relay it. - MaxVer int32 - - // If this set contains any elements, then only nodes that have their - // subVer contained in this set are affected by the alert. Other versions - // should still relay it. - SetSubVer []string - - // Relative priority compared to other alerts - Priority int32 - - // A comment on the alert that is not displayed - Comment string - - // The alert message that is displayed to the user - StatusBar string - - // Reserved - Reserved string -} - -// Serialize encodes the alert to w using the alert protocol encoding format. -func (alert *Alert) Serialize(w io.Writer, pver uint32) error { - err := writeElements(w, alert.Version, alert.RelayUntil, - alert.Expiration, alert.ID, alert.Cancel) - if err != nil { - return err - } - - count := len(alert.SetCancel) - if count > maxCountSetCancel { - str := fmt.Sprintf("too many cancel alert IDs for alert "+ - "[count %d, max %d]", count, maxCountSetCancel) - return messageError("Alert.Serialize", str) - } - err = WriteVarInt(w, uint64(count)) - if err != nil { - return err - } - for i := 0; i < count; i++ { - err = WriteElement(w, alert.SetCancel[i]) - if err != nil { - return err - } - } - - err = writeElements(w, alert.MinVer, alert.MaxVer) - if err != nil { - return err - } - - count = len(alert.SetSubVer) - if count > maxCountSetSubVer { - str := fmt.Sprintf("too many sub versions for alert "+ - "[count %d, max %d]", count, maxCountSetSubVer) - return messageError("Alert.Serialize", str) - } - err = WriteVarInt(w, uint64(count)) - if err != nil { - return err - } - for i := 0; i < count; i++ { - err = WriteVarString(w, alert.SetSubVer[i]) - if err != nil { - return err - } - } - - err = WriteElement(w, alert.Priority) - if err != nil { - return err - } - err = WriteVarString(w, alert.Comment) - if err != nil { - return err - } - err = WriteVarString(w, alert.StatusBar) - if err != nil { - return err - } - return WriteVarString(w, alert.Reserved) -} - -// Deserialize decodes from r into the receiver using the alert protocol -// encoding format. -func (alert *Alert) Deserialize(r io.Reader, pver uint32) error { - err := readElements(r, &alert.Version, &alert.RelayUntil, - &alert.Expiration, &alert.ID, &alert.Cancel) - if err != nil { - return err - } - - // SetCancel: first read a VarInt that contains - // count - the number of Cancel IDs, then - // iterate count times and read them - count, err := ReadVarInt(r) - if err != nil { - return err - } - if count > maxCountSetCancel { - str := fmt.Sprintf("too many cancel alert IDs for alert "+ - "[count %d, max %d]", count, maxCountSetCancel) - return messageError("Alert.Deserialize", str) - } - alert.SetCancel = make([]int32, count) - for i := 0; i < int(count); i++ { - err := ReadElement(r, &alert.SetCancel[i]) - if err != nil { - return err - } - } - - err = readElements(r, &alert.MinVer, &alert.MaxVer) - if err != nil { - return err - } - - // SetSubVer: similar to SetCancel - // but read count number of sub-version strings - count, err = ReadVarInt(r) - if err != nil { - return err - } - if count > maxCountSetSubVer { - str := fmt.Sprintf("too many sub versions for alert "+ - "[count %d, max %d]", count, maxCountSetSubVer) - return messageError("Alert.Deserialize", str) - } - alert.SetSubVer = make([]string, count) - for i := 0; i < int(count); i++ { - alert.SetSubVer[i], err = ReadVarString(r, pver) - if err != nil { - return err - } - } - - err = ReadElement(r, &alert.Priority) - if err != nil { - return err - } - alert.Comment, err = ReadVarString(r, pver) - if err != nil { - return err - } - alert.StatusBar, err = ReadVarString(r, pver) - if err != nil { - return err - } - alert.Reserved, err = ReadVarString(r, pver) - return err -} - -// NewAlert returns an new Alert with values provided. -func NewAlert(version int32, relayUntil int64, expiration int64, - id int32, cancel int32, setCancel []int32, minVer int32, - maxVer int32, setSubVer []string, priority int32, comment string, - statusBar string) *Alert { - return &Alert{ - Version: version, - RelayUntil: relayUntil, - Expiration: expiration, - ID: id, - Cancel: cancel, - SetCancel: setCancel, - MinVer: minVer, - MaxVer: maxVer, - SetSubVer: setSubVer, - Priority: priority, - Comment: comment, - StatusBar: statusBar, - Reserved: "", - } -} - -// NewAlertFromPayload returns an Alert with values deserialized from the -// serialized payload. -func NewAlertFromPayload(serializedPayload []byte, pver uint32) (*Alert, error) { - var alert Alert - r := bytes.NewReader(serializedPayload) - err := alert.Deserialize(r, pver) - if err != nil { - return nil, err - } - return &alert, nil -} - -// MsgAlert implements the Message interface and defines a bitcoin alert -// message. -// -// This is a signed message that provides notifications that the client should -// display if the signature matches the key. bitcoind/bitcoin-qt only checks -// against a signature from the core developers. -type MsgAlert struct { - // SerializedPayload is the alert payload serialized as a string so that the - // version can change but the Alert can still be passed on by older - // clients. - SerializedPayload []byte - - // Signature is the ECDSA signature of the message. - Signature []byte - - // Deserialized Payload - Payload *Alert -} - -// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. -// This is part of the Message interface implementation. -func (msg *MsgAlert) BtcDecode(r io.Reader, pver uint32) error { - var err error - - msg.SerializedPayload, err = ReadVarBytes(r, pver, MaxMessagePayload, - "alert serialized payload") - if err != nil { - return err - } - - msg.Payload, err = NewAlertFromPayload(msg.SerializedPayload, pver) - if err != nil { - msg.Payload = nil - } - - msg.Signature, err = ReadVarBytes(r, pver, MaxMessagePayload, - "alert signature") - return err -} - -// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. -// This is part of the Message interface implementation. -func (msg *MsgAlert) BtcEncode(w io.Writer, pver uint32) error { - var err error - var serializedpayload []byte - if msg.Payload != nil { - // try to Serialize Payload if possible - r := new(bytes.Buffer) - err = msg.Payload.Serialize(r, pver) - if err != nil { - // Serialize failed - ignore & fallback - // to SerializedPayload - serializedpayload = msg.SerializedPayload - } else { - serializedpayload = r.Bytes() - } - } else { - serializedpayload = msg.SerializedPayload - } - slen := uint64(len(serializedpayload)) - if slen == 0 { - return messageError("MsgAlert.BtcEncode", "empty serialized payload") - } - err = WriteVarBytes(w, pver, serializedpayload) - if err != nil { - return err - } - return WriteVarBytes(w, pver, msg.Signature) -} - -// Command returns the protocol command string for the message. This is part -// of the Message interface implementation. -func (msg *MsgAlert) Command() string { - return CmdAlert -} - -// MaxPayloadLength returns the maximum length the payload can be for the -// receiver. This is part of the Message interface implementation. -func (msg *MsgAlert) MaxPayloadLength(pver uint32) uint32 { - // Since this can vary depending on the message, make it the max - // size allowed. - return MaxMessagePayload -} - -// NewMsgAlert returns a new bitcoin alert message that conforms to the Message -// interface. See MsgAlert for details. -func NewMsgAlert(serializedPayload []byte, signature []byte) *MsgAlert { - return &MsgAlert{ - SerializedPayload: serializedPayload, - Signature: signature, - Payload: nil, - } -} diff --git a/wire/msgalert_test.go b/wire/msgalert_test.go deleted file mode 100644 index a5e503700..000000000 --- a/wire/msgalert_test.go +++ /dev/null @@ -1,434 +0,0 @@ -// Copyright (c) 2013-2016 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "bytes" - "io" - "reflect" - "testing" - - "github.com/davecgh/go-spew/spew" -) - -// TestMsgAlert tests the MsgAlert API. -func TestMsgAlert(t *testing.T) { - pver := ProtocolVersion - serializedpayload := []byte("some message") - signature := []byte("some sig") - - // Ensure we get the same payload and signature back out. - msg := NewMsgAlert(serializedpayload, signature) - if !reflect.DeepEqual(msg.SerializedPayload, serializedpayload) { - t.Errorf("NewMsgAlert: wrong serializedpayload - got %v, want %v", - msg.SerializedPayload, serializedpayload) - } - if !reflect.DeepEqual(msg.Signature, signature) { - t.Errorf("NewMsgAlert: wrong signature - got %v, want %v", - msg.Signature, signature) - } - - // Ensure the command is expected value. - wantCmd := "alert" - if cmd := msg.Command(); cmd != wantCmd { - t.Errorf("NewMsgAlert: wrong command - got %v want %v", - cmd, wantCmd) - } - - // Ensure max payload is expected value. - wantPayload := uint32(1024 * 1024 * 32) - maxPayload := msg.MaxPayloadLength(pver) - if maxPayload != wantPayload { - t.Errorf("MaxPayloadLength: wrong max payload length for "+ - "protocol version %d - got %v, want %v", pver, - maxPayload, wantPayload) - } - - // Test BtcEncode with Payload == nil - var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) - if err != nil { - t.Error(err.Error()) - } - // expected = 0x0c + serializedpayload + 0x08 + signature - expectedBuf := append([]byte{0x0c}, serializedpayload...) - expectedBuf = append(expectedBuf, []byte{0x08}...) - expectedBuf = append(expectedBuf, signature...) - if !bytes.Equal(buf.Bytes(), expectedBuf) { - t.Errorf("BtcEncode got: %s want: %s", - spew.Sdump(buf.Bytes()), spew.Sdump(expectedBuf)) - } - - // Test BtcEncode with Payload != nil - // note: Payload is an empty Alert but not nil - msg.Payload = new(Alert) - buf = *new(bytes.Buffer) - err = msg.BtcEncode(&buf, pver) - if err != nil { - t.Error(err.Error()) - } - // empty Alert is 45 null bytes, see Alert comments - // for details - // expected = 0x2d + 45*0x00 + 0x08 + signature - expectedBuf = append([]byte{0x2d}, bytes.Repeat([]byte{0x00}, 45)...) - expectedBuf = append(expectedBuf, []byte{0x08}...) - expectedBuf = append(expectedBuf, signature...) - if !bytes.Equal(buf.Bytes(), expectedBuf) { - t.Errorf("BtcEncode got: %s want: %s", - spew.Sdump(buf.Bytes()), spew.Sdump(expectedBuf)) - } -} - -// TestMsgAlertWire tests the MsgAlert wire encode and decode for various protocol -// versions. -func TestMsgAlertWire(t *testing.T) { - baseMsgAlert := NewMsgAlert([]byte("some payload"), []byte("somesig")) - baseMsgAlertEncoded := []byte{ - 0x0c, // Varint for payload length - 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, // "some payload" - 0x07, // Varint for signature length - 0x73, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x67, // "somesig" - } - - tests := []struct { - in *MsgAlert // Message to encode - out *MsgAlert // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - }{ - // Latest protocol version. - { - baseMsgAlert, - baseMsgAlert, - baseMsgAlertEncoded, - ProtocolVersion, - }, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - // Encode the message to wire format. - var buf bytes.Buffer - err := test.in.BtcEncode(&buf, test.pver) - if err != nil { - t.Errorf("BtcEncode #%d error %v", i, err) - continue - } - if !bytes.Equal(buf.Bytes(), test.buf) { - t.Errorf("BtcEncode #%d\n got: %s want: %s", i, - spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) - continue - } - - // Decode the message from wire format. - var msg MsgAlert - rbuf := bytes.NewReader(test.buf) - err = msg.BtcDecode(rbuf, test.pver) - if err != nil { - t.Errorf("BtcDecode #%d error %v", i, err) - continue - } - if !reflect.DeepEqual(&msg, test.out) { - t.Errorf("BtcDecode #%d\n got: %s want: %s", i, - spew.Sdump(msg), spew.Sdump(test.out)) - continue - } - } -} - -// TestMsgAlertWireErrors performs negative tests against wire encode and decode -// of MsgAlert to confirm error paths work correctly. -func TestMsgAlertWireErrors(t *testing.T) { - pver := ProtocolVersion - - baseMsgAlert := NewMsgAlert([]byte("some payload"), []byte("somesig")) - baseMsgAlertEncoded := []byte{ - 0x0c, // Varint for payload length - 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, // "some payload" - 0x07, // Varint for signature length - 0x73, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x67, // "somesig" - } - - tests := []struct { - in *MsgAlert // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error - }{ - // Force error in payload length. - {baseMsgAlert, baseMsgAlertEncoded, pver, 0, io.ErrShortWrite, io.EOF}, - // Force error in payload. - {baseMsgAlert, baseMsgAlertEncoded, pver, 1, io.ErrShortWrite, io.EOF}, - // Force error in signature length. - {baseMsgAlert, baseMsgAlertEncoded, pver, 13, io.ErrShortWrite, io.EOF}, - // Force error in signature. - {baseMsgAlert, baseMsgAlertEncoded, pver, 14, io.ErrShortWrite, io.EOF}, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - // Encode to wire format. - w := newFixedWriter(test.max) - err := test.in.BtcEncode(w, test.pver) - if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { - t.Errorf("BtcEncode #%d wrong error got: %v, want: %v", - i, err, test.writeErr) - continue - } - - // For errors which are not of type MessageError, check them for - // equality. - if _, ok := err.(*MessageError); !ok { - if err != test.writeErr { - t.Errorf("BtcEncode #%d wrong error got: %v, "+ - "want: %v", i, err, test.writeErr) - continue - } - } - - // Decode from wire format. - var msg MsgAlert - r := newFixedReader(test.max, test.buf) - err = msg.BtcDecode(r, test.pver) - if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { - t.Errorf("BtcDecode #%d wrong error got: %v, want: %v", - i, err, test.readErr) - continue - } - - // For errors which are not of type MessageError, check them for - // equality. - if _, ok := err.(*MessageError); !ok { - if err != test.readErr { - t.Errorf("BtcDecode #%d wrong error got: %v, "+ - "want: %v", i, err, test.readErr) - continue - } - } - } - - // Test Error on empty Payload - baseMsgAlert.SerializedPayload = []byte{} - w := new(bytes.Buffer) - err := baseMsgAlert.BtcEncode(w, pver) - if _, ok := err.(*MessageError); !ok { - t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T", - err, MessageError{}) - } - - // Test Payload Serialize error - // overflow the max number of elements in SetCancel - baseMsgAlert.Payload = new(Alert) - baseMsgAlert.Payload.SetCancel = make([]int32, maxCountSetCancel+1) - buf := *new(bytes.Buffer) - err = baseMsgAlert.BtcEncode(&buf, pver) - if _, ok := err.(*MessageError); !ok { - t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T", - err, MessageError{}) - } - - // overflow the max number of elements in SetSubVer - baseMsgAlert.Payload = new(Alert) - baseMsgAlert.Payload.SetSubVer = make([]string, maxCountSetSubVer+1) - buf = *new(bytes.Buffer) - err = baseMsgAlert.BtcEncode(&buf, pver) - if _, ok := err.(*MessageError); !ok { - t.Errorf("MsgAlert.BtcEncode wrong error got: %T, want: %T", - err, MessageError{}) - } -} - -// TestAlert tests serialization and deserialization -// of the payload to Alert -func TestAlert(t *testing.T) { - pver := ProtocolVersion - alert := NewAlert( - 1, 1337093712, 1368628812, 1015, - 1013, []int32{1014}, 0, 40599, []string{"/Satoshi:0.7.2/"}, 5000, "", - "URGENT: upgrade required, see http://bitcoin.org/dos for details", - ) - w := new(bytes.Buffer) - err := alert.Serialize(w, pver) - if err != nil { - t.Error(err.Error()) - } - serializedpayload := w.Bytes() - newAlert, err := NewAlertFromPayload(serializedpayload, pver) - if err != nil { - t.Error(err.Error()) - } - - if alert.Version != newAlert.Version { - t.Errorf("NewAlertFromPayload: wrong Version - got %v, want %v ", - alert.Version, newAlert.Version) - } - if alert.RelayUntil != newAlert.RelayUntil { - t.Errorf("NewAlertFromPayload: wrong RelayUntil - got %v, want %v ", - alert.RelayUntil, newAlert.RelayUntil) - } - if alert.Expiration != newAlert.Expiration { - t.Errorf("NewAlertFromPayload: wrong Expiration - got %v, want %v ", - alert.Expiration, newAlert.Expiration) - } - if alert.ID != newAlert.ID { - t.Errorf("NewAlertFromPayload: wrong ID - got %v, want %v ", - alert.ID, newAlert.ID) - } - if alert.Cancel != newAlert.Cancel { - t.Errorf("NewAlertFromPayload: wrong Cancel - got %v, want %v ", - alert.Cancel, newAlert.Cancel) - } - if len(alert.SetCancel) != len(newAlert.SetCancel) { - t.Errorf("NewAlertFromPayload: wrong number of SetCancel - got %v, want %v ", - len(alert.SetCancel), len(newAlert.SetCancel)) - } - for i := 0; i < len(alert.SetCancel); i++ { - if alert.SetCancel[i] != newAlert.SetCancel[i] { - t.Errorf("NewAlertFromPayload: wrong SetCancel[%v] - got %v, want %v ", - len(alert.SetCancel), alert.SetCancel[i], newAlert.SetCancel[i]) - } - } - if alert.MinVer != newAlert.MinVer { - t.Errorf("NewAlertFromPayload: wrong MinVer - got %v, want %v ", - alert.MinVer, newAlert.MinVer) - } - if alert.MaxVer != newAlert.MaxVer { - t.Errorf("NewAlertFromPayload: wrong MaxVer - got %v, want %v ", - alert.MaxVer, newAlert.MaxVer) - } - if len(alert.SetSubVer) != len(newAlert.SetSubVer) { - t.Errorf("NewAlertFromPayload: wrong number of SetSubVer - got %v, want %v ", - len(alert.SetSubVer), len(newAlert.SetSubVer)) - } - for i := 0; i < len(alert.SetSubVer); i++ { - if alert.SetSubVer[i] != newAlert.SetSubVer[i] { - t.Errorf("NewAlertFromPayload: wrong SetSubVer[%v] - got %v, want %v ", - len(alert.SetSubVer), alert.SetSubVer[i], newAlert.SetSubVer[i]) - } - } - if alert.Priority != newAlert.Priority { - t.Errorf("NewAlertFromPayload: wrong Priority - got %v, want %v ", - alert.Priority, newAlert.Priority) - } - if alert.Comment != newAlert.Comment { - t.Errorf("NewAlertFromPayload: wrong Comment - got %v, want %v ", - alert.Comment, newAlert.Comment) - } - if alert.StatusBar != newAlert.StatusBar { - t.Errorf("NewAlertFromPayload: wrong StatusBar - got %v, want %v ", - alert.StatusBar, newAlert.StatusBar) - } - if alert.Reserved != newAlert.Reserved { - t.Errorf("NewAlertFromPayload: wrong Reserved - got %v, want %v ", - alert.Reserved, newAlert.Reserved) - } -} - -// TestAlertErrors performs negative tests against payload serialization, -// deserialization of Alert to confirm error paths work correctly. -func TestAlertErrors(t *testing.T) { - pver := ProtocolVersion - - baseAlert := NewAlert( - 1, 1337093712, 1368628812, 1015, - 1013, []int32{1014}, 0, 40599, []string{"/Satoshi:0.7.2/"}, 5000, "", - "URGENT", - ) - baseAlertEncoded := []byte{ - 0x01, 0x00, 0x00, 0x00, 0x50, 0x6e, 0xb2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9e, 0x93, 0x51, //|....Pn.O....L..Q| - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00, 0xf5, 0x03, 0x00, 0x00, 0x01, 0xf6, 0x03, 0x00, //|................| - 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x9e, 0x00, 0x00, 0x01, 0x0f, 0x2f, 0x53, 0x61, 0x74, 0x6f, //|.........../Sato| - 0x73, 0x68, 0x69, 0x3a, 0x30, 0x2e, 0x37, 0x2e, 0x32, 0x2f, 0x88, 0x13, 0x00, 0x00, 0x00, 0x06, //|shi:0.7.2/......| - 0x55, 0x52, 0x47, 0x45, 0x4e, 0x54, 0x00, //|URGENT.| - } - tests := []struct { - in *Alert // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error - }{ - // Force error in Version - {baseAlert, baseAlertEncoded, pver, 0, io.ErrShortWrite, io.EOF}, - // Force error in SetCancel VarInt. - {baseAlert, baseAlertEncoded, pver, 28, io.ErrShortWrite, io.EOF}, - // Force error in SetCancel ints. - {baseAlert, baseAlertEncoded, pver, 29, io.ErrShortWrite, io.EOF}, - // Force error in MinVer - {baseAlert, baseAlertEncoded, pver, 40, io.ErrShortWrite, io.EOF}, - // Force error in SetSubVer string VarInt. - {baseAlert, baseAlertEncoded, pver, 41, io.ErrShortWrite, io.EOF}, - // Force error in SetSubVer strings. - {baseAlert, baseAlertEncoded, pver, 48, io.ErrShortWrite, io.EOF}, - // Force error in Priority - {baseAlert, baseAlertEncoded, pver, 60, io.ErrShortWrite, io.EOF}, - // Force error in Comment string. - {baseAlert, baseAlertEncoded, pver, 62, io.ErrShortWrite, io.EOF}, - // Force error in StatusBar string. - {baseAlert, baseAlertEncoded, pver, 64, io.ErrShortWrite, io.EOF}, - // Force error in Reserved string. - {baseAlert, baseAlertEncoded, pver, 70, io.ErrShortWrite, io.EOF}, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - w := newFixedWriter(test.max) - err := test.in.Serialize(w, test.pver) - if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { - t.Errorf("Alert.Serialize #%d wrong error got: %v, want: %v", - i, err, test.writeErr) - continue - } - - var alert Alert - r := newFixedReader(test.max, test.buf) - err = alert.Deserialize(r, test.pver) - if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { - t.Errorf("Alert.Deserialize #%d wrong error got: %v, want: %v", - i, err, test.readErr) - continue - } - } - - // overflow the max number of elements in SetCancel - // maxCountSetCancel + 1 == 8388575 == \xdf\xff\x7f\x00 - // replace bytes 29-33 - badAlertEncoded := []byte{ - 0x01, 0x00, 0x00, 0x00, 0x50, 0x6e, 0xb2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9e, 0x93, 0x51, //|....Pn.O....L..Q| - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00, 0xf5, 0x03, 0x00, 0x00, 0xfe, 0xdf, 0xff, 0x7f, //|................| - 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x9e, 0x00, 0x00, 0x01, 0x0f, 0x2f, 0x53, 0x61, 0x74, 0x6f, //|.........../Sato| - 0x73, 0x68, 0x69, 0x3a, 0x30, 0x2e, 0x37, 0x2e, 0x32, 0x2f, 0x88, 0x13, 0x00, 0x00, 0x00, 0x06, //|shi:0.7.2/......| - 0x55, 0x52, 0x47, 0x45, 0x4e, 0x54, 0x00, //|URGENT.| - } - var alert Alert - r := bytes.NewReader(badAlertEncoded) - err := alert.Deserialize(r, pver) - if _, ok := err.(*MessageError); !ok { - t.Errorf("Alert.Deserialize wrong error got: %T, want: %T", - err, MessageError{}) - } - - // overflow the max number of elements in SetSubVer - // maxCountSetSubVer + 1 == 131071 + 1 == \x00\x00\x02\x00 - // replace bytes 42-46 - badAlertEncoded = []byte{ - 0x01, 0x00, 0x00, 0x00, 0x50, 0x6e, 0xb2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x9e, 0x93, 0x51, //|....Pn.O....L..Q| - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x03, 0x00, 0x00, 0xf5, 0x03, 0x00, 0x00, 0x01, 0xf6, 0x03, 0x00, //|................| - 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x9e, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x02, 0x00, 0x74, 0x6f, //|.........../Sato| - 0x73, 0x68, 0x69, 0x3a, 0x30, 0x2e, 0x37, 0x2e, 0x32, 0x2f, 0x88, 0x13, 0x00, 0x00, 0x00, 0x06, //|shi:0.7.2/......| - 0x55, 0x52, 0x47, 0x45, 0x4e, 0x54, 0x00, //|URGENT.| - } - r = bytes.NewReader(badAlertEncoded) - err = alert.Deserialize(r, pver) - if _, ok := err.(*MessageError); !ok { - t.Errorf("Alert.Deserialize wrong error got: %T, want: %T", - err, MessageError{}) - } -} diff --git a/wire/msgmempool.go b/wire/msgmempool.go deleted file mode 100644 index 9a3974927..000000000 --- a/wire/msgmempool.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2013-2015 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "io" -) - -// MsgMemPool implements the Message interface and represents a bitcoin mempool -// message. It is used to request a list of transactions still in the active -// memory pool of a relay. -// -// This message has no payload and was not added until protocol versions -// starting with BIP0035Version. -type MsgMemPool struct{} - -// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. -// This is part of the Message interface implementation. -func (msg *MsgMemPool) BtcDecode(r io.Reader, pver uint32) error { - return nil -} - -// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. -// This is part of the Message interface implementation. -func (msg *MsgMemPool) BtcEncode(w io.Writer, pver uint32) error { - return nil -} - -// Command returns the protocol command string for the message. This is part -// of the Message interface implementation. -func (msg *MsgMemPool) Command() string { - return CmdMemPool -} - -// MaxPayloadLength returns the maximum length the payload can be for the -// receiver. This is part of the Message interface implementation. -func (msg *MsgMemPool) MaxPayloadLength(pver uint32) uint32 { - return 0 -} - -// NewMsgMemPool returns a new bitcoin pong message that conforms to the Message -// interface. See MsgPong for details. -func NewMsgMemPool() *MsgMemPool { - return &MsgMemPool{} -} diff --git a/wire/msgmempool_test.go b/wire/msgmempool_test.go deleted file mode 100644 index cb49b998b..000000000 --- a/wire/msgmempool_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2013-2016 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "bytes" - "testing" -) - -func TestMemPool(t *testing.T) { - pver := ProtocolVersion - - // Ensure the command is expected value. - wantCmd := "mempool" - msg := NewMsgMemPool() - if cmd := msg.Command(); cmd != wantCmd { - t.Errorf("NewMsgMemPool: wrong command - got %v want %v", - cmd, wantCmd) - } - - // Ensure max payload is expected value. - wantPayload := uint32(0) - maxPayload := msg.MaxPayloadLength(pver) - if maxPayload != wantPayload { - t.Errorf("MaxPayloadLength: wrong max payload length for "+ - "protocol version %d - got %v, want %v", pver, - maxPayload, wantPayload) - } - - // Test encode with latest protocol version. - var buf bytes.Buffer - err := msg.BtcEncode(&buf, pver) - if err != nil { - t.Errorf("encode of MsgMemPool failed %v err <%v>", msg, err) - } - - // Test decode with latest protocol version. - readmsg := NewMsgMemPool() - err = readmsg.BtcDecode(&buf, pver) - if err != nil { - t.Errorf("decode of MsgMemPool failed [%v] err <%v>", buf, err) - } -}