/
peer.go
135 lines (110 loc) · 2.71 KB
/
peer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
"fmt"
"github.com/conformal/btcwire"
"net"
"errors"
)
type OutMsg struct {
msg btcwire.Message
//doneChan chan bool
}
type Peer struct {
server *Server
conn net.Conn
outputQueue chan OutMsg
version uint32
btcnet btcwire.BitcoinNet
}
func (peer *Peer) InHandler() {
for {
msg, _, err := btcwire.ReadMessage(peer.conn, peer.version, peer.btcnet)
if err != nil {
fmt.Println("Error %v", err)
continue
}
switch msg := msg.(type) {
case *btcwire.MsgVerAck:
// Do nothing
fmt.Println("Version ackknowledged")
default:
fmt.Printf("Received unhandled message of type %v\n", msg.Command())
}
}
}
func (peer *Peer) OutHandler() {
for {
select {
case msg := <- peer.outputQueue:
switch msg.msg.(type) {
case *btcwire.MsgVersion:
// Version is ok
default:
fmt.Printf("Unknown message %v\n", msg)
return
}
fmt.Println("Sending message to peer")
peer.WriteMessage(msg.msg)
}
}
}
func (peer *Peer) WriteMessage(msg btcwire.Message) {
err := btcwire.WriteMessage(peer.conn, msg, peer.version, peer.btcnet)
if err != nil {
fmt.Println("Error writing message %v", err)
return
}
}
func (peer *Peer) Start() error {
err := peer.SendVersionMsg()
if err != nil {
return err
}
go peer.OutHandler()
go peer.InHandler()
return nil
}
func (peer *Peer) Stop() {
}
func (peer *Peer) QueueMsg(msg btcwire.Message) {
peer.outputQueue <- OutMsg{msg: msg}
}
func (peer *Peer) SendVersionMsg() error {
me, err := NewNetAddress(peer.conn.LocalAddr(), 0)
if err != nil {
return err
}
you, err := NewNetAddress(peer.conn.RemoteAddr(), 0)
if err != nil {
return err
}
msg := btcwire.NewMsgVersion(me, you, 1, "mscd", int32(peer.server.db.LastBlock()))
msg.AddrYou.Services = btcwire.SFNodeNetwork
msg.Services = btcwire.SFNodeNetwork
peer.QueueMsg(msg)
return nil
}
func NewNetAddress(addr net.Addr, services btcwire.ServiceFlag) (*btcwire.NetAddress, error) {
// addr will be addr net.TCPAddr when not using a proxy.
if tcpAddr, ok := addr.(*net.TCPAddr); ok {
ip := tcpAddr.IP
port := uint16(tcpAddr.Port)
na := btcwire.NewNetAddressIPPort(ip, port, services)
return na, nil
}
return nil, errors.New("Couldn't create address")
}
func NewPeer(server *Server) (*Peer, error) {
conn, err := net.Dial("tcp", "62.194.122.22:8333")
if err != nil {
return nil, err
}
p := Peer{
server: server,
conn: conn,
version: btcwire.ProtocolVersion,
btcnet: btcwire.MainNet,
outputQueue: make(chan OutMsg, 20),
}
return &p, nil
}