github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/qln/autoconnect.go (about) 1 package qln 2 3 import ( 4 "time" 5 6 "github.com/mit-dci/lit/logging" 7 8 "github.com/mit-dci/lit/bech32" 9 "github.com/mit-dci/lit/crypto/fastsha256" 10 ) 11 12 func removeDuplicates(inputArr []uint32) []uint32 { 13 keys := make(map[uint32]bool) 14 outputArr := []uint32{} 15 for _, entry := range inputArr { 16 if _, value := keys[entry]; !value { 17 keys[entry] = true 18 outputArr = append(outputArr, entry) 19 } 20 } 21 return outputArr 22 } 23 24 // AutoReconnect will start listening for incoming connections 25 // and attempt to automatically reconnect to all 26 // previously known peers attached with the coin daemons running. 27 func (nd *LitNode) AutoReconnect(port int, interval int64, connectedCoinOnly bool) { 28 // Listen myself after a timeout 29 _, err := nd.TCPListener(port) 30 if err != nil { 31 logging.Errorf("Could not start listening automatically: %s", err.Error()) 32 return 33 } 34 35 // Reconnect to other nodes after an interval 36 ticker := time.NewTicker(time.Duration(interval) * time.Second) 37 qcs, _ := nd.GetAllQchans() // get all chan data 38 coinMap := make(map[uint32][]uint32) 39 for _, qc := range qcs { 40 // make a map of all channel data with the key as coinType 41 coinMap[qc.Coin()] = append(coinMap[qc.Coin()], qc.KeyGen.Step[3]&0x7fffffff) 42 } 43 for i, arr := range coinMap { 44 // remove duplicates in the map 45 if nd.ConnectedCoinTypes[i] { 46 coinMap[i] = removeDuplicates(arr) 47 } 48 } 49 50 isConnectedCoin := func(peerIdx uint32) bool { 51 // now only connect to those peers in the array 52 for _, arr := range coinMap { 53 for _, i := range arr { 54 if peerIdx == i { 55 return true 56 } 57 } 58 } 59 return false 60 } 61 62 var empty [33]byte 63 i := uint32(1) 64 for { 65 66 pubKey, _ := nd.GetPubHostFromPeerIdx(i) 67 if pubKey == empty { 68 logging.Infof("Done, tried %d hosts\n", i-1) 69 break 70 } 71 72 // If we're only reconnecting to peers we have channels with 73 // in a connected coin type (daemon is available), then skip 74 // peers that are not in that list 75 if connectedCoinOnly && !isConnectedCoin(i) { 76 logging.Infof("Skipping peer %d due to onlyConnectedCoins=true\n", i) 77 i++ 78 continue 79 } 80 81 nd.RemoteMtx.Lock() 82 _, alreadyConnected := nd.RemoteCons[i] 83 nd.RemoteMtx.Unlock() 84 if alreadyConnected { 85 continue 86 } 87 idHash := fastsha256.Sum256(pubKey[:]) 88 adr := bech32.Encode("ln", idHash[:20]) 89 go func() { 90 err := nd.DialPeer(adr) 91 if err != nil { 92 logging.Errorf("Could not restore connection to %s: %s\n", adr, err.Error()) 93 } 94 <-ticker.C 95 }() 96 97 i++ 98 } 99 100 }