mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
87 lines
1.8 KiB
Go
87 lines
1.8 KiB
Go
package bor
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"path"
|
|
"time"
|
|
|
|
"github.com/maticnetwork/bor/log"
|
|
)
|
|
|
|
// ResponseWithHeight defines a response object type that wraps an original
|
|
// response with a height.
|
|
type ResponseWithHeight struct {
|
|
Height string `json:"height"`
|
|
Result json.RawMessage `json:"result"`
|
|
}
|
|
|
|
// internal fetch method
|
|
func internalFetch(client http.Client, u *url.URL) (*ResponseWithHeight, error) {
|
|
res, err := client.Get(u.String())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
// check status code
|
|
if res.StatusCode != 200 {
|
|
return nil, fmt.Errorf("Error while fetching data from Heimdall")
|
|
}
|
|
|
|
// get response
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// unmarshall data from buffer
|
|
var response ResponseWithHeight
|
|
if err := json.Unmarshal(body, &response); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &response, nil
|
|
}
|
|
|
|
// FetchFromHeimdallWithRetry returns data from heimdall with retry
|
|
func FetchFromHeimdallWithRetry(client http.Client, urlString string, paths ...string) (*ResponseWithHeight, error) {
|
|
u, err := url.Parse(urlString)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, e := range paths {
|
|
if e != "" {
|
|
u.Path = path.Join(u.Path, e)
|
|
}
|
|
}
|
|
|
|
for {
|
|
res, err := internalFetch(client, u)
|
|
if err == nil && res != nil {
|
|
return res, nil
|
|
}
|
|
log.Info("Retrying again in 5 seconds for next Heimdall span", u.Path)
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
}
|
|
|
|
// FetchFromHeimdall returns data from heimdall
|
|
func FetchFromHeimdall(client http.Client, urlString string, paths ...string) (*ResponseWithHeight, error) {
|
|
u, err := url.Parse(urlString)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, e := range paths {
|
|
if e != "" {
|
|
u.Path = path.Join(u.Path, e)
|
|
}
|
|
}
|
|
|
|
return internalFetch(client, u)
|
|
}
|