[NOD-417] Remove mempool and alert messages (#515)

This commit is contained in:
Ori Newman 2019-12-04 10:43:50 +02:00 committed by stasatdaglabs
parent e68b242243
commit e872ebc7b3
11 changed files with 0 additions and 1048 deletions

View File

@ -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),

View File

@ -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)

View File

@ -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)

View File

@ -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)
}
}

View File

@ -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,

View File

@ -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{}

View File

@ -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},

View File

@ -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<int32> | ? |
// -----------------------------------------------
// | MinVer | int32 | 4 |
// -----------------------------------------------
// | MaxVer | int32 | 4 |
// -----------------------------------------------
// | SetSubVer | set<string> | ? |
// -----------------------------------------------
// | 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<string> is a VarInt followed by as many number of strings
// * set<int32> 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,
}
}

View File

@ -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{})
}
}

View File

@ -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{}
}

View File

@ -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)
}
}