func TestVisorAnnounceBlocks(t *testing.T) { defer cleanupVisor() defer gnet.EraseMessages() p, gc := setupPool() vc, _ := setupVisor() go p.Pool.ConnectionWriteLoop(gc) // Disabled vc.Disabled = true v := NewVisor(vc) assert.NotPanics(t, func() { v.AnnounceBlocks(p) }) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, gc.LastSent.IsZero()) // Valid send vc.Disabled = false gc.Conn = NewDummyConn(addr) v = NewVisor(vc) assert.False(t, v.Config.Disabled) assert.NotPanics(t, func() { v.AnnounceBlocks(p) }) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } sr := <-p.Pool.SendResults assert.Nil(t, sr.Error) assert.Equal(t, sr.Connection, gc) _, ok := sr.Message.(*AnnounceBlocksMessage) assert.True(t, ok) assert.False(t, gc.LastSent.IsZero()) }
func TestVisorBroadcastBlock(t *testing.T) { defer cleanupVisor() defer gnet.EraseMessages() p, gc := setupPool() vc, _ := setupVisor() vc.Disabled = true v := NewVisor(vc) // Should not send anything if disabled assert.NotPanics(t, func() { v.broadcastBlock(visor.SignedBlock{}, p) }) assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, gc.LastSent.IsZero()) // Sending gc.Conn = NewDummyConn(addr) vc.Disabled = false v = NewVisor(vc) sb := v.Visor.GetGenesisBlock() assert.NotPanics(t, func() { v.broadcastBlock(sb, p) }) go p.Pool.ConnectionWriteLoop(gc) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } sr := <-p.Pool.SendResults assert.Equal(t, sr.Connection, gc) _, ok := sr.Message.(*GiveBlocksMessage) assert.True(t, ok) assert.Nil(t, sr.Error) assert.False(t, gc.LastSent.IsZero()) }
func TestOnDisconnect(t *testing.T) { gnet.EraseMessages() d := newDefaultDaemon() c := gnetConnection(addr) var mirror uint32 = 100 // Not blacklistable reason := gnet.DisconnectWriteFailed setupTestOnDisconnect(d, c, mirror) assert.NotPanics(t, func() { d.onGnetDisconnect(c, reason) }) // Should not be in blacklist assert.Equal(t, len(d.Peers.Peers.Blacklist), 0) // Should no longer be in OutgoingConnections assert.Equal(t, len(d.OutgoingConnections), 0) // Should no longer be in d.ExpectingIntroductions assert.Equal(t, len(d.ExpectingIntroductions), 0) // Should be removed from the mirror, and the mirror dict for this ip // should be removed assert.Equal(t, len(d.mirrorConnections), 0) assert.Equal(t, len(d.ConnectionMirrors), 0) // Blacklistable reason = DisconnectIntroductionTimeout setupTestOnDisconnect(d, c, mirror) assert.NotPanics(t, func() { d.onGnetDisconnect(c, reason) }) assert.Equal(t, len(d.Peers.Peers.Blacklist), 1) assert.NotNil(t, d.Peers.Peers.Blacklist[addr]) // Should be in blacklist assert.Equal(t, len(d.Peers.Peers.Blacklist), 1) assert.NotNil(t, d.Peers.Peers.Blacklist[addr]) // Should no longer be in OutgoingConnections assert.Equal(t, len(d.OutgoingConnections), 0) // Should no longer be in d.ExpectingIntroductions assert.Equal(t, len(d.ExpectingIntroductions), 0) // Should be removed from the mirror, and the mirror dict for this ip // should be removed assert.Equal(t, len(d.mirrorConnections), 0) assert.Equal(t, len(d.ConnectionMirrors), 0) // Cleanup delete(d.Peers.Peers.Blacklist, addr) // d.mirrorConnections should retain a submap if there are other ports // inside reason = gnet.DisconnectWriteFailed setupTestOnDisconnect(d, c, mirror) d.mirrorConnections[mirror][strings.Split(addrb, ":")[0]] = addrPort assert.NotPanics(t, func() { d.onGnetDisconnect(c, reason) }) // Should not be in blacklist assert.Equal(t, len(d.Peers.Peers.Blacklist), 0) // Should no longer be in OutgoingConnections assert.Equal(t, len(d.OutgoingConnections), 0) // Should no longer be in d.ExpectingIntroductions assert.Equal(t, len(d.ExpectingIntroductions), 0) // Should be removed from the mirror, and the mirror dict for this ip // should be removed assert.Equal(t, len(d.mirrorConnections), 1) assert.Equal(t, len(d.mirrorConnections[mirror]), 1) assert.Equal(t, len(d.ConnectionMirrors), 0) shutdown(d) }
func TestVisorBroadcastTransaction(t *testing.T) { defer cleanupVisor() defer gnet.EraseMessages() p, gc := setupPool() go p.Pool.ConnectionWriteLoop(gc) vc, _ := setupVisor() vc.Disabled = true v := NewVisor(vc) ut := createUnconfirmedTxn() assert.NotPanics(t, func() { v.broadcastTransaction(ut.Txn, p) }) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, gc.LastSent.IsZero()) // Sending vc.Disabled = false gc.Conn = NewDummyConn(addr) v = NewVisor(vc) assert.NotPanics(t, func() { v.broadcastTransaction(ut.Txn, p) }) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } sr := <-p.Pool.SendResults assert.Nil(t, sr.Error) assert.Equal(t, sr.Connection, gc) _, ok := sr.Message.(*GiveTxnsMessage) assert.True(t, ok) assert.False(t, gc.LastSent.IsZero()) }
func TestPingMessage(t *testing.T) { d := newDefaultDaemon() defer shutdown(d) p := d.Pool.Pool m := &PingMessage{} testSimpleMessageHandler(t, d, m) m.c = messageContext(addr) go p.ConnectionWriteLoop(m.c.Conn) defer m.c.Conn.Close() assert.NotPanics(t, func() { m.Process(d) }) // A pong message should have been sent wait() assert.Equal(t, len(p.SendResults), 1) if len(p.SendResults) == 0 { t.Fatalf("SendResults empty, would block") } sr := <-p.SendResults assert.Equal(t, sr.Connection, m.c.Conn) assert.Nil(t, sr.Error) _, ok := sr.Message.(*PongMessage) assert.True(t, ok) assert.False(t, m.c.Conn.LastSent.IsZero()) // Test serialization mm := PingMessage{} b := encoder.Serialize(mm) m2 := PingMessage{} assert.Nil(t, encoder.DeserializeRaw(b, &m2)) assert.Equal(t, mm, m2) gnet.EraseMessages() }
func TestGivePeersMessage(t *testing.T) { d := newDefaultDaemon() defer shutdown(d) addrs := []string{addr, addrb, "7"} peers := make([]*pex.Peer, 3) for i, addr := range addrs { peers[i] = &pex.Peer{Addr: addr} } m := NewGivePeersMessage(peers) assert.Equal(t, len(m.GetPeers()), 2) testSimpleMessageHandler(t, d, m) assert.Equal(t, m.GetPeers()[0], addrs[0]) assert.Equal(t, m.GetPeers()[1], addrs[1]) // Test disabled d.Peers.Config.Disabled = true m.Process(d) assert.Equal(t, len(d.Peers.Peers.Peerlist), 0) // Test serialization m = NewGivePeersMessage(peers) b := encoder.Serialize(m) m2 := GivePeersMessage{} assert.Nil(t, encoder.DeserializeRaw(b, &m2)) assert.Equal(t, *m, m2) // Peers should be added to the pex when processed d.Peers.Config.Disabled = false m.Process(d) assert.Equal(t, len(d.Peers.Peers.Peerlist), 2) gnet.EraseMessages() }
// Terminates all subsystems safely. To stop the Daemon run loop, send a value // over the quit channel provided to Init. The Daemon run lopp must be stopped // before calling this function. func (self *Daemon) Shutdown() { self.DHT.Shutdown() self.Pool.Shutdown() self.Peers.Shutdown() self.Visor.Shutdown() gnet.EraseMessages() }
func TestGetPeersMessage(t *testing.T) { d := newDefaultDaemon() defer shutdown(d) p := d.Pool m := NewGetPeersMessage() testSimpleMessageHandler(t, d, m) d.Peers.Peers.AddPeer(addr) q, err := d.Peers.Peers.AddPeer(addrb) assert.Nil(t, err) q.Private = true d.Peers.Config.ReplyCount = 100 m.c = messageContext(addr) // Peers disabled d.Peers.Config.Disabled = true assert.NotPanics(t, func() { m.Process(d) }) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, m.c.Conn.LastSent.IsZero()) // Peers enabled d.Peers.Config.Disabled = false m.c = messageContext(addr) defer m.c.Conn.Close() go p.Pool.ConnectionWriteLoop(m.c.Conn) assert.NotPanics(t, func() { m.Process(d) }) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } sr := <-p.Pool.SendResults assert.Nil(t, sr.Error) assert.Equal(t, sr.Connection, m.c.Conn) msg, ok := sr.Message.(*GivePeersMessage) assert.True(t, ok) // Private peer should not be included ipAddr, err := NewIPAddr(addr) assert.Nil(t, err) assert.Equal(t, msg.Peers, []IPAddr{ipAddr}) assert.False(t, m.c.Conn.LastSent.IsZero()) // If no peers, nothing should happen m.c.Conn.LastSent = util.ZeroTime() delete(d.Peers.Peers.Peerlist, addr) assert.NotPanics(t, func() { m.Process(d) }) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, m.c.Conn.LastSent.IsZero()) // Test serialization m = NewGetPeersMessage() b := encoder.Serialize(m) m2 := GetPeersMessage{} assert.Nil(t, encoder.DeserializeRaw(b, &m2)) assert.Equal(t, *m, m2) gnet.EraseMessages() }
func TestVisorSpend(t *testing.T) { defer cleanupVisor() defer gnet.EraseMessages() p, gc := setupPool() go p.Pool.ConnectionWriteLoop(gc) vc, mv := setupVisor() vc.Disabled = true v := NewVisor(vc) // Spending while disabled assert.NotPanics(t, func() { _, err := v.Spend(visor.Balance{10e6, 0}, 0, mv.Wallet.GetAddresses()[0], p) assert.NotNil(t, err) assert.Equal(t, err.Error(), "Visor disabled") wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, gc.LastSent.IsZero()) }) // Spending but spend fails (no money) vc.Disabled = false v = NewVisor(vc) assert.NotPanics(t, func() { _, err := v.Spend(visor.Balance{1000 * 10e6, 0}, 0, mv.Wallet.GetAddresses()[0], p) wait() assert.NotNil(t, err) assert.Equal(t, len(p.Pool.SendResults), 0) assert.Equal(t, len(v.Visor.Unconfirmed.Txns), 0) assert.True(t, gc.LastSent.IsZero()) }) // Spending succeeds, and announced vc, mv = setupVisor() vc.Disabled = false gc.Conn = NewDummyConn(addr) v = NewVisor(vc) assert.Nil(t, transferCoins(mv, v.Visor)) assert.NotPanics(t, func() { _, err := v.Spend(visor.Balance{10e6, 0}, 0, mv.Wallet.GetAddresses()[0], p) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } sr := <-p.Pool.SendResults assert.Equal(t, sr.Connection, gc) assert.Nil(t, sr.Error) _, ok := sr.Message.(*GiveTxnsMessage) assert.True(t, ok) assert.Nil(t, err) assert.Equal(t, len(v.Visor.Unconfirmed.Txns), 1) assert.False(t, gc.LastSent.IsZero()) }) }
func TestIntroductionMessageProcess(t *testing.T) { cleanupPeers() d := newDefaultDaemon() defer shutdown(d) m := NewIntroductionMessage(d.Messages.Mirror, d.Config.Version, uint16(poolPort)) m.c = messageContext(addr) d.Pool.Pool.Pool[1] = m.c.Conn // Test invalid m.valid = false d.ExpectingIntroductions[addr] = time.Now() m.Process(d) // d.ExpectingIntroductions should get updated _, x := d.ExpectingIntroductions[addr] assert.False(t, x) // d.mirrorConnections should not have an entry _, x = d.mirrorConnections[m.Mirror] assert.False(t, x) assert.Equal(t, len(d.Peers.Peers.Peerlist), 0) // Test valid m.valid = true d.ExpectingIntroductions[addr] = time.Now() m.Process(d) // d.ExpectingIntroductions should get updated _, x = d.ExpectingIntroductions[addr] assert.False(t, x) assert.Equal(t, len(d.Peers.Peers.Peerlist), 1) assert.Equal(t, d.ConnectionMirrors[addr], m.Mirror) assert.NotNil(t, d.mirrorConnections[m.Mirror]) assert.Equal(t, d.mirrorConnections[m.Mirror][addrIP], addrPort) peerAddr := fmt.Sprintf("%s:%d", addrIP, poolPort) assert.NotNil(t, d.Peers.Peers.Peerlist[peerAddr]) // Handle impossibly bad ip:port returned from conn.Addr() // User should be disconnected m.valid = true m.c = messageContext(badAddrPort) m.Process(d) if len(d.Pool.Pool.DisconnectQueue) != 1 { t.Fatalf("DisconnectQueue empty") } <-d.Pool.Pool.DisconnectQueue m.valid = true m.c = messageContext(badAddrNoPort) m.Process(d) if len(d.Pool.Pool.DisconnectQueue) != 1 { t.Fatalf("DisconnectQueue empty") } <-d.Pool.Pool.DisconnectQueue gnet.EraseMessages() }
func TestIntroductionMessageHandle(t *testing.T) { d := newDefaultDaemon() defer shutdown(d) mc := messageContext(addr) m := NewIntroductionMessage(d.Messages.Mirror, d.Config.Version, d.Pool.Pool.Config.Port) // Test valid handling m.Mirror = d.Messages.Mirror + 1 err := m.Handle(mc, d) assert.Nil(t, err) if len(d.messageEvents) == 0 { t.Fatalf("messageEvent is empty") } <-d.messageEvents assert.True(t, m.valid) m.valid = false // Test matching mirror m.Mirror = d.Messages.Mirror err = m.Handle(mc, d) assert.Equal(t, err, DisconnectSelf) m.Mirror = d.Messages.Mirror + 1 assert.False(t, m.valid) // Test mismatched d.Config.Version m.Version = d.Config.Version + 1 err = m.Handle(mc, d) assert.Equal(t, err, DisconnectInvalidVersion) assert.False(t, m.valid) // Test serialization m = NewIntroductionMessage(d.Messages.Mirror, d.Config.Version, d.Pool.Pool.Config.Port) b := encoder.Serialize(m) m2 := IntroductionMessage{} assert.Nil(t, encoder.DeserializeRaw(b, &m2)) assert.Equal(t, *m, m2) // Test already connected d.mirrorConnections[m.Mirror] = make(map[string]uint16) d.mirrorConnections[m.Mirror][addrIP] = addrPort + 1 err = m.Handle(mc, d) assert.Equal(t, err, DisconnectConnectedTwice) delete(d.mirrorConnections, m.Mirror) assert.False(t, m.valid) for len(d.messageEvents) > 0 { <-d.messageEvents } gnet.EraseMessages() }
func TestRequestPeers(t *testing.T) { defer cleanupPeers() gnet.EraseMessages() defer gnet.EraseMessages() // Disabled c := NewPeersConfig() c.Disabled = true p := NewPeers(c) assert.NotPanics(t, func() { p.requestPeers(nil) }) // Full c.Disabled = false c.Max = 1 p = NewPeers(c) p.Init() p.Peers.AddPeer(addr) assert.NotPanics(t, func() { p.requestPeers(nil) }) // Not full, will send message c.Max = 10 p = NewPeers(c) p.Init() p.Peers.AddPeer(addr) pool, gc := setupPool() go pool.Pool.ConnectionWriteLoop(gc) defer gc.Close() assert.NotPanics(t, func() { p.requestPeers(pool) }) wait() assert.Equal(t, len(pool.Pool.SendResults), 1) if len(pool.Pool.SendResults) == 0 { t.Fatalf("SendResults empty, would block") } sr := <-pool.Pool.SendResults assert.Equal(t, sr.Connection, gc) assert.Nil(t, sr.Error) _, ok := sr.Message.(*GetPeersMessage) assert.True(t, ok) }
func TestVisorBroadcastOurTransactions(t *testing.T) { defer cleanupVisor() defer gnet.EraseMessages() p, gc := setupPool() vc, _ := setupVisor() go p.Pool.ConnectionWriteLoop(gc) // Disabled vc.Disabled = true v := NewVisor(vc) assert.NotPanics(t, func() { v.BroadcastOurTransactions(p) }) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, gc.LastSent.IsZero()) // With no transactions, nothing should be sent vc.Disabled = false vc.TransactionRebroadcastRate = time.Millisecond * 5 v = NewVisor(vc) time.Sleep(time.Millisecond * 20) assert.NotPanics(t, func() { v.BroadcastOurTransactions(p) }) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, gc.LastSent.IsZero()) // We have a stale owned unconfirmed txn, it should be sent gc.Conn = NewDummyConn(addr) vc.Disabled = false v = NewVisor(vc) tx := addUnconfirmedTxn(v) assert.Equal(t, len(v.Visor.Unconfirmed.Txns), 1) assert.NotPanics(t, func() { v.BroadcastOurTransactions(p) }) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } sr := <-p.Pool.SendResults assert.Nil(t, sr.Error) assert.Equal(t, sr.Connection, gc) msg, ok := sr.Message.(*AnnounceTxnsMessage) assert.True(t, ok) assert.Equal(t, msg.Txns, coin.Transactions{tx.Txn}.Hashes()) assert.False(t, gc.LastSent.IsZero()) }
func TestVisorRequestBlocksFromAddr(t *testing.T) { defer cleanupVisor() defer gnet.EraseMessages() p, gc := setupPool() vc, _ := setupVisor() go p.Pool.ConnectionWriteLoop(gc) // Disabled vc.Disabled = true v := NewVisor(vc) assert.NotPanics(t, func() { err := v.RequestBlocksFromAddr(p, addr) assert.NotNil(t, err) assert.Equal(t, err.Error(), "Visor disabled") }) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, gc.LastSent.IsZero()) vc.Disabled = false v = NewVisor(vc) assert.NotPanics(t, func() { assert.Nil(t, v.RequestBlocksFromAddr(p, addr)) }) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } sr := <-p.Pool.SendResults assert.Nil(t, sr.Error) assert.Equal(t, sr.Connection, gc) _, ok := sr.Message.(*GetBlocksMessage) assert.True(t, ok) assert.False(t, gc.LastSent.IsZero()) // No connection found for addr gc.LastSent = util.ZeroTime() gc.Conn = NewDummyConn(addr) delete(p.Pool.Pool, gc.Id) delete(p.Pool.Addresses, gc.Addr()) assert.NotPanics(t, func() { assert.NotNil(t, v.RequestBlocksFromAddr(p, addr)) }) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.True(t, gc.LastSent.IsZero()) }
func TestPongMessage(t *testing.T) { cmsgs := NewMessagesConfig() cmsgs.Register() m := &PongMessage{} // Pongs dont do anything assert.Nil(t, m.Handle(messageContext(addr), nil)) gnet.EraseMessages() // Test serialization mm := PongMessage{} b := encoder.Serialize(mm) m2 := PongMessage{} assert.Nil(t, encoder.DeserializeRaw(b, &m2)) assert.Equal(t, mm, m2) }
func TestStart(t *testing.T) { gnet.EraseMessages() defer cleanupPeers() d, quit := setupDaemonLoopDHT() defer closeDaemon(d, quit) assert.NotNil(t, d) assert.NotNil(t, d.Pool) assert.NotNil(t, d.DHT) go d.Start(quit) wait() assert.NotEqual(t, len(gnet.MessageIdMap), 0) assert.NotNil(t, d.Pool) assert.NotNil(t, d.Peers) assert.NotNil(t, d.DHT) assert.NotNil(t, d.Messages) assert.NotNil(t, d.Gateway) }
func TestOnConnect(t *testing.T) { d := newDefaultDaemon() // Test a valid connection, unsolicited e := ConnectEvent{addr, false} p, _ := d.Peers.Peers.AddPeer(addr) c := setupExistingPool(d.Pool) go d.Pool.Pool.ConnectionWriteLoop(c) d.pendingConnections[addr] = p assert.NotPanics(t, func() { d.onConnect(e) }) wait() assert.Equal(t, len(d.Pool.Pool.SendResults), 1) if len(d.Pool.Pool.SendResults) == 0 { t.Fatalf("SendResults empty, would block") } sr := <-d.Pool.Pool.SendResults assert.Equal(t, sr.Connection, c) assert.Nil(t, sr.Error) _, ok := sr.Message.(*IntroductionMessage) assert.True(t, ok) // This connection should no longer be pending assert.Equal(t, len(d.pendingConnections), 0) // This is not an outgoing connection, we did not solicit it assert.Equal(t, len(d.OutgoingConnections), 0) // We should be expecting its version assert.Equal(t, len(d.ExpectingIntroductions), 1) _, exists := d.ExpectingIntroductions[addr] assert.True(t, exists) // An introduction should have been sent assert.False(t, c.LastSent.IsZero()) // d.ipCounts should be 1 assert.Equal(t, d.ipCounts[addrIP], 1) // Cleanup delete(d.ipCounts, addrIP) delete(d.ExpectingIntroductions, addr) c.Close() // Test a valid connection, solicited e = ConnectEvent{addr, true} c = gnetConnection(addr) go d.Pool.Pool.ConnectionWriteLoop(c) d.pendingConnections[addr] = p d.Pool.Pool.Addresses[addr] = c d.Pool.Pool.Pool[c.Id] = c assert.NotPanics(t, func() { d.onConnect(e) }) wait() assert.Equal(t, len(d.Pool.Pool.SendResults), 1) if len(d.Pool.Pool.SendResults) == 0 { t.Fatalf("SendResults empty, would block") } sr = <-d.Pool.Pool.SendResults assert.Equal(t, sr.Connection, c) assert.Nil(t, sr.Error) _, ok = sr.Message.(*IntroductionMessage) assert.True(t, ok) // This connection should no longer be pending assert.Equal(t, len(d.pendingConnections), 0) // We should mark this as an outgoing connection since we solicited it assert.Equal(t, len(d.OutgoingConnections), 1) assert.NotNil(t, d.OutgoingConnections[addr]) // We should be expecting its version assert.Equal(t, len(d.ExpectingIntroductions), 1) _, exists = d.ExpectingIntroductions[addr] assert.True(t, exists) // An introduction should have been sent assert.False(t, c.LastSent.IsZero()) // d.ipCounts should be 1 assert.Equal(t, d.ipCounts[addrIP], 1) // Cleanup c.Close() delete(d.ExpectingIntroductions, addr) delete(d.OutgoingConnections, addr) delete(d.ipCounts, addrIP) // Test a connection that is not connected by the time of processing c.LastSent = util.ZeroTime() e = ConnectEvent{addr, true} delete(d.Pool.Pool.Addresses, addr) d.pendingConnections[addr] = p assert.NotPanics(t, func() { d.onConnect(e) }) wait() assert.Equal(t, len(d.Pool.Pool.SendResults), 0) // This connection should no longer be pending assert.Equal(t, len(d.pendingConnections), 0) // No message should have been sent assert.True(t, c.LastSent.IsZero()) // We should not be expecting its version assert.Equal(t, len(d.ExpectingIntroductions), 0) // We should not have recorded it to ipCount assert.Equal(t, d.ipCounts[addrIP], 0) // Test a connection that is blacklisted e = ConnectEvent{addr, true} c = gnetConnection(addr) go d.Pool.Pool.ConnectionWriteLoop(c) d.Peers.Peers.AddBlacklistEntry(addr, time.Hour) d.pendingConnections[addr] = p d.Pool.Pool.Addresses[addr] = c d.Pool.Pool.Pool[c.Id] = c assert.NotPanics(t, func() { d.onConnect(e) }) wait() // No introduction should have been sent assert.Equal(t, len(d.Pool.Pool.SendResults), 0) // This connection should no longer be pending assert.Equal(t, len(d.pendingConnections), 0) // No message should have been sent assert.True(t, c.LastSent.IsZero()) // We should not be expecting its version assert.Equal(t, len(d.ExpectingIntroductions), 0) // We should not have recorded its ipCount assert.Equal(t, d.ipCounts[addrIP], 0) // We should be looking to disconnect this client assert.Equal(t, len(d.Pool.Pool.DisconnectQueue), 1) if len(d.Pool.Pool.DisconnectQueue) == 0 { t.Fatal("pool.Pool.DisconnectQueue is empty, would block") } de := <-d.Pool.Pool.DisconnectQueue assert.Equal(t, de.ConnId, 1) assert.Equal(t, de.Reason, DisconnectIsBlacklisted) // Cleanup c.Close() delete(d.Peers.Peers.Blacklist, addr) // Test a connection that has reached maxed ipCount e = ConnectEvent{addr, true} c = gnetConnection(addr) go d.Pool.Pool.ConnectionWriteLoop(c) d.ipCounts[addrIP] = d.Config.IPCountsMax d.pendingConnections[addr] = p d.Pool.Pool.Addresses[addr] = c d.Pool.Pool.Pool[c.Id] = c assert.NotPanics(t, func() { d.onConnect(e) }) wait() // No introduction should have been sent assert.Equal(t, len(d.Pool.Pool.SendResults), 0) // This connection should no longer be pending assert.Equal(t, len(d.pendingConnections), 0) // No message should have been sent assert.True(t, c.LastSent.IsZero()) // We should not be expecting its version assert.Equal(t, len(d.ExpectingIntroductions), 0) // d.ipCounts should be unchanged assert.Equal(t, d.ipCounts[addrIP], d.Config.IPCountsMax) // We should be looking to disconnect this client assert.Equal(t, len(d.Pool.Pool.DisconnectQueue), 1) if len(d.Pool.Pool.DisconnectQueue) == 0 { t.Fatal("pool.Pool.DisconnectQueue is empty, would block") } de = <-d.Pool.Pool.DisconnectQueue assert.Equal(t, de.ConnId, 1) assert.Equal(t, de.Reason, DisconnectIPLimitReached) // Cleanup c.Close() delete(d.ipCounts, addrIP) gnet.EraseMessages() shutdown(d) }
func shutdown(d *Daemon) { d.Shutdown() wait() cleanupPeers() gnet.EraseMessages() }
func TestCreateAndPublishBlock(t *testing.T) { defer cleanupVisor() defer gnet.EraseMessages() p, gc := setupPool() vc, mv := setupVisor() dest := visor.NewWalletEntry() go p.Pool.ConnectionWriteLoop(gc) // Disabled vc.Disabled = true vc.Config = mv.Config v := NewVisor(vc) v.Visor = mv err := v.CreateAndPublishBlock(p) assert.NotNil(t, err) wait() assert.Equal(t, err.Error(), "Visor disabled") assert.Equal(t, len(p.Pool.SendResults), 0) assert.Equal(t, v.Visor.MostRecentBkSeq(), uint64(0)) // Created and sent vc.Disabled = false vc.Config.IsMaster = true vc.Config = mv.Config v = NewVisor(vc) gc.Conn = NewDummyConn(addr) _, err = v.Spend(visor.Balance{10 * 1e6, 0}, 0, dest.Address, p) assert.Nil(t, err) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } <-p.Pool.SendResults err = v.CreateAndPublishBlock(p) wait() assert.Nil(t, err) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } sr := <-p.Pool.SendResults assert.Nil(t, sr.Error) assert.Equal(t, sr.Connection, gc) _, ok := sr.Message.(*GiveBlocksMessage) assert.True(t, ok) assert.Equal(t, v.Visor.MostRecentBkSeq(), uint64(1)) // Can't create, don't have coins // First, spend all of our coins vc, _ = setupVisor() vc.Config.IsMaster = true vc.Config.MasterKeys = visor.NewWalletEntry() vc.Disabled = false v = NewVisor(vc) tx, err := v.Spend(visor.Balance{100 * 1e6 * 1e6, 0}, 1024*1024, dest.Address, p) mv.RecordTxn(tx) wait() assert.Nil(t, err) assert.Equal(t, len(p.Pool.SendResults), 1) for len(p.Pool.SendResults) > 0 { <-p.Pool.SendResults } err = v.CreateAndPublishBlock(p) assert.Nil(t, err) wait() assert.Equal(t, len(p.Pool.SendResults), 1) for len(p.Pool.SendResults) > 0 { <-p.Pool.SendResults } // No coins to spend, fail assert.Equal(t, v.Visor.MostRecentBkSeq(), uint64(1)) _, err = v.Spend(visor.Balance{10 * 1e6, 0}, 0, dest.Address, p) assert.NotNil(t, err) wait() assert.Equal(t, len(p.Pool.SendResults), 0) err = v.CreateAndPublishBlock(p) assert.NotNil(t, err) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.Equal(t, v.Visor.MostRecentBkSeq(), uint64(1)) }
func TestVisorResendTransaction(t *testing.T) { defer cleanupVisor() defer gnet.EraseMessages() p, gc := setupPool() go p.Pool.ConnectionWriteLoop(gc) vc, mv := setupVisor() v := NewVisor(vc) assert.Equal(t, len(v.Visor.Unconfirmed.Txns), 0) // Nothing should happen if txn unknown v.ResendTransaction(coin.SumSHA256([]byte("garbage")), p) wait() assert.Equal(t, len(p.Pool.SendResults), 0) assert.Equal(t, len(p.Pool.SendResults), 0) assert.Equal(t, len(v.Visor.Unconfirmed.Txns), 0) assert.True(t, gc.LastSent.IsZero()) // give the visor some coins, and make a spend to add a txn assert.Nil(t, transferCoins(mv, v.Visor)) tx, err := v.Spend(visor.Balance{10e6, 0}, 0, mv.Wallet.GetAddresses()[0], p) assert.Nil(t, err) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } <-p.Pool.SendResults assert.Equal(t, len(v.Visor.Unconfirmed.Txns), 1) h := tx.Hash() ut := v.Visor.Unconfirmed.Txns[h] ut.Announced = util.ZeroTime() v.Visor.Unconfirmed.Txns[h] = ut assert.True(t, v.Visor.Unconfirmed.Txns[h].Announced.IsZero()) // Reset the sent timer since we made a successful spend gc.LastSent = util.ZeroTime() // Nothing should send if disabled v.Config.Disabled = true v.ResendTransaction(h, p) wait() assert.Equal(t, len(p.Pool.SendResults), 0) ann := v.Visor.Unconfirmed.Txns[h].Announced assert.True(t, ann.IsZero()) assert.True(t, gc.LastSent.IsZero()) // Should have resent v.Config.Disabled = false gc.Conn = NewDummyConn(addr) v.ResendTransaction(h, p) wait() assert.Equal(t, len(p.Pool.SendResults), 1) if len(p.Pool.SendResults) == 0 { t.Fatal("SendResults empty, would block") } sr := <-p.Pool.SendResults assert.Nil(t, sr.Error) assert.Equal(t, sr.Connection, gc) _, ok := sr.Message.(*GiveTxnsMessage) assert.True(t, ok) ann = v.Visor.Unconfirmed.Txns[h].Announced // Announced state should not be updated until we process it assert.True(t, ann.IsZero()) assert.False(t, gc.LastSent.IsZero()) }
func TestRegisterMessages(t *testing.T) { gnet.EraseMessages() c := NewMessagesConfig() assert.NotPanics(t, c.Register) gnet.EraseMessages() }
func testBlockCreationTicker(t *testing.T, vcfg VisorConfig, master bool, mv *visor.Visor) { vcfg.Config.BlockCreationInterval = 1 defer gnet.EraseMessages() c := NewConfig() c.Visor = vcfg c.Daemon.DisableNetworking = false d := NewDaemon(c) if !master { err := transferCoins(mv, d.Visor.Visor) assert.Nil(t, err) } quit := make(chan int) defer closeDaemon(d, quit) gc := setupExistingPool(d.Pool) go d.Pool.Pool.ConnectionWriteLoop(gc) assert.True(t, gc.LastSent.IsZero()) assert.Equal(t, len(d.Pool.Pool.Pool), 1) assert.Equal(t, d.Pool.Pool.Pool[gc.Id], gc) assert.Equal(t, len(d.Pool.Pool.Addresses), 1) start := 0 if !master { start = 1 } assert.Equal(t, d.Visor.Visor.MostRecentBkSeq(), uint64(start)) go d.Start(quit) time.Sleep(time.Second + (time.Millisecond * 50)) // Creation should not have occured, because no transaction assert.Equal(t, d.Visor.Visor.MostRecentBkSeq(), uint64(start)) assert.Equal(t, len(d.Pool.Pool.SendResults), 0) // Creation should occur with a transaction, if not a master // Make a transaction assert.False(t, d.Visor.Config.Disabled) assert.True(t, gc.LastSent.IsZero()) dest := visor.NewWalletEntry() tx, err := d.Visor.Spend(visor.Balance{10 * 1e6, 0}, 0, dest.Address, d.Pool) wait() assert.Nil(t, err) assert.Equal(t, d.Pool.Pool.Pool[gc.Id], gc) assert.Equal(t, len(d.Pool.Pool.DisconnectQueue), 0) assert.Equal(t, len(d.Pool.Pool.Pool), 1) assert.Equal(t, len(d.Pool.Pool.Addresses), 1) // Since the daemon loop is running, it will have processed the SendResult // Instead we can check if the txn was announced assert.Equal(t, len(d.Pool.Pool.SendResults), 0) ut := d.Visor.Visor.Unconfirmed.Txns[tx.Hash()] assert.False(t, ut.Announced.IsZero()) assert.False(t, gc.LastSent.IsZero()) ls := gc.LastSent // Now, block should be created time.Sleep(time.Second + (time.Millisecond * 50)) final := start if master { final += 1 } assert.Equal(t, len(d.Pool.Pool.Pool), 1) // Again, we can't check SendResults since the daemon loop is running. // We can only check that LastSent was updated, if its the master and it // created the block. if master { assert.True(t, gc.LastSent.After(ls)) } else { assert.Equal(t, gc.LastSent, ls) } assert.Equal(t, d.Visor.Visor.MostRecentBkSeq(), uint64(final)) assert.False(t, gc.LastSent.IsZero()) }