mirror of
https://github.com/ditatompel/xmr-remote-nodes.git
synced 2025-01-08 05:52:10 +07:00
Moving monero.go to its own internal package
This commit is contained in:
parent
7d69e9af95
commit
ddc448e90c
7 changed files with 117 additions and 116 deletions
|
@ -13,7 +13,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
"xmr-remote-nodes/internal/config"
|
"xmr-remote-nodes/internal/config"
|
||||||
"xmr-remote-nodes/internal/repo"
|
"xmr-remote-nodes/internal/monero"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
|
@ -66,13 +66,13 @@ func RunProbe() {
|
||||||
slog.Debug(fmt.Sprintf("[PROBE] fetchNode: %s", prettyPrint(fetchNode)))
|
slog.Debug(fmt.Sprintf("[PROBE] fetchNode: %s", prettyPrint(fetchNode)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proberClient) getJob() (repo.MoneroNode, error) {
|
func (p *proberClient) getJob() (monero.Node, error) {
|
||||||
queryParams := ""
|
queryParams := ""
|
||||||
if p.config.AcceptTor {
|
if p.config.AcceptTor {
|
||||||
queryParams = "?accept_tor=1"
|
queryParams = "?accept_tor=1"
|
||||||
}
|
}
|
||||||
|
|
||||||
node := repo.MoneroNode{}
|
var node monero.Node
|
||||||
|
|
||||||
endpoint := fmt.Sprintf("%s/api/v1/job%s", p.config.ServerEndpoint, queryParams)
|
endpoint := fmt.Sprintf("%s/api/v1/job%s", p.config.ServerEndpoint, queryParams)
|
||||||
slog.Info(fmt.Sprintf("[PROBE] Getting node from %s", endpoint))
|
slog.Info(fmt.Sprintf("[PROBE] Getting node from %s", endpoint))
|
||||||
|
@ -96,7 +96,7 @@ func (p *proberClient) getJob() (repo.MoneroNode, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
response := struct {
|
response := struct {
|
||||||
Data repo.MoneroNode `json:"data"`
|
Data monero.Node `json:"data"`
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
err = json.NewDecoder(resp.Body).Decode(&response)
|
err = json.NewDecoder(resp.Body).Decode(&response)
|
||||||
|
@ -110,7 +110,7 @@ func (p *proberClient) getJob() (repo.MoneroNode, error) {
|
||||||
return node, nil
|
return node, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proberClient) fetchNode(node repo.MoneroNode) (repo.MoneroNode, error) {
|
func (p *proberClient) fetchNode(node monero.Node) (monero.Node, error) {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
endpoint := fmt.Sprintf("%s://%s:%d/json_rpc", node.Protocol, node.Hostname, node.Port)
|
endpoint := fmt.Sprintf("%s://%s:%d/json_rpc", node.Protocol, node.Hostname, node.Port)
|
||||||
rpcParam := []byte(`{"jsonrpc": "2.0","id": "0","method": "get_info"}`)
|
rpcParam := []byte(`{"jsonrpc": "2.0","id": "0","method": "get_info"}`)
|
||||||
|
@ -167,7 +167,7 @@ func (p *proberClient) fetchNode(node repo.MoneroNode) (repo.MoneroNode, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
reportNode := struct {
|
reportNode := struct {
|
||||||
repo.MoneroNode `json:"result"`
|
monero.Node `json:"result"`
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
if err := json.Unmarshal(body, &reportNode); err != nil {
|
if err := json.Unmarshal(body, &reportNode); err != nil {
|
||||||
|
@ -178,7 +178,7 @@ func (p *proberClient) fetchNode(node repo.MoneroNode) (repo.MoneroNode, error)
|
||||||
if reportNode.Status == "OK" {
|
if reportNode.Status == "OK" {
|
||||||
node.IsAvailable = true
|
node.IsAvailable = true
|
||||||
}
|
}
|
||||||
node.NetType = reportNode.NetType
|
node.Nettype = reportNode.Nettype
|
||||||
node.AdjustedTime = reportNode.AdjustedTime
|
node.AdjustedTime = reportNode.AdjustedTime
|
||||||
node.DatabaseSize = reportNode.DatabaseSize
|
node.DatabaseSize = reportNode.DatabaseSize
|
||||||
node.Difficulty = reportNode.Difficulty
|
node.Difficulty = reportNode.Difficulty
|
||||||
|
@ -186,7 +186,7 @@ func (p *proberClient) fetchNode(node repo.MoneroNode) (repo.MoneroNode, error)
|
||||||
node.Version = reportNode.Version
|
node.Version = reportNode.Version
|
||||||
|
|
||||||
if resp.Header.Get("Access-Control-Allow-Origin") == "*" || resp.Header.Get("Access-Control-Allow-Origin") == "https://xmr.ditatompel.com" {
|
if resp.Header.Get("Access-Control-Allow-Origin") == "*" || resp.Header.Get("Access-Control-Allow-Origin") == "https://xmr.ditatompel.com" {
|
||||||
node.CorsCapable = true
|
node.CORSCapable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !node.IsTor {
|
if !node.IsTor {
|
||||||
|
@ -194,7 +194,7 @@ func (p *proberClient) fetchNode(node repo.MoneroNode) (repo.MoneroNode, error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Warning: Could not resolve hostname: " + node.Hostname)
|
fmt.Println("Warning: Could not resolve hostname: " + node.Hostname)
|
||||||
} else {
|
} else {
|
||||||
node.Ip = hostIp[0].String()
|
node.IP = hostIp[0].String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,8 +245,8 @@ func (p *proberClient) fetchNode(node repo.MoneroNode) (repo.MoneroNode, error)
|
||||||
return node, nil
|
return node, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proberClient) reportResult(node repo.MoneroNode, tookTime float64) error {
|
func (p *proberClient) reportResult(node monero.Node, tookTime float64) error {
|
||||||
jsonData, err := json.Marshal(repo.ProbeReport{
|
jsonData, err := json.Marshal(monero.ProbeReport{
|
||||||
TookTime: tookTime,
|
TookTime: tookTime,
|
||||||
Message: p.message,
|
Message: p.message,
|
||||||
NodeInfo: node,
|
NodeInfo: node,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"time"
|
"time"
|
||||||
"xmr-remote-nodes/internal/database"
|
"xmr-remote-nodes/internal/database"
|
||||||
"xmr-remote-nodes/internal/repo"
|
"xmr-remote-nodes/internal/monero"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -43,8 +43,8 @@ xmr-nodes probers list -s last_submit_ts -d asc sin1`,
|
||||||
sortBy, _ := cmd.Flags().GetString("sort-by")
|
sortBy, _ := cmd.Flags().GetString("sort-by")
|
||||||
sortDir, _ := cmd.Flags().GetString("sort-dir")
|
sortDir, _ := cmd.Flags().GetString("sort-dir")
|
||||||
|
|
||||||
probersRepo := repo.NewProberRepo(database.GetDB())
|
probersRepo := monero.NewProberRepo(database.GetDB())
|
||||||
probers, err := probersRepo.Probers(repo.ProbersQueryParams{
|
probers, err := probersRepo.Probers(monero.ProbersQueryParams{
|
||||||
Search: strings.Join(args, " "),
|
Search: strings.Join(args, " "),
|
||||||
SortBy: sortBy,
|
SortBy: sortBy,
|
||||||
SortDirection: sortDir,
|
SortDirection: sortDir,
|
||||||
|
@ -90,7 +90,7 @@ This command will display the prober name and API key when successfully executed
|
||||||
proberName = stringPrompt("Prober Name:")
|
proberName = stringPrompt("Prober Name:")
|
||||||
}
|
}
|
||||||
|
|
||||||
proberRepo := repo.NewProberRepo(database.GetDB())
|
proberRepo := monero.NewProberRepo(database.GetDB())
|
||||||
prober, err := proberRepo.Add(proberName)
|
prober, err := proberRepo.Add(proberName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
@ -117,7 +117,7 @@ var editProbersCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
proberName := stringPrompt("Prober Name:")
|
proberName := stringPrompt("Prober Name:")
|
||||||
proberRepo := repo.NewProberRepo(database.GetDB())
|
proberRepo := monero.NewProberRepo(database.GetDB())
|
||||||
err = proberRepo.Edit(proberId, proberName)
|
err = proberRepo.Edit(proberId, proberName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Failed to update prober:", err)
|
fmt.Println("Failed to update prober:", err)
|
||||||
|
@ -143,7 +143,7 @@ var deleteProbersCmd = &cobra.Command{
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
proberRepo := repo.NewProberRepo(database.GetDB())
|
proberRepo := monero.NewProberRepo(database.GetDB())
|
||||||
err = proberRepo.Delete(proberId)
|
err = proberRepo.Delete(proberId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Failed to delete prober:", err)
|
fmt.Println("Failed to delete prober:", err)
|
||||||
|
|
|
@ -2,7 +2,7 @@ package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"xmr-remote-nodes/internal/database"
|
"xmr-remote-nodes/internal/database"
|
||||||
"xmr-remote-nodes/internal/repo"
|
"xmr-remote-nodes/internal/monero"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
@ -17,7 +17,7 @@ func CheckProber(c *fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
proberRepo := repo.NewProberRepo(database.GetDB())
|
proberRepo := monero.NewProberRepo(database.GetDB())
|
||||||
|
|
||||||
prober, err := proberRepo.CheckApi(key)
|
prober, err := proberRepo.CheckApi(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package handler
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"xmr-remote-nodes/internal/database"
|
"xmr-remote-nodes/internal/database"
|
||||||
"xmr-remote-nodes/internal/repo"
|
"xmr-remote-nodes/internal/monero"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
@ -26,7 +26,7 @@ func MoneroNode(c *fiber.Ctx) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
moneroRepo := repo.NewMoneroRepo(database.GetDB())
|
moneroRepo := monero.NewMoneroRepo(database.GetDB())
|
||||||
node, err := moneroRepo.Node(nodeId)
|
node, err := moneroRepo.Node(nodeId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||||
|
@ -44,18 +44,18 @@ func MoneroNode(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func MoneroNodes(c *fiber.Ctx) error {
|
func MoneroNodes(c *fiber.Ctx) error {
|
||||||
moneroRepo := repo.NewMoneroRepo(database.GetDB())
|
moneroRepo := monero.NewMoneroRepo(database.GetDB())
|
||||||
query := repo.MoneroQueryParams{
|
query := monero.MoneroQueryParams{
|
||||||
RowsPerPage: c.QueryInt("limit", 10),
|
RowsPerPage: c.QueryInt("limit", 10),
|
||||||
Page: c.QueryInt("page", 1),
|
Page: c.QueryInt("page", 1),
|
||||||
SortBy: c.Query("sort_by", "id"),
|
SortBy: c.Query("sort_by", "id"),
|
||||||
SortDirection: c.Query("sort_direction", "desc"),
|
SortDirection: c.Query("sort_direction", "desc"),
|
||||||
Host: c.Query("host"),
|
Host: c.Query("host"),
|
||||||
NetType: c.Query("nettype", "any"),
|
Nettype: c.Query("nettype", "any"),
|
||||||
Protocol: c.Query("protocol", "any"),
|
Protocol: c.Query("protocol", "any"),
|
||||||
CC: c.Query("cc", "any"),
|
CC: c.Query("cc", "any"),
|
||||||
Status: c.QueryInt("status", -1),
|
Status: c.QueryInt("status", -1),
|
||||||
Cors: c.QueryInt("cors", -1),
|
CORS: c.QueryInt("cors", -1),
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes, err := moneroRepo.Nodes(query)
|
nodes, err := moneroRepo.Nodes(query)
|
||||||
|
@ -75,13 +75,13 @@ func MoneroNodes(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProbeLogs(c *fiber.Ctx) error {
|
func ProbeLogs(c *fiber.Ctx) error {
|
||||||
moneroRepo := repo.NewMoneroRepo(database.GetDB())
|
moneroRepo := monero.NewMoneroRepo(database.GetDB())
|
||||||
query := repo.MoneroLogQueryParams{
|
query := monero.MoneroLogQueryParams{
|
||||||
RowsPerPage: c.QueryInt("limit", 10),
|
RowsPerPage: c.QueryInt("limit", 10),
|
||||||
Page: c.QueryInt("page", 1),
|
Page: c.QueryInt("page", 1),
|
||||||
SortBy: c.Query("sort_by", "id"),
|
SortBy: c.Query("sort_by", "id"),
|
||||||
SortDirection: c.Query("sort_direction", "desc"),
|
SortDirection: c.Query("sort_direction", "desc"),
|
||||||
NodeId: c.QueryInt("node_id", 0),
|
NodeID: c.QueryInt("node_id", 0),
|
||||||
Status: c.QueryInt("status", -1),
|
Status: c.QueryInt("status", -1),
|
||||||
FailedReason: c.Query("failed_reason"),
|
FailedReason: c.Query("failed_reason"),
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ func AddNode(c *fiber.Ctx) error {
|
||||||
protocol := c.FormValue("protocol")
|
protocol := c.FormValue("protocol")
|
||||||
hostname := c.FormValue("hostname")
|
hostname := c.FormValue("hostname")
|
||||||
|
|
||||||
moneroRepo := repo.NewMoneroRepo(database.GetDB())
|
moneroRepo := monero.NewMoneroRepo(database.GetDB())
|
||||||
if err := moneroRepo.Add(protocol, hostname, uint(port)); err != nil {
|
if err := moneroRepo.Add(protocol, hostname, uint(port)); err != nil {
|
||||||
return c.JSON(fiber.Map{
|
return c.JSON(fiber.Map{
|
||||||
"status": "error",
|
"status": "error",
|
||||||
|
@ -133,7 +133,7 @@ func AddNode(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NetFee(c *fiber.Ctx) error {
|
func NetFee(c *fiber.Ctx) error {
|
||||||
moneroRepo := repo.NewMoneroRepo(database.GetDB())
|
moneroRepo := monero.NewMoneroRepo(database.GetDB())
|
||||||
return c.JSON(fiber.Map{
|
return c.JSON(fiber.Map{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"message": "Success",
|
"message": "Success",
|
||||||
|
@ -142,7 +142,7 @@ func NetFee(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Countries(c *fiber.Ctx) error {
|
func Countries(c *fiber.Ctx) error {
|
||||||
moneroRepo := repo.NewMoneroRepo(database.GetDB())
|
moneroRepo := monero.NewMoneroRepo(database.GetDB())
|
||||||
countries, err := moneroRepo.Countries()
|
countries, err := moneroRepo.Countries()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(fiber.Map{
|
return c.JSON(fiber.Map{
|
||||||
|
@ -161,7 +161,7 @@ func Countries(c *fiber.Ctx) error {
|
||||||
func GiveJob(c *fiber.Ctx) error {
|
func GiveJob(c *fiber.Ctx) error {
|
||||||
acceptTor := c.QueryInt("accept_tor", 0)
|
acceptTor := c.QueryInt("accept_tor", 0)
|
||||||
|
|
||||||
moneroRepo := repo.NewMoneroRepo(database.GetDB())
|
moneroRepo := monero.NewMoneroRepo(database.GetDB())
|
||||||
node, err := moneroRepo.GiveJob(acceptTor)
|
node, err := moneroRepo.GiveJob(acceptTor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(fiber.Map{
|
return c.JSON(fiber.Map{
|
||||||
|
@ -179,8 +179,8 @@ func GiveJob(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProcessJob(c *fiber.Ctx) error {
|
func ProcessJob(c *fiber.Ctx) error {
|
||||||
moneroRepo := repo.NewMoneroRepo(database.GetDB())
|
moneroRepo := monero.NewMoneroRepo(database.GetDB())
|
||||||
report := repo.ProbeReport{}
|
report := monero.ProbeReport{}
|
||||||
|
|
||||||
if err := c.BodyParser(&report); err != nil {
|
if err := c.BodyParser(&report); err != nil {
|
||||||
return c.Status(fiber.StatusUnprocessableEntity).JSON(fiber.Map{
|
return c.Status(fiber.StatusUnprocessableEntity).JSON(fiber.Map{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package repo
|
package geo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/oschwald/geoip2-golang"
|
"github.com/oschwald/geoip2-golang"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GeoIpInfo struct {
|
type IPInfo struct {
|
||||||
Ip string `json:"ip"`
|
Ip string `json:"ip"`
|
||||||
IsAnonymousProxy bool `json:"is_anonymous_proxy"`
|
IsAnonymousProxy bool `json:"is_anonymous_proxy"`
|
||||||
IsSatelliteProvider bool `json:"is_satellite_provider"`
|
IsSatelliteProvider bool `json:"is_satellite_provider"`
|
||||||
|
@ -25,7 +25,7 @@ type GeoIpInfo struct {
|
||||||
Asn uint `json:"asn"`
|
Asn uint `json:"asn"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGeoIpInfo(ipAddr string) (*GeoIpInfo, error) {
|
func IpInfo(ipAddr string) (*IPInfo, error) {
|
||||||
ip := net.ParseIP(ipAddr)
|
ip := net.ParseIP(ipAddr)
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return nil, errors.New("Invalid IP address")
|
return nil, errors.New("Invalid IP address")
|
||||||
|
@ -52,7 +52,7 @@ func GetGeoIpInfo(ipAddr string) (*GeoIpInfo, error) {
|
||||||
return nil, errors.New("Cannot read GeoIP ASN database")
|
return nil, errors.New("Cannot read GeoIP ASN database")
|
||||||
}
|
}
|
||||||
|
|
||||||
qip := GeoIpInfo{
|
qip := IPInfo{
|
||||||
Ip: ipAddr,
|
Ip: ipAddr,
|
||||||
IsAnonymousProxy: cityRecord.Traits.IsAnonymousProxy,
|
IsAnonymousProxy: cityRecord.Traits.IsAnonymousProxy,
|
||||||
IsSatelliteProvider: cityRecord.Traits.IsSatelliteProvider,
|
IsSatelliteProvider: cityRecord.Traits.IsSatelliteProvider,
|
|
@ -1,4 +1,4 @@
|
||||||
package repo
|
package monero
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
@ -11,18 +11,19 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"xmr-remote-nodes/internal/database"
|
"xmr-remote-nodes/internal/database"
|
||||||
|
"xmr-remote-nodes/internal/geo"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx/types"
|
"github.com/jmoiron/sqlx/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MoneroRepository interface {
|
type MoneroRepository interface {
|
||||||
Node(id int) (MoneroNode, error)
|
Node(id int) (Node, error)
|
||||||
Add(protocol string, host string, port uint) error
|
Add(protocol string, host string, port uint) error
|
||||||
Nodes(q MoneroQueryParams) (MoneroNodes, error)
|
Nodes(q MoneroQueryParams) (Nodes, error)
|
||||||
GiveJob(acceptTor int) (MoneroNode, error)
|
GiveJob(acceptTor int) (Node, error)
|
||||||
ProcessJob(report ProbeReport, proberId int64) error
|
ProcessJob(report ProbeReport, proberId int64) error
|
||||||
NetFee() []NetFee
|
NetFee() []NetFee
|
||||||
Countries() ([]MoneroCountries, error)
|
Countries() ([]Countries, error)
|
||||||
Logs(q MoneroLogQueryParams) (MoneroNodeFetchLogs, error)
|
Logs(q MoneroLogQueryParams) (MoneroNodeFetchLogs, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,15 +35,15 @@ func NewMoneroRepo(db *database.DB) MoneroRepository {
|
||||||
return &MoneroRepo{db}
|
return &MoneroRepo{db}
|
||||||
}
|
}
|
||||||
|
|
||||||
type MoneroNode struct {
|
type Node struct {
|
||||||
Id uint `json:"id,omitempty" db:"id"`
|
ID uint `json:"id,omitempty" db:"id"`
|
||||||
Hostname string `json:"hostname" db:"hostname"`
|
Hostname string `json:"hostname" db:"hostname"`
|
||||||
Ip string `json:"ip" db:"ip_addr"`
|
IP string `json:"ip" db:"ip_addr"`
|
||||||
Port uint `json:"port" db:"port"`
|
Port uint `json:"port" db:"port"`
|
||||||
Protocol string `json:"protocol" db:"protocol"`
|
Protocol string `json:"protocol" db:"protocol"`
|
||||||
IsTor bool `json:"is_tor" db:"is_tor"`
|
IsTor bool `json:"is_tor" db:"is_tor"`
|
||||||
IsAvailable bool `json:"is_available" db:"is_available"`
|
IsAvailable bool `json:"is_available" db:"is_available"`
|
||||||
NetType string `json:"nettype" db:"nettype"`
|
Nettype string `json:"nettype" db:"nettype"`
|
||||||
Height uint `json:"height" db:"height"`
|
Height uint `json:"height" db:"height"`
|
||||||
AdjustedTime uint `json:"adjusted_time" db:"adjusted_time"`
|
AdjustedTime uint `json:"adjusted_time" db:"adjusted_time"`
|
||||||
DatabaseSize uint `json:"database_size" db:"database_size"`
|
DatabaseSize uint `json:"database_size" db:"database_size"`
|
||||||
|
@ -51,22 +52,22 @@ type MoneroNode struct {
|
||||||
Status string `json:"status,omitempty"`
|
Status string `json:"status,omitempty"`
|
||||||
Uptime float64 `json:"uptime" db:"uptime"`
|
Uptime float64 `json:"uptime" db:"uptime"`
|
||||||
EstimateFee uint `json:"estimate_fee" db:"estimate_fee"`
|
EstimateFee uint `json:"estimate_fee" db:"estimate_fee"`
|
||||||
Asn uint `json:"asn" db:"asn"`
|
ASN uint `json:"asn" db:"asn"`
|
||||||
AsnName string `json:"asn_name" db:"asn_name"`
|
ASNName string `json:"asn_name" db:"asn_name"`
|
||||||
CountryCode string `json:"cc" db:"country"`
|
CountryCode string `json:"cc" db:"country"`
|
||||||
CountryName string `json:"country_name" db:"country_name"`
|
CountryName string `json:"country_name" db:"country_name"`
|
||||||
City string `json:"city" db:"city"`
|
City string `json:"city" db:"city"`
|
||||||
Lat float64 `json:"latitude" db:"lat"`
|
Latitude float64 `json:"latitude" db:"lat"`
|
||||||
Lon float64 `json:"longitude" db:"lon"`
|
Longitude float64 `json:"longitude" db:"lon"`
|
||||||
DateEntered uint `json:"date_entered,omitempty" db:"date_entered"`
|
DateEntered uint `json:"date_entered,omitempty" db:"date_entered"`
|
||||||
LastChecked uint `json:"last_checked" db:"last_checked"`
|
LastChecked uint `json:"last_checked" db:"last_checked"`
|
||||||
FailedCount uint `json:"failed_count,omitempty" db:"failed_count"`
|
FailedCount uint `json:"failed_count,omitempty" db:"failed_count"`
|
||||||
LastCheckStatus types.JSONText `json:"last_check_statuses" db:"last_check_status"`
|
LastCheckStatus types.JSONText `json:"last_check_statuses" db:"last_check_status"`
|
||||||
CorsCapable bool `json:"cors" db:"cors_capable"`
|
CORSCapable bool `json:"cors" db:"cors_capable"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *MoneroRepo) Node(id int) (MoneroNode, error) {
|
func (repo *MoneroRepo) Node(id int) (Node, error) {
|
||||||
node := MoneroNode{}
|
var node Node
|
||||||
err := repo.db.Get(&node, `SELECT * FROM tbl_node WHERE id = ?`, id)
|
err := repo.db.Get(&node, `SELECT * FROM tbl_node WHERE id = ?`, id)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
fmt.Println("WARN:", err)
|
fmt.Println("WARN:", err)
|
||||||
|
@ -78,26 +79,26 @@ func (repo *MoneroRepo) Node(id int) (MoneroNode, error) {
|
||||||
return node, err
|
return node, err
|
||||||
}
|
}
|
||||||
|
|
||||||
type MoneroNodes struct {
|
type Nodes struct {
|
||||||
TotalRows int `json:"total_rows"`
|
TotalRows int `json:"total_rows"`
|
||||||
RowsPerPage int `json:"rows_per_page"`
|
RowsPerPage int `json:"rows_per_page"`
|
||||||
Items []*MoneroNode `json:"items"`
|
Items []*Node `json:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MoneroQueryParams struct {
|
type MoneroQueryParams struct {
|
||||||
Host string
|
Host string
|
||||||
NetType string
|
Nettype string
|
||||||
Protocol string
|
Protocol string
|
||||||
CC string // 2 letter country code
|
CC string // 2 letter country code
|
||||||
Status int
|
Status int
|
||||||
Cors int
|
CORS int
|
||||||
RowsPerPage int
|
RowsPerPage int
|
||||||
Page int
|
Page int
|
||||||
SortBy string
|
SortBy string
|
||||||
SortDirection string
|
SortDirection string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *MoneroRepo) Nodes(q MoneroQueryParams) (MoneroNodes, error) {
|
func (repo *MoneroRepo) Nodes(q MoneroQueryParams) (Nodes, error) {
|
||||||
queryParams := []interface{}{}
|
queryParams := []interface{}{}
|
||||||
whereQueries := []string{}
|
whereQueries := []string{}
|
||||||
where := ""
|
where := ""
|
||||||
|
@ -107,17 +108,17 @@ func (repo *MoneroRepo) Nodes(q MoneroQueryParams) (MoneroNodes, error) {
|
||||||
queryParams = append(queryParams, "%"+q.Host+"%")
|
queryParams = append(queryParams, "%"+q.Host+"%")
|
||||||
queryParams = append(queryParams, "%"+q.Host+"%")
|
queryParams = append(queryParams, "%"+q.Host+"%")
|
||||||
}
|
}
|
||||||
if q.NetType != "any" {
|
if q.Nettype != "any" {
|
||||||
if q.NetType != "mainnet" && q.NetType != "stagenet" && q.NetType != "testnet" {
|
if q.Nettype != "mainnet" && q.Nettype != "stagenet" && q.Nettype != "testnet" {
|
||||||
return MoneroNodes{}, errors.New("Invalid nettype, must be one of 'mainnet', 'stagenet', 'testnet' or 'any'")
|
return Nodes{}, errors.New("Invalid nettype, must be one of 'mainnet', 'stagenet', 'testnet' or 'any'")
|
||||||
}
|
}
|
||||||
whereQueries = append(whereQueries, "nettype = ?")
|
whereQueries = append(whereQueries, "nettype = ?")
|
||||||
queryParams = append(queryParams, q.NetType)
|
queryParams = append(queryParams, q.Nettype)
|
||||||
}
|
}
|
||||||
if q.Protocol != "any" {
|
if q.Protocol != "any" {
|
||||||
allowedProtocols := []string{"tor", "http", "https"}
|
allowedProtocols := []string{"tor", "http", "https"}
|
||||||
if !slices.Contains(allowedProtocols, q.Protocol) {
|
if !slices.Contains(allowedProtocols, q.Protocol) {
|
||||||
return MoneroNodes{}, errors.New("Invalid protocol, must be one of '" + strings.Join(allowedProtocols, "', '") + "' or 'any'")
|
return Nodes{}, errors.New("Invalid protocol, must be one of '" + strings.Join(allowedProtocols, "', '") + "' or 'any'")
|
||||||
}
|
}
|
||||||
if q.Protocol == "tor" {
|
if q.Protocol == "tor" {
|
||||||
whereQueries = append(whereQueries, "is_tor = ?")
|
whereQueries = append(whereQueries, "is_tor = ?")
|
||||||
|
@ -140,7 +141,7 @@ func (repo *MoneroRepo) Nodes(q MoneroQueryParams) (MoneroNodes, error) {
|
||||||
whereQueries = append(whereQueries, "is_available = ?")
|
whereQueries = append(whereQueries, "is_available = ?")
|
||||||
queryParams = append(queryParams, q.Status)
|
queryParams = append(queryParams, q.Status)
|
||||||
}
|
}
|
||||||
if q.Cors != -1 {
|
if q.CORS != -1 {
|
||||||
whereQueries = append(whereQueries, "cors_capable = ?")
|
whereQueries = append(whereQueries, "cors_capable = ?")
|
||||||
queryParams = append(queryParams, 1)
|
queryParams = append(queryParams, 1)
|
||||||
}
|
}
|
||||||
|
@ -149,7 +150,7 @@ func (repo *MoneroRepo) Nodes(q MoneroQueryParams) (MoneroNodes, error) {
|
||||||
where = "WHERE " + strings.Join(whereQueries, " AND ")
|
where = "WHERE " + strings.Join(whereQueries, " AND ")
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes := MoneroNodes{}
|
nodes := Nodes{}
|
||||||
|
|
||||||
queryTotalRows := fmt.Sprintf(`
|
queryTotalRows := fmt.Sprintf(`
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -220,15 +221,15 @@ func (repo *MoneroRepo) Nodes(q MoneroQueryParams) (MoneroNodes, error) {
|
||||||
nodes.RowsPerPage = q.RowsPerPage
|
nodes.RowsPerPage = q.RowsPerPage
|
||||||
|
|
||||||
for row.Next() {
|
for row.Next() {
|
||||||
node := MoneroNode{}
|
var node Node
|
||||||
err = row.Scan(
|
err = row.Scan(
|
||||||
&node.Id,
|
&node.ID,
|
||||||
&node.Protocol,
|
&node.Protocol,
|
||||||
&node.Hostname,
|
&node.Hostname,
|
||||||
&node.Port,
|
&node.Port,
|
||||||
&node.IsTor,
|
&node.IsTor,
|
||||||
&node.IsAvailable,
|
&node.IsAvailable,
|
||||||
&node.NetType,
|
&node.Nettype,
|
||||||
&node.Height,
|
&node.Height,
|
||||||
&node.AdjustedTime,
|
&node.AdjustedTime,
|
||||||
&node.DatabaseSize,
|
&node.DatabaseSize,
|
||||||
|
@ -236,18 +237,18 @@ func (repo *MoneroRepo) Nodes(q MoneroQueryParams) (MoneroNodes, error) {
|
||||||
&node.Version,
|
&node.Version,
|
||||||
&node.Uptime,
|
&node.Uptime,
|
||||||
&node.EstimateFee,
|
&node.EstimateFee,
|
||||||
&node.Ip,
|
&node.IP,
|
||||||
&node.Asn,
|
&node.ASN,
|
||||||
&node.AsnName,
|
&node.ASNName,
|
||||||
&node.CountryCode,
|
&node.CountryCode,
|
||||||
&node.CountryName,
|
&node.CountryName,
|
||||||
&node.City,
|
&node.City,
|
||||||
&node.Lat,
|
&node.Latitude,
|
||||||
&node.Lon,
|
&node.Longitude,
|
||||||
&node.DateEntered,
|
&node.DateEntered,
|
||||||
&node.LastChecked,
|
&node.LastChecked,
|
||||||
&node.LastCheckStatus,
|
&node.LastCheckStatus,
|
||||||
&node.CorsCapable)
|
&node.CORSCapable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nodes, err
|
return nodes, err
|
||||||
}
|
}
|
||||||
|
@ -258,8 +259,8 @@ func (repo *MoneroRepo) Nodes(q MoneroQueryParams) (MoneroNodes, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type MoneroLogQueryParams struct {
|
type MoneroLogQueryParams struct {
|
||||||
NodeId int // 0 fpr all, >0 for specific node
|
NodeID int // 0 fpr all, >0 for specific node
|
||||||
WorkerId int // 0 for all, >0 for specific worker
|
WorkerID int // 0 for all, >0 for specific worker
|
||||||
Status int // -1 for all, 0 for failed, 1 for success
|
Status int // -1 for all, 0 for failed, 1 for success
|
||||||
FailedReason string // empty for all, if not empty, will be used as search from failed_reaso
|
FailedReason string // empty for all, if not empty, will be used as search from failed_reaso
|
||||||
|
|
||||||
|
@ -270,9 +271,9 @@ type MoneroLogQueryParams struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProbeLog struct {
|
type ProbeLog struct {
|
||||||
Id int `db:"id" json:"id,omitempty"`
|
ID int `db:"id" json:"id,omitempty"`
|
||||||
NodeId int `db:"node_id" json:"node_id"`
|
NodeID int `db:"node_id" json:"node_id"`
|
||||||
ProberId int `db:"prober_id" json:"prober_id"`
|
ProberID int `db:"prober_id" json:"prober_id"`
|
||||||
Status int `db:"is_available" json:"status"`
|
Status int `db:"is_available" json:"status"`
|
||||||
Height int `db:"height" json:"height"`
|
Height int `db:"height" json:"height"`
|
||||||
AdjustedTime int `db:"adjusted_time" json:"adjusted_time"`
|
AdjustedTime int `db:"adjusted_time" json:"adjusted_time"`
|
||||||
|
@ -295,9 +296,9 @@ func (repo *MoneroRepo) Logs(q MoneroLogQueryParams) (MoneroNodeFetchLogs, error
|
||||||
whereQueries := []string{}
|
whereQueries := []string{}
|
||||||
where := ""
|
where := ""
|
||||||
|
|
||||||
if q.NodeId != 0 {
|
if q.NodeID != 0 {
|
||||||
whereQueries = append(whereQueries, "node_id = ?")
|
whereQueries = append(whereQueries, "node_id = ?")
|
||||||
queryParams = append(queryParams, q.NodeId)
|
queryParams = append(queryParams, q.NodeID)
|
||||||
}
|
}
|
||||||
if q.Status != -1 {
|
if q.Status != -1 {
|
||||||
whereQueries = append(whereQueries, "is_available = ?")
|
whereQueries = append(whereQueries, "is_available = ?")
|
||||||
|
@ -365,9 +366,9 @@ func (repo *MoneroRepo) Logs(q MoneroLogQueryParams) (MoneroNodeFetchLogs, error
|
||||||
for row.Next() {
|
for row.Next() {
|
||||||
probeLog := ProbeLog{}
|
probeLog := ProbeLog{}
|
||||||
err = row.Scan(
|
err = row.Scan(
|
||||||
&probeLog.Id,
|
&probeLog.ID,
|
||||||
&probeLog.NodeId,
|
&probeLog.NodeID,
|
||||||
&probeLog.ProberId,
|
&probeLog.ProberID,
|
||||||
&probeLog.Status,
|
&probeLog.Status,
|
||||||
&probeLog.Height,
|
&probeLog.Height,
|
||||||
&probeLog.AdjustedTime,
|
&probeLog.AdjustedTime,
|
||||||
|
@ -496,7 +497,7 @@ func (repo *MoneroRepo) Delete(id uint) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *MoneroRepo) GiveJob(acceptTor int) (MoneroNode, error) {
|
func (repo *MoneroRepo) GiveJob(acceptTor int) (Node, error) {
|
||||||
queryParams := []interface{}{}
|
queryParams := []interface{}{}
|
||||||
whereQueries := []string{}
|
whereQueries := []string{}
|
||||||
where := ""
|
where := ""
|
||||||
|
@ -510,7 +511,7 @@ func (repo *MoneroRepo) GiveJob(acceptTor int) (MoneroNode, error) {
|
||||||
where = "WHERE " + strings.Join(whereQueries, " AND ")
|
where = "WHERE " + strings.Join(whereQueries, " AND ")
|
||||||
}
|
}
|
||||||
|
|
||||||
node := MoneroNode{}
|
var node Node
|
||||||
|
|
||||||
query := fmt.Sprintf(`
|
query := fmt.Sprintf(`
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -527,7 +528,7 @@ func (repo *MoneroRepo) GiveJob(acceptTor int) (MoneroNode, error) {
|
||||||
last_checked ASC
|
last_checked ASC
|
||||||
LIMIT 1`, where)
|
LIMIT 1`, where)
|
||||||
err := repo.db.QueryRow(query, queryParams...).Scan(
|
err := repo.db.QueryRow(query, queryParams...).Scan(
|
||||||
&node.Id,
|
&node.ID,
|
||||||
&node.Hostname,
|
&node.Hostname,
|
||||||
&node.Port,
|
&node.Port,
|
||||||
&node.Protocol,
|
&node.Protocol,
|
||||||
|
@ -540,7 +541,7 @@ func (repo *MoneroRepo) GiveJob(acceptTor int) (MoneroNode, error) {
|
||||||
_, err = repo.db.Exec(`
|
_, err = repo.db.Exec(`
|
||||||
UPDATE tbl_node
|
UPDATE tbl_node
|
||||||
SET last_checked = ?
|
SET last_checked = ?
|
||||||
WHERE id = ?`, time.Now().Unix(), node.Id)
|
WHERE id = ?`, time.Now().Unix(), node.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return node, err
|
return node, err
|
||||||
}
|
}
|
||||||
|
@ -549,13 +550,13 @@ func (repo *MoneroRepo) GiveJob(acceptTor int) (MoneroNode, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProbeReport struct {
|
type ProbeReport struct {
|
||||||
TookTime float64 `json:"took_time"`
|
TookTime float64 `json:"took_time"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
NodeInfo MoneroNode `json:"node_info"`
|
NodeInfo Node `json:"node_info"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *MoneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
func (repo *MoneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
if report.NodeInfo.Id == 0 {
|
if report.NodeInfo.ID == 0 {
|
||||||
return errors.New("Invalid node")
|
return errors.New("Invalid node")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,7 +587,7 @@ func (repo *MoneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
?
|
?
|
||||||
)`
|
)`
|
||||||
_, err := repo.db.Exec(qInsertLog,
|
_, err := repo.db.Exec(qInsertLog,
|
||||||
report.NodeInfo.Id,
|
report.NodeInfo.ID,
|
||||||
proberId,
|
proberId,
|
||||||
report.NodeInfo.IsAvailable,
|
report.NodeInfo.IsAvailable,
|
||||||
report.NodeInfo.Height,
|
report.NodeInfo.Height,
|
||||||
|
@ -620,7 +621,7 @@ func (repo *MoneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
WHERE
|
WHERE
|
||||||
node_id = ?
|
node_id = ?
|
||||||
AND date_checked > ?`
|
AND date_checked > ?`
|
||||||
repo.db.Get(&nodeStats, qstats, report.NodeInfo.Id, limitTs)
|
repo.db.Get(&nodeStats, qstats, report.NodeInfo.ID, limitTs)
|
||||||
|
|
||||||
avgUptime := (float64(nodeStats.OnlineCount) / float64(nodeStats.TotalFetched)) * 100
|
avgUptime := (float64(nodeStats.OnlineCount) / float64(nodeStats.TotalFetched)) * 100
|
||||||
report.NodeInfo.Uptime = math.Ceil(avgUptime*100) / 100
|
report.NodeInfo.Uptime = math.Ceil(avgUptime*100) / 100
|
||||||
|
@ -645,17 +646,17 @@ func (repo *MoneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// recheck IP
|
// recheck IP
|
||||||
if report.NodeInfo.Ip != "" {
|
if report.NodeInfo.IP != "" {
|
||||||
if ipInfo, errGeoIp := GetGeoIpInfo(report.NodeInfo.Ip); errGeoIp != nil {
|
if ipInfo, errGeoIp := geo.IpInfo(report.NodeInfo.IP); errGeoIp != nil {
|
||||||
fmt.Println("WARN:", errGeoIp.Error())
|
fmt.Println("WARN:", errGeoIp.Error())
|
||||||
} else {
|
} else {
|
||||||
report.NodeInfo.Asn = ipInfo.Asn
|
report.NodeInfo.ASN = ipInfo.Asn
|
||||||
report.NodeInfo.AsnName = ipInfo.AsnOrg
|
report.NodeInfo.ASNName = ipInfo.AsnOrg
|
||||||
report.NodeInfo.CountryCode = ipInfo.CountryCode
|
report.NodeInfo.CountryCode = ipInfo.CountryCode
|
||||||
report.NodeInfo.CountryName = ipInfo.CountryName
|
report.NodeInfo.CountryName = ipInfo.CountryName
|
||||||
report.NodeInfo.City = ipInfo.City
|
report.NodeInfo.City = ipInfo.City
|
||||||
report.NodeInfo.Lon = ipInfo.Longitude
|
report.NodeInfo.Longitude = ipInfo.Longitude
|
||||||
report.NodeInfo.Lat = ipInfo.Latitude
|
report.NodeInfo.Latitude = ipInfo.Latitude
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,7 +686,7 @@ func (repo *MoneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
id = ?`
|
id = ?`
|
||||||
_, err = repo.db.Exec(update,
|
_, err = repo.db.Exec(update,
|
||||||
nodeAvailable,
|
nodeAvailable,
|
||||||
report.NodeInfo.NetType,
|
report.NodeInfo.Nettype,
|
||||||
report.NodeInfo.Height,
|
report.NodeInfo.Height,
|
||||||
report.NodeInfo.AdjustedTime,
|
report.NodeInfo.AdjustedTime,
|
||||||
report.NodeInfo.DatabaseSize,
|
report.NodeInfo.DatabaseSize,
|
||||||
|
@ -693,16 +694,16 @@ func (repo *MoneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
report.NodeInfo.Version,
|
report.NodeInfo.Version,
|
||||||
report.NodeInfo.Uptime,
|
report.NodeInfo.Uptime,
|
||||||
report.NodeInfo.EstimateFee,
|
report.NodeInfo.EstimateFee,
|
||||||
report.NodeInfo.Ip,
|
report.NodeInfo.IP,
|
||||||
report.NodeInfo.Asn,
|
report.NodeInfo.ASN,
|
||||||
report.NodeInfo.AsnName,
|
report.NodeInfo.ASNName,
|
||||||
report.NodeInfo.CountryCode,
|
report.NodeInfo.CountryCode,
|
||||||
report.NodeInfo.CountryName,
|
report.NodeInfo.CountryName,
|
||||||
report.NodeInfo.City,
|
report.NodeInfo.City,
|
||||||
now.Unix(),
|
now.Unix(),
|
||||||
string(statuesValueToDb),
|
string(statuesValueToDb),
|
||||||
report.NodeInfo.CorsCapable,
|
report.NodeInfo.CORSCapable,
|
||||||
report.NodeInfo.Id)
|
report.NodeInfo.ID)
|
||||||
} else {
|
} else {
|
||||||
update := `
|
update := `
|
||||||
UPDATE tbl_node
|
UPDATE tbl_node
|
||||||
|
@ -713,12 +714,12 @@ func (repo *MoneroRepo) ProcessJob(report ProbeReport, proberId int64) error {
|
||||||
last_check_status = ?
|
last_check_status = ?
|
||||||
WHERE
|
WHERE
|
||||||
id = ?`
|
id = ?`
|
||||||
_, err = repo.db.Exec(update, nodeAvailable, report.NodeInfo.Uptime, now.Unix(), string(statuesValueToDb), report.NodeInfo.Id)
|
_, err = repo.db.Exec(update, nodeAvailable, report.NodeInfo.Uptime, now.Unix(), string(statuesValueToDb), report.NodeInfo.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if avgUptime <= 0 && nodeStats.TotalFetched > 300 {
|
if avgUptime <= 0 && nodeStats.TotalFetched > 300 {
|
||||||
fmt.Println("Deleting Monero node (0% uptime from > 300 records)")
|
fmt.Println("Deleting Monero node (0% uptime from > 300 records)")
|
||||||
repo.Delete(report.NodeInfo.Id)
|
repo.Delete(report.NodeInfo.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.db.Exec(`
|
repo.db.Exec(`
|
||||||
|
@ -765,14 +766,14 @@ func (repo *MoneroRepo) NetFee() []NetFee {
|
||||||
return netFees
|
return netFees
|
||||||
}
|
}
|
||||||
|
|
||||||
type MoneroCountries struct {
|
type Countries struct {
|
||||||
TotalNodes int `json:"total_nodes" db:"total_nodes"`
|
TotalNodes int `json:"total_nodes" db:"total_nodes"`
|
||||||
Cc string `json:"cc" db:"country"`
|
CC string `json:"cc" db:"country"` // country code
|
||||||
Name string `json:"name" db:"country_name"`
|
Name string `json:"name" db:"country_name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *MoneroRepo) Countries() ([]MoneroCountries, error) {
|
func (repo *MoneroRepo) Countries() ([]Countries, error) {
|
||||||
countries := []MoneroCountries{}
|
countries := []Countries{}
|
||||||
err := repo.db.Select(&countries, `
|
err := repo.db.Select(&countries, `
|
||||||
SELECT
|
SELECT
|
||||||
COUNT(id) AS total_nodes,
|
COUNT(id) AS total_nodes,
|
|
@ -1,4 +1,4 @@
|
||||||
package repo
|
package monero
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
Loading…
Reference in a new issue