package monitor import ( "fmt" "log" "math" "math/big" "strconv" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" ) type node struct { owner common.Address email string fined *big.Int name string publicKey []byte nodeKeyAddress common.Address } func (n node) Print() { fmt.Println("========") fmt.Println(n.name) fmt.Println("fined: ", n.fined) fmt.Println("email: ", n.email) fmt.Println("owner: ", n.owner.Hex()) fmt.Println("nodekey address: ", n.nodeKeyAddress.Hex()) } // NetworkConfig represents the network config. type NetworkConfig struct { WSEndpoint string HTTPEndpoint string EthHTTPEndpoint string GovAddress common.Address Network string } // GovAddress is governance address. var GovAddress = common.HexToAddress("0x246FcDE58581e2754f215A523C0718C4BFc8041F") // Fifty is 50 * 10^18 var Fifty *big.Int // OneHundred is 100 * 10^18 var OneHundred *big.Int func init() { Fifty, _ = big.NewInt(0).SetString("50000000000000000000", 10) OneHundred, _ = big.NewInt(0).SetString("100000000000000000000", 10) } // NetworkConfigMap represents the system network config mapping. var NetworkConfigMap = map[int64]NetworkConfig{ 411: { WSEndpoint: "wss://mainnet-rpc.tangerine-network.io/ws", HTTPEndpoint: "https://mainnet-rpc.tangerine-network.io", EthHTTPEndpoint: "https://mainnet.infura.io/v3/4eb07139b29d41c59b352f21c4c9f526", Network: "Mainnet", }, 374: { WSEndpoint: "wss://testnet-rpc.tangerine-network.io/ws", HTTPEndpoint: "https://testnet-rpc.tangerine-network.io", EthHTTPEndpoint: "https://rinkeby.infura.io/v3/4eb07139b29d41c59b352f21c4c9f526", Network: "Testnet", }, } // Monitor is the object to monitor tangerine network. type Monitor struct { networkID int notifiers []Notifier backend backendIntf tanBalancesCache map[common.Address]*big.Int ethBalancesCache map[common.Address]*big.Int ethThreshold *big.Int // in wei ethThresholdString string // in ETH checkBalanceDuration time.Duration } // NewMonitor is the constructor for monitor object. func NewMonitor(networkID int, backend backendIntf, threshold string) *Monitor { tanBalance := make(map[common.Address]*big.Int) ethBalance := make(map[common.Address]*big.Int) t, err := strconv.ParseFloat(threshold, 64) if err != nil { panic(err) } t = t * math.Pow(10, 18) ethThreshold := new(big.Int) ethThreshold.SetString( strconv.FormatFloat(t, 'f', 0, 64), 10, ) m := Monitor{ networkID: networkID, backend: backend, tanBalancesCache: tanBalance, ethBalancesCache: ethBalance, checkBalanceDuration: 24 * time.Hour, ethThresholdString: threshold, ethThreshold: ethThreshold, } return &m } // Run is the entry point for running monitor. func (m *Monitor) Run() { done := make(chan bool) finedNodeChan := make(chan node) go m.fetchFinedNodes(finedNodeChan) go m.sendNotifications(finedNodeChan, FINED) go m.checkTanBalance() go m.checkEthBalance() <-done } func (m *Monitor) checkEthBalance() { ethNodeChan := make(chan node) go m.sendNotifications(ethNodeChan, INSUFFICIENT_ETH) for { nc := NetworkConfigMap[int64(m.networkID)] conn, err := ethclient.Dial(nc.EthHTTPEndpoint) if err != nil { log.Println("Get Tan balance fail at") continue } nodes := m.backend.NodeSet() for i := range nodes { n := nodes[i] address := n.nodeKeyAddress balance := m.backend.BalanceFromAddress(conn, address) if balance.Cmp(m.ethThreshold) < 0 { if cacheBalance, exist := m.ethBalancesCache[address]; exist { if cacheBalance.Cmp(m.ethThreshold) >= 0 { ethNodeChan <- n } } else { ethNodeChan <- n } } m.ethBalancesCache[address] = balance } time.Sleep(m.checkBalanceDuration) } } func (m *Monitor) checkTanBalance() { tanNodeChan := make(chan node) go m.sendNotifications(tanNodeChan, INSUFFICIENT_TAN) for { nodes := m.backend.NodeSet() nc := NetworkConfigMap[int64(m.networkID)] conn, err := ethclient.Dial(nc.HTTPEndpoint) if err != nil { log.Println("Get TAN balance fail") continue } for i := range nodes { n := nodes[i] balance := m.backend.BalanceFromAddress(conn, n.nodeKeyAddress) if balance.Cmp(Fifty) < 0 { if cacheBalance, exist := m.tanBalancesCache[n.nodeKeyAddress]; exist { if cacheBalance.Cmp(Fifty) >= 0 { tanNodeChan <- n } } else { tanNodeChan <- n } } else if balance.Cmp(OneHundred) < 0 { if cacheBalance, exist := m.tanBalancesCache[n.nodeKeyAddress]; exist { if cacheBalance.Cmp(OneHundred) >= 0 { tanNodeChan <- n } } else { tanNodeChan <- n } } m.tanBalancesCache[n.nodeKeyAddress] = balance } time.Sleep(m.checkBalanceDuration) } } // Register registries the notifiers. func (m *Monitor) Register(n Notifier) { m.notifiers = append(m.notifiers, n) } func (m *Monitor) fetchFinedNodes(nodeChan chan node) { m.backend.FetchFinedNodes(nodeChan) } func (m *Monitor) sendNotifications(nodeChan chan node, notifyType uint) { nc := NetworkConfigMap[int64(m.networkID)] for { node, open := <-nodeChan if !open { return } for _, notifier := range m.notifiers { notifier.notify(node, nc.Network, notifyType, m.ethThresholdString) } } } o/libdssialsacompat'>log</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/tree/audio/libdssialsacompat?id=7e7e63aa49ff223c68742601e95308bc747920a9'>tree</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/audio/libdssialsacompat?id=7e7e63aa49ff223c68742601e95308bc747920a9'>commit</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/diff/audio/libdssialsacompat?id=7e7e63aa49ff223c68742601e95308bc747920a9'>diff</a><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/stats/audio/libdssialsacompat'>stats</a></td><td class='form'><form class='right' method='get' action='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/audio/libdssialsacompat'> <input type='hidden' name='id' value='7e7e63aa49ff223c68742601e95308bc747920a9'/><select name='qt'> <option value='grep'>log msg</option> <option value='author'>author</option> <option value='committer'>committer</option> <option value='range'>range</option> </select> <input class='txt' type='search' size='10' name='q' value=''/> <input type='submit' value='search'/> </form> </td></tr></table> <div class='path'>path: <a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/?id=7e7e63aa49ff223c68742601e95308bc747920a9'>root</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/audio?id=7e7e63aa49ff223c68742601e95308bc747920a9'>audio</a>/<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/audio/libdssialsacompat?id=7e7e63aa49ff223c68742601e95308bc747920a9'>libdssialsacompat</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th></th><th class='left'>Commit message (<a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/log/audio/libdssialsacompat?id=7e7e63aa49ff223c68742601e95308bc747920a9&showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Age</th><th class='left'>Files</th><th class='left'>Lines</th></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/audio/libdssialsacompat?id=a6abc3b42030610bc8f182e713867c3b8ed9dab5'>Cleanup plist</a></td><td>Baptiste Daroussin</td><td><span title='2014-10-20 14:35:58 +0800'>2014-10-20</span></td><td>1</td><td><span class='deletions'>-3</span>/<span class='insertions'>+0</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/audio/libdssialsacompat?id=fdbacb726345612e79bf62506838c230ec5709b1'>- Drop .la files, no dependees require them</a></td><td>Dmitry Marakasov</td><td><span title='2014-08-22 21:06:41 +0800'>2014-08-22</span></td><td>2</td><td><span class='deletions'>-3</span>/<span class='insertions'>+2</span></td></tr> <tr><td class='commitgraph'>* </td><td><a href='/~lantw44/cgit/cgit.cgi/freebsd-ports-gnome/commit/audio/libdssialsacompat?id=ff44441fb3d030270aa68bce83ea210145560e1e'>- Switch to USES=libtool</a></td><td>Dmitry Marakasov</td><td><span title='2014-06-16 22:19:29 +0800'>2014-06-16</span>