// TestVerAck tests the MsgVerAck API. func TestVerAck(t *testing.T) { pver := wire.ProtocolVersion // Ensure the command is expected value. wantCmd := "verack" msg := wire.NewMsgVerAck() if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgVerAck: 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) } return }
// TestOutboundPeer tests that the outbound peer works as expected. func TestOutboundPeer(t *testing.T) { // Use a mock NewestBlock func to test errs var errBlockNotFound = errors.New("newest block not found") var mockNewestSha = func() (*wire.ShaHash, int32, error) { return nil, 0, errBlockNotFound } peerCfg := &peer.Config{ NewestBlock: mockNewestSha, UserAgentName: "peer", UserAgentVersion: "1.0", ChainParams: &chaincfg.MainNetParams, Services: 0, } r, w := io.Pipe() c := &conn{raddr: "10.0.0.1:8333", Writer: w, Reader: r} p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return } wantErr := errBlockNotFound if err := p.Connect(c); err != wantErr { t.Errorf("Connect: expected err %v, got %v\n", wantErr, err) return } // Test already connected. if err := p.Connect(c); err != nil { t.Errorf("Connect: unexpected err %v\n", err) return } // Test Queue Inv fakeBlockHash := &wire.ShaHash{0: 0x00, 1: 0x01} fakeInv := wire.NewInvVect(wire.InvTypeBlock, fakeBlockHash) p.QueueInventory(fakeInv) p.AddKnownInventory(fakeInv) p.QueueInventory(fakeInv) // Test Queue Message fakeMsg := wire.NewMsgVerAck() p.QueueMessage(fakeMsg, nil) done := make(chan struct{}) p.QueueMessage(fakeMsg, done) <-done p.Disconnect() // Test NewestBlock var newestBlock = func() (*wire.ShaHash, int32, error) { hashStr := "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef" hash, err := wire.NewShaHashFromStr(hashStr) if err != nil { return nil, 0, err } return hash, 234439, nil } peerCfg.NewestBlock = newestBlock r1, w1 := io.Pipe() c1 := &conn{raddr: "10.0.0.1:8333", Writer: w1, Reader: r1} p1, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return } if err := p1.Connect(c1); err != nil { t.Errorf("Connect: unexpected err %v\n", err) return } // Test update latest block latestBlockSha, err := wire.NewShaHashFromStr("1a63f9cdff1752e6375c8c76e543a71d239e1a2e5c6db1aa679") if err != nil { t.Errorf("NewShaHashFromStr: unexpected err %v\n", err) return } p1.UpdateLastAnnouncedBlock(latestBlockSha) p1.UpdateLastBlockHeight(234440) if p1.LastAnnouncedBlock() != latestBlockSha { t.Errorf("LastAnnouncedBlock: wrong block - got %v, want %v", p1.LastAnnouncedBlock(), latestBlockSha) return } // Test Queue Inv after connection p1.QueueInventory(fakeInv) p1.Disconnect() // Test regression peerCfg.ChainParams = &chaincfg.RegressionNetParams peerCfg.Services = wire.SFNodeBloom r2, w2 := io.Pipe() c2 := &conn{raddr: "10.0.0.1:8333", Writer: w2, Reader: r2} p2, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return } if err := p2.Connect(c2); err != nil { t.Errorf("Connect: unexpected err %v\n", err) return } // Test PushXXX var addrs []*wire.NetAddress for i := 0; i < 5; i++ { na := wire.NetAddress{} addrs = append(addrs, &na) } if _, err := p2.PushAddrMsg(addrs); err != nil { t.Errorf("PushAddrMsg: unexpected err %v\n", err) return } if err := p2.PushGetBlocksMsg(nil, &wire.ShaHash{}); err != nil { t.Errorf("PushGetBlocksMsg: unexpected err %v\n", err) return } if err := p2.PushGetHeadersMsg(nil, &wire.ShaHash{}); err != nil { t.Errorf("PushGetHeadersMsg: unexpected err %v\n", err) return } p2.PushRejectMsg("block", wire.RejectMalformed, "malformed", nil, true) p2.PushRejectMsg("block", wire.RejectInvalid, "invalid", nil, false) // Test Queue Messages p2.QueueMessage(wire.NewMsgGetAddr(), nil) p2.QueueMessage(wire.NewMsgPing(1), nil) p2.QueueMessage(wire.NewMsgMemPool(), nil) p2.QueueMessage(wire.NewMsgGetData(), nil) p2.QueueMessage(wire.NewMsgGetHeaders(), nil) p2.Disconnect() }
// TestVerAckWire tests the MsgVerAck wire encode and decode for various // protocol versions. func TestVerAckWire(t *testing.T) { msgVerAck := wire.NewMsgVerAck() msgVerAckEncoded := []byte{} tests := []struct { in *wire.MsgVerAck // Message to encode out *wire.MsgVerAck // Expected decoded message buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding }{ // Latest protocol version. { msgVerAck, msgVerAck, msgVerAckEncoded, wire.ProtocolVersion, }, // Protocol version BIP0035Version. { msgVerAck, msgVerAck, msgVerAckEncoded, wire.BIP0035Version, }, // Protocol version BIP0031Version. { msgVerAck, msgVerAck, msgVerAckEncoded, wire.BIP0031Version, }, // Protocol version NetAddressTimeVersion. { msgVerAck, msgVerAck, msgVerAckEncoded, wire.NetAddressTimeVersion, }, // Protocol version MultipleAddressVersion. { msgVerAck, msgVerAck, msgVerAckEncoded, wire.MultipleAddressVersion, }, } 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 wire.MsgVerAck 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 } } }
func (s *SPVCon) Open(remoteNode string, hfn string, inTs *TxStore) error { // open header file err := s.openHeaderFile(headerFileName) if err != nil { return err } // open TCP connection s.con, err = net.Dial("tcp", remoteNode) if err != nil { return err } s.localVersion = VERSION s.netType = NETVERSION s.TS = inTs myMsgVer, err := wire.NewMsgVersionFromConn(s.con, 0, 0) if err != nil { return err } err = myMsgVer.AddUserAgent("test", "zero") if err != nil { return err } // must set this to enable SPV stuff myMsgVer.AddService(wire.SFNodeBloom) // this actually sends n, err := wire.WriteMessageN(s.con, myMsgVer, s.localVersion, s.netType) if err != nil { return err } s.WBytes += uint64(n) log.Printf("wrote %d byte version message to %s\n", n, s.con.RemoteAddr().String()) n, m, b, err := wire.ReadMessageN(s.con, s.localVersion, s.netType) if err != nil { return err } s.RBytes += uint64(n) log.Printf("got %d byte response %x\n command: %s\n", n, b, m.Command()) mv, ok := m.(*wire.MsgVersion) if ok { log.Printf("connected to %s", mv.UserAgent) } log.Printf("remote reports version %x (dec %d)\n", mv.ProtocolVersion, mv.ProtocolVersion) mva := wire.NewMsgVerAck() n, err = wire.WriteMessageN(s.con, mva, s.localVersion, s.netType) if err != nil { return err } s.WBytes += uint64(n) s.inMsgQueue = make(chan wire.Message) go s.incomingMessageHandler() s.outMsgQueue = make(chan wire.Message) go s.outgoingMessageHandler() return nil }
func (p *Peer) pushVerAck() { p.sendQ <- wire.NewMsgVerAck() }
// TestMessage tests the Read/WriteMessage and Read/WriteMessageN API. func TestMessage(t *testing.T) { pver := wire.ProtocolVersion // Create the various types of messages to test. // MsgVersion. addrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 8333} you, err := wire.NewNetAddress(addrYou, wire.SFNodeNetwork) if err != nil { t.Errorf("NewNetAddress: %v", err) } you.Timestamp = time.Time{} // Version message has zero value timestamp. addrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333} me, err := wire.NewNetAddress(addrMe, wire.SFNodeNetwork) if err != nil { t.Errorf("NewNetAddress: %v", err) } me.Timestamp = time.Time{} // Version message has zero value timestamp. msgVersion := wire.NewMsgVersion(me, you, 123123, 0) msgVerack := wire.NewMsgVerAck() msgGetAddr := wire.NewMsgGetAddr() msgAddr := wire.NewMsgAddr() msgGetBlocks := wire.NewMsgGetBlocks(&wire.ShaHash{}) msgBlock := &blockOne msgInv := wire.NewMsgInv() msgGetData := wire.NewMsgGetData() msgNotFound := wire.NewMsgNotFound() msgTx := wire.NewMsgTx() msgPing := wire.NewMsgPing(123123) msgPong := wire.NewMsgPong(123123) msgGetHeaders := wire.NewMsgGetHeaders() msgHeaders := wire.NewMsgHeaders() msgAlert := wire.NewMsgAlert([]byte("payload"), []byte("signature")) msgMemPool := wire.NewMsgMemPool() msgFilterAdd := wire.NewMsgFilterAdd([]byte{0x01}) msgFilterClear := wire.NewMsgFilterClear() msgFilterLoad := wire.NewMsgFilterLoad([]byte{0x01}, 10, 0, wire.BloomUpdateNone) bh := wire.NewBlockHeader(&wire.ShaHash{}, &wire.ShaHash{}, 0, 0) msgMerkleBlock := wire.NewMsgMerkleBlock(bh) msgReject := wire.NewMsgReject("block", wire.RejectDuplicate, "duplicate block") tests := []struct { in wire.Message // Value to encode out wire.Message // Expected decoded value pver uint32 // Protocol version for wire encoding btcnet wire.BitcoinNet // Network to use for wire encoding bytes int // Expected num bytes read/written }{ {msgVersion, msgVersion, pver, wire.MainNet, 125}, {msgVerack, msgVerack, pver, wire.MainNet, 24}, {msgGetAddr, msgGetAddr, pver, wire.MainNet, 24}, {msgAddr, msgAddr, pver, wire.MainNet, 25}, {msgGetBlocks, msgGetBlocks, pver, wire.MainNet, 61}, {msgBlock, msgBlock, pver, wire.MainNet, 239}, {msgInv, msgInv, pver, wire.MainNet, 25}, {msgGetData, msgGetData, pver, wire.MainNet, 25}, {msgNotFound, msgNotFound, pver, wire.MainNet, 25}, {msgTx, msgTx, pver, wire.MainNet, 34}, {msgPing, msgPing, pver, wire.MainNet, 32}, {msgPong, msgPong, pver, wire.MainNet, 32}, {msgGetHeaders, msgGetHeaders, pver, wire.MainNet, 61}, {msgHeaders, msgHeaders, pver, wire.MainNet, 25}, {msgAlert, msgAlert, pver, wire.MainNet, 42}, {msgMemPool, msgMemPool, pver, wire.MainNet, 24}, {msgFilterAdd, msgFilterAdd, pver, wire.MainNet, 26}, {msgFilterClear, msgFilterClear, pver, wire.MainNet, 24}, {msgFilterLoad, msgFilterLoad, pver, wire.MainNet, 35}, {msgMerkleBlock, msgMerkleBlock, pver, wire.MainNet, 110}, {msgReject, msgReject, pver, wire.MainNet, 79}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. var buf bytes.Buffer nw, err := wire.WriteMessageN(&buf, test.in, test.pver, test.btcnet) if err != nil { t.Errorf("WriteMessage #%d error %v", i, err) continue } // Ensure the number of bytes written match the expected value. if nw != test.bytes { t.Errorf("WriteMessage #%d unexpected num bytes "+ "written - got %d, want %d", i, nw, test.bytes) } // Decode from wire format. rbuf := bytes.NewReader(buf.Bytes()) nr, msg, _, err := wire.ReadMessageN(rbuf, test.pver, test.btcnet) if err != nil { t.Errorf("ReadMessage #%d error %v, msg %v", i, err, spew.Sdump(msg)) continue } if !reflect.DeepEqual(msg, test.out) { t.Errorf("ReadMessage #%d\n got: %v want: %v", i, spew.Sdump(msg), spew.Sdump(test.out)) continue } // Ensure the number of bytes read match the expected value. if nr != test.bytes { t.Errorf("ReadMessage #%d unexpected num bytes read - "+ "got %d, want %d", i, nr, test.bytes) } } // Do the same thing for Read/WriteMessage, but ignore the bytes since // they don't return them. t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. var buf bytes.Buffer err := wire.WriteMessage(&buf, test.in, test.pver, test.btcnet) if err != nil { t.Errorf("WriteMessage #%d error %v", i, err) continue } // Decode from wire format. rbuf := bytes.NewReader(buf.Bytes()) msg, _, err := wire.ReadMessage(rbuf, test.pver, test.btcnet) if err != nil { t.Errorf("ReadMessage #%d error %v, msg %v", i, err, spew.Sdump(msg)) continue } if !reflect.DeepEqual(msg, test.out) { t.Errorf("ReadMessage #%d\n got: %v want: %v", i, spew.Sdump(msg), spew.Sdump(test.out)) continue } } }
// crawlIP retrievs a slice of ip addresses from a client func crawlIP(s *dnsseeder, r *result) ([]*wire.NetAddress, *crawlError) { conn, err := net.DialTimeout("tcp", r.node, time.Second*10) if err != nil { if config.debug { log.Printf("%s - debug - Could not connect to %s - %v\n", s.name, r.node, err) } return nil, &crawlError{"", err} } defer conn.Close() if config.debug { log.Printf("%s - debug - Connected to remote address: %s\n", s.name, r.node) } // set a deadline for all comms to be done by. After this all i/o will error conn.SetDeadline(time.Now().Add(time.Second * maxTo)) // First command to remote end needs to be a version command // last parameter is lastblock msgver, err := wire.NewMsgVersionFromConn(conn, nounce, 0) if err != nil { return nil, &crawlError{"Create NewMsgVersionFromConn", err} } err = wire.WriteMessage(conn, msgver, s.pver, s.id) if err != nil { // Log and handle the error return nil, &crawlError{"Write Version Message", err} } // first message received should be version msg, _, err := wire.ReadMessage(conn, s.pver, s.id) if err != nil { // Log and handle the error return nil, &crawlError{"Read message after sending Version", err} } switch msg := msg.(type) { case *wire.MsgVersion: // The message is a pointer to a MsgVersion struct. if config.debug { log.Printf("%s - debug - %s - Remote version: %v\n", s.name, r.node, msg.ProtocolVersion) } // fill the node struct with the remote details r.version = msg.ProtocolVersion r.services = msg.Services r.lastBlock = msg.LastBlock r.strVersion = msg.UserAgent default: return nil, &crawlError{"Did not receive expected Version message from remote client", errors.New("")} } // send verack command msgverack := wire.NewMsgVerAck() err = wire.WriteMessage(conn, msgverack, s.pver, s.id) if err != nil { return nil, &crawlError{"writing message VerAck", err} } // second message received should be verack msg, _, err = wire.ReadMessage(conn, s.pver, s.id) if err != nil { return nil, &crawlError{"reading expected Ver Ack from remote client", err} } switch msg.(type) { case *wire.MsgVerAck: if config.debug { log.Printf("%s - debug - %s - received Version Ack\n", s.name, r.node) } default: return nil, &crawlError{"Did not receive expected Ver Ack message from remote client", errors.New("")} } // if we get this far and if the seeder is full then don't ask for addresses. This will reduce bandwith usage while still // confirming that we can connect to the remote node if len(s.theList) > s.maxSize { return nil, nil } // send getaddr command msgGetAddr := wire.NewMsgGetAddr() err = wire.WriteMessage(conn, msgGetAddr, s.pver, s.id) if err != nil { return nil, &crawlError{"writing Addr message to remote client", err} } c := 0 dowhile := true for dowhile == true { // Using the Bitcoin lib for the some networks means it does not understand some // of the commands and will error. We can ignore these as we are only // interested in the addr message and its content. msgaddr, _, _ := wire.ReadMessage(conn, s.pver, s.id) if msgaddr != nil { switch msg := msgaddr.(type) { case *wire.MsgAddr: // received the addr message so return the result if config.debug { log.Printf("%s - debug - %s - received valid addr message\n", s.name, r.node) } dowhile = false return msg.AddrList, nil default: if config.debug { log.Printf("%s - debug - %s - ignoring message - %v\n", s.name, r.node, msg.Command()) } } } // if we get more than 25 messages before the addr we asked for then give up on this client if c++; c >= 25 { dowhile = false } } // received too many messages before requested Addr return nil, &crawlError{"message loop - did not receive remote addresses in first 25 messages from remote client", errors.New("")} }
// OpenPV starts a func OpenSPV(remoteNode string, hfn, dbfn string, inTs *TxStore, hard bool, iron bool, p *chaincfg.Params) (SPVCon, error) { // create new SPVCon var s SPVCon s.HardMode = hard s.Ironman = iron // I should really merge SPVCon and TxStore, they're basically the same inTs.Param = p s.TS = inTs // copy pointer of txstore into spvcon // open header file err := s.openHeaderFile(hfn) if err != nil { return s, err } // open TCP connection s.con, err = net.Dial("tcp", remoteNode) if err != nil { return s, err } // assign version bits for local node s.localVersion = VERSION // transaction store for this SPV connection err = inTs.OpenDB(dbfn) if err != nil { return s, err } myMsgVer, err := wire.NewMsgVersionFromConn(s.con, 0, 0) if err != nil { return s, err } err = myMsgVer.AddUserAgent("test", "zero") if err != nil { return s, err } // must set this to enable SPV stuff myMsgVer.AddService(wire.SFNodeBloom) // this actually sends n, err := wire.WriteMessageN(s.con, myMsgVer, s.localVersion, s.TS.Param.Net) if err != nil { return s, err } s.WBytes += uint64(n) log.Printf("wrote %d byte version message to %s\n", n, s.con.RemoteAddr().String()) n, m, b, err := wire.ReadMessageN(s.con, s.localVersion, s.TS.Param.Net) if err != nil { return s, err } s.RBytes += uint64(n) log.Printf("got %d byte response %x\n command: %s\n", n, b, m.Command()) mv, ok := m.(*wire.MsgVersion) if ok { log.Printf("connected to %s", mv.UserAgent) } log.Printf("remote reports version %x (dec %d)\n", mv.ProtocolVersion, mv.ProtocolVersion) // set remote height s.remoteHeight = mv.LastBlock mva := wire.NewMsgVerAck() n, err = wire.WriteMessageN(s.con, mva, s.localVersion, s.TS.Param.Net) if err != nil { return s, err } s.WBytes += uint64(n) s.inMsgQueue = make(chan wire.Message) go s.incomingMessageHandler() s.outMsgQueue = make(chan wire.Message) go s.outgoingMessageHandler() s.blockQueue = make(chan HashAndHeight, 32) // queue depth 32 is a thing s.fPositives = make(chan int32, 4000) // a block full, approx s.inWaitState = make(chan bool, 1) go s.fPositiveHandler() return s, nil }
// TestOutboundPeer tests that the outbound peer works as expected. func TestOutboundPeer(t *testing.T) { peerCfg := &peer.Config{ NewestBlock: func() (*wire.ShaHash, int32, error) { return nil, 0, errors.New("newest block not found") }, UserAgentName: "peer", UserAgentVersion: "1.0", ChainParams: &chaincfg.MainNetParams, Services: 0, } r, w := io.Pipe() c := &conn{raddr: "10.0.0.1:8333", Writer: w, Reader: r} p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return } // Test trying to connect twice. p.Connect(c) p.Connect(c) disconnected := make(chan struct{}) go func() { p.WaitForDisconnect() disconnected <- struct{}{} }() select { case <-disconnected: close(disconnected) case <-time.After(time.Second): t.Fatal("Peer did not automatically disconnect.") } if p.Connected() { t.Fatalf("Should not be connected as NewestBlock produces error.") } // Test Queue Inv fakeBlockHash := &wire.ShaHash{0: 0x00, 1: 0x01} fakeInv := wire.NewInvVect(wire.InvTypeBlock, fakeBlockHash) // Should be noops as the peer could not connect. p.QueueInventory(fakeInv) p.AddKnownInventory(fakeInv) p.QueueInventory(fakeInv) fakeMsg := wire.NewMsgVerAck() p.QueueMessage(fakeMsg, nil) done := make(chan struct{}) p.QueueMessage(fakeMsg, done) <-done p.Disconnect() // Test NewestBlock var newestBlock = func() (*wire.ShaHash, int32, error) { hashStr := "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef" hash, err := wire.NewShaHashFromStr(hashStr) if err != nil { return nil, 0, err } return hash, 234439, nil } peerCfg.NewestBlock = newestBlock r1, w1 := io.Pipe() c1 := &conn{raddr: "10.0.0.1:8333", Writer: w1, Reader: r1} p1, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return } p1.Connect(c1) // Test update latest block latestBlockSha, err := wire.NewShaHashFromStr("1a63f9cdff1752e6375c8c76e543a71d239e1a2e5c6db1aa679") if err != nil { t.Errorf("NewShaHashFromStr: unexpected err %v\n", err) return } p1.UpdateLastAnnouncedBlock(latestBlockSha) p1.UpdateLastBlockHeight(234440) if p1.LastAnnouncedBlock() != latestBlockSha { t.Errorf("LastAnnouncedBlock: wrong block - got %v, want %v", p1.LastAnnouncedBlock(), latestBlockSha) return } // Test Queue Inv after connection p1.QueueInventory(fakeInv) p1.Disconnect() // Test regression peerCfg.ChainParams = &chaincfg.RegressionNetParams peerCfg.Services = wire.SFNodeBloom r2, w2 := io.Pipe() c2 := &conn{raddr: "10.0.0.1:8333", Writer: w2, Reader: r2} p2, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") if err != nil { t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) return } p2.Connect(c2) // Test PushXXX var addrs []*wire.NetAddress for i := 0; i < 5; i++ { na := wire.NetAddress{} addrs = append(addrs, &na) } if _, err := p2.PushAddrMsg(addrs); err != nil { t.Errorf("PushAddrMsg: unexpected err %v\n", err) return } if err := p2.PushGetBlocksMsg(nil, &wire.ShaHash{}); err != nil { t.Errorf("PushGetBlocksMsg: unexpected err %v\n", err) return } if err := p2.PushGetHeadersMsg(nil, &wire.ShaHash{}); err != nil { t.Errorf("PushGetHeadersMsg: unexpected err %v\n", err) return } p2.PushRejectMsg("block", wire.RejectMalformed, "malformed", nil, false) p2.PushRejectMsg("block", wire.RejectInvalid, "invalid", nil, false) // Test Queue Messages p2.QueueMessage(wire.NewMsgGetAddr(), nil) p2.QueueMessage(wire.NewMsgPing(1), nil) p2.QueueMessage(wire.NewMsgMemPool(), nil) p2.QueueMessage(wire.NewMsgGetData(), nil) p2.QueueMessage(wire.NewMsgGetHeaders(), nil) p2.Disconnect() }