diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba2906d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +main diff --git a/README.md b/README.md index d6d129e..465c8b0 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ import ( "log" "os" - "github.com/o3labs/neo-transaction-watcher/neotx" - "github.com/o3labs/neo-transaction-watcher/neotx/network" + "github.com/corollari/neo-transaction-watcher/neotx" + "github.com/corollari/neo-transaction-watcher/neotx/network" ) type Handler struct { diff --git a/main.go b/main.go index b2d5e16..9bbd7b7 100644 --- a/main.go +++ b/main.go @@ -4,8 +4,8 @@ import ( "log" "os" - "github.com/o3labs/neo-transaction-watcher/neotx" - "github.com/o3labs/neo-transaction-watcher/neotx/network" + "github.com/corollari/neo-transaction-watcher/neotx" + "github.com/corollari/neo-transaction-watcher/neotx/network" ) type Handler struct { @@ -28,7 +28,7 @@ func main() { config := neotx.Config{ Network: neotx.NEOMainNet, Port: 10333, - IPAddress: "52.193.202.2", + IPAddress: "207.180.217.134", } client := neotx.NewClient(config) handler := &Handler{} diff --git a/neotx/network.go b/neotx/network.go index 253c52a..fe9567f 100644 --- a/neotx/network.go +++ b/neotx/network.go @@ -7,8 +7,9 @@ import ( "io" "log" "net" + "time" - "github.com/o3labs/neo-transaction-watcher/neotx/network" + "github.com/corollari/neo-transaction-watcher/neotx/network" ) //Network @@ -51,6 +52,17 @@ type Interface interface { SetDelegate(MessageDelegate) } +func startPingLoop(c *Client) { + conn := c.connection + for { + time.Sleep(1000 * time.Millisecond) + nonce, _ := network.RandomUint32() + payload := network.NewPingPayload(nonce) + pingCommand := network.NewMessage(c.Config.Network, network.CommandPing, payload) + conn.Write(pingCommand) + } +} + var _ Interface = (*Client)(nil) func (c *Client) handleConnection() { @@ -73,17 +85,18 @@ func (c *Client) handleConnection() { return } + payloadByte := make([]byte, msg.Length) + _, err = io.ReadFull(conn, payloadByte) + if err != nil { + if c.delegate != nil { + go c.delegate.OnError(err) + } + continue + } + //receive version from remote node if msg.Command == string(network.CommandVersion) { out := &network.Version{} - payloadByte := make([]byte, msg.Length) - _, err = io.ReadFull(conn, payloadByte) - if err != nil { - if c.delegate != nil { - go c.delegate.OnError(err) - } - continue - } pr := bytes.NewBuffer(payloadByte) out.Decode(pr, 0) //reply with verack @@ -94,29 +107,15 @@ func (c *Client) handleConnection() { go c.delegate.OnConnected(*out) } } else if msg.Command == string(network.CommandVerack) { - + go startPingLoop(c) + } else if msg.Command == string(network.CommandPong) { + log.Println("Pong!") } else if msg.Command == string(network.CommandAddr) { out := &network.Addr{} - payloadByte := make([]byte, msg.Length) - _, err = io.ReadFull(conn, payloadByte) - if err != nil { - if c.delegate != nil { - go c.delegate.OnError(err) - } - continue - } pr := bytes.NewBuffer(payloadByte) out.Decode(pr, 0) } else if msg.Command == string(network.CommandInv) { out := &network.Inv{} - payloadByte := make([]byte, msg.Length) - _, err = io.ReadFull(conn, payloadByte) - if err != nil { - if c.delegate != nil { - go c.delegate.OnError(err) - } - continue - } log.Printf("msg = %+v\n", msg) pr := bytes.NewBuffer(payloadByte) out.Decode(pr, 0) @@ -132,7 +131,8 @@ func (c *Client) handleConnection() { go c.delegate.OnReceive(tx) } } - + } else { + log.Printf("Unhandled message: %s\n", msg.Command) } } } diff --git a/neotx/network/ping.go b/neotx/network/ping.go new file mode 100644 index 0000000..2c38e60 --- /dev/null +++ b/neotx/network/ping.go @@ -0,0 +1,58 @@ +package network + +import ( + "bytes" + "fmt" + "io" + "time" +) + +type Ping struct { + Timestamp uint32 //4 bytes + Nonce uint32 //4 bytes + BlockHeight uint32 //4 bytes +} + +func NewPingPayload(nonce uint32) *Ping { + + v := Ping{} + v.Timestamp = uint32(time.Unix(time.Now().Unix(), 0).Unix()) + v.Nonce = nonce + v.BlockHeight = 0 //TODO get this from a chain data + return &v +} + +func (v *Ping) Decode(r io.Reader, protocolVersion uint32) error { + + buf, ok := r.(*bytes.Buffer) + + if !ok { + return fmt.Errorf("Ping decode reader is not a *byte.Buffer") + } + + err := ReadElements(buf, &v.BlockHeight, (*uint32)(&v.Timestamp), &v.Nonce) + if err != nil { + return err + } + + return nil +} + +func (v *Ping) Encode(w io.Writer, protocolVersion uint32) error { + err := WriteElement(w, v.BlockHeight) + if err != nil { + return err + } + + err = WriteElement(w, v.Timestamp) + if err != nil { + return err + } + + err = WriteElement(w, v.Nonce) + if err != nil { + return err + } + + return nil +} diff --git a/neotx/network/version.go b/neotx/network/version.go index 7bd8ba4..5fb438e 100644 --- a/neotx/network/version.go +++ b/neotx/network/version.go @@ -11,7 +11,7 @@ type ServiceFlag uint64 const ( MaxUserAgentLength = 1024 - DefaultUserAgent = "NEOxO3:0.0.1;" //test + DefaultUserAgent = "/Neo:2.10.2/" //test ProtocolVersion = uint32(0) DefaultServiceFlag = ServiceFlag(1) )