observer-bot/api.go

153 lines
3.3 KiB
Go

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
}