package main import ( "encoding/json" "fmt" "git.gammaspectra.live/P2Pool/consensus/v3/utils" "git.gammaspectra.live/P2Pool/observer-cmd-utils/index" cmdutils "git.gammaspectra.live/P2Pool/observer-cmd-utils/utils" "io" "net/http" "net/url" "slices" "strconv" "time" ) func getTypeFromAPI[T any](host, method string) *T { uri, _ := url.Parse(host + method) if response, err := http.DefaultClient.Do(&http.Request{ Method: "GET", URL: uri, }); err != nil { return nil } else { defer response.Body.Close() if response.StatusCode == http.StatusOK { var result T if data, err := io.ReadAll(response.Body); err != nil { return nil } else if utils.UnmarshalJSON(data, &result) != nil { return nil } else { return &result } } else { return nil } } } func getSideBlocksFromAPI(host, method string) []*index.SideBlock { return getSliceFromAPI[*index.SideBlock](host, method) } func getSliceFromAPI[T any](host, method string) []T { uri, _ := url.Parse(host + method) if response, err := http.DefaultClient.Do(&http.Request{ Method: "GET", URL: uri, }); err != nil { return nil } else { defer response.Body.Close() if response.StatusCode == http.StatusOK { var result []T if data, err := io.ReadAll(response.Body); err != nil { return nil } else if utils.UnmarshalJSON(data, &result) != nil { return nil } else { return result } } else { return nil } } } func toFloat64(t any) float64 { if x, ok := t.(json.Number); ok { if n, err := x.Float64(); err == nil { return n } } if x, ok := t.(float64); ok { return x } else if x, ok := t.(float32); ok { return float64(x) } else if x, ok := t.(uint64); ok { return float64(x) } else if x, ok := t.(int64); ok { return float64(x) } else if x, ok := t.(uint); ok { return float64(x) } else if x, ok := t.(int); ok { return float64(x) } else if x, ok := t.(string); ok { if n, err := strconv.ParseFloat(x, 0); err == nil { return n } } return 0 } func toUint64(t any) uint64 { if x, ok := t.(json.Number); ok { if n, err := x.Int64(); err == nil { return uint64(n) } } if x, ok := t.(uint64); ok { return x } else if x, ok := t.(int64); ok { return uint64(x) } else if x, ok := t.(uint); ok { return uint64(x) } else if x, ok := t.(int); ok { return uint64(x) } else if x, ok := t.(uint32); ok { return uint64(x) } else if x, ok := t.(int32); ok { return uint64(x) } else if x, ok := t.(float64); ok { return uint64(x) } else if x, ok := t.(float32); ok { return uint64(x) } else if x, ok := t.(string); ok { if n, err := strconv.ParseUint(x, 10, 0); err == nil { return n } } return 0 } func getPoolInfo(host string) *cmdutils.PoolInfoResult { for { d := getTypeFromAPI[cmdutils.PoolInfoResult](host, "/api/pool_info") if d == nil || d.SideChain.LastBlock == nil { time.Sleep(5) continue } return d } } func getPreviousBlocks(host string) (result foundBlocks) { result = getSliceFromAPI[*index.FoundBlock](host, fmt.Sprintf("/api/found_blocks?limit=%d", numberOfBlockHistoryToKeep)) //sort from oldest to newest slices.SortFunc(result, func(a, b *index.FoundBlock) int { if a.MainBlock.Height < b.MainBlock.Height { return -1 } else if a.MainBlock.Height > b.MainBlock.Height { return 1 } return 0 }) return result }