Skip to content

Commit

Permalink
Merge branch 'andrius/value-provider-config' into 'main'
Browse files Browse the repository at this point in the history
Make full value provider url configurable instead of hardcoding endpoint + some cleanup.

See merge request flarenetwork/fast-updates!26
  • Loading branch information
tilenflare committed Jun 7, 2024
2 parents bc029ed + 0ea6769 commit f1a7ac2
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 137 deletions.
1 change: 0 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ test-go-client:
before_script:
- cd go-client
script:
- go test -v provider/random_provider_test.go
- go test -v provider/feed_provider_test.go
- go test -v sortition/sortition_test.go

Expand Down
7 changes: 3 additions & 4 deletions go-client/client/client_requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,7 @@ func (client *FastUpdatesClient) SubmitUpdates(updateProof *sortition.UpdateProo
client.transactionQueue.InputChan <- compReq
}

func (client *FastUpdatesClient) getOnlineOfflineValues() ([]int, []float64, []float64, error) {
// 0 value indicates unsupported feed. TODO: need to differentiate between 0 and absent value better.
func (client *FastUpdatesClient) getOnlineOfflineValues() ([]int, []float64, []float64, error) {
providerRawValues, err := client.valuesProvider.GetValues(client.allFeeds)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "error getting feed values")
Expand All @@ -202,9 +201,9 @@ func (client *FastUpdatesClient) getOnlineOfflineValues() ([]int, []float64, []f
supportedFeedIndexes := []int{}
providerValues := []float64{}
for i, value := range providerRawValues {
if value != 0 {
if value != nil {
supportedFeedIndexes = append(supportedFeedIndexes, i)
providerValues = append(providerValues, float64(value))
providerValues = append(providerValues, *value)
}
}

Expand Down
2 changes: 1 addition & 1 deletion go-client/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ flare_system_manager = "0x85680Dd93755Fe5d0789773fd0896cEE51F9e358"
incentive_manager_address = "0xc1a22A1d295e829Caf3be61bd1E11E5eEd7f0F15"
submission_window = 10
max_weight = 512
value_provider_base_url = "http://localhost:3101"
value_provider_url = "http://127.0.0.1:3101/feed-values/0"

[transactions]
accounts = [
Expand Down
14 changes: 7 additions & 7 deletions go-client/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ type Config struct {
}

type LoggerConfig struct {
Level string `toml:"level"` // valid values are: DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL (zap)
File string `toml:"file"`
MaxFileSize int `toml:"max_file_size"` // In megabytes
Console bool `toml:"console"`
MinBalance float64 `toml:"min_balance"`
FeedValuesLog int `toml:"feed_values_log"`
Level string `toml:"level"` // valid values are: DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL (zap)
File string `toml:"file"`
MaxFileSize int `toml:"max_file_size"` // In megabytes
Console bool `toml:"console"`
MinBalance float64 `toml:"min_balance"`
FeedValuesLog int `toml:"feed_values_log"`
}

type ChainConfig struct {
Expand All @@ -57,7 +57,7 @@ type FastUpdateClientConfig struct {
SortitionPrivateKey string `toml:"sortition_private_key" envconfig:"SORTITION_PRIVATE_KEY"`
SubmissionWindow int `toml:"submission_window"`
MaxWeight int `toml:"max_weight"`
ValueProviderUrl string `toml:"value_provider_base_url"`
ValueProviderUrl string `toml:"value_provider_url"`
}

type TransactionsConfig struct {
Expand Down
23 changes: 11 additions & 12 deletions go-client/provider/feed_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ type ValuesDecimals struct {
Timestamp uint64
}

// Values provider is an interface needed to provide current off-chain values.
// ValuesProvider is an interface needed to provide current off-chain values.
type ValuesProvider interface {
GetValues(feeds []FeedId) ([]float64, error)
GetValues(feeds []FeedId) ([]*float64, error)
}

// GetDeltas calculates the deltas between the provider values and the chain values for each feed.
Expand All @@ -40,7 +40,7 @@ func GetDeltas(chainValues []float64, providerValues []float64, valueIndexToFeed

for i := 0; i < len(chainValues); i++ {
delta := byte('0')
diff := math.Abs((providerValues[i] - chainValues[i])) / chainValues[i]
diff := math.Abs(providerValues[i]-chainValues[i]) / chainValues[i]

if diff > scaleDiff {
if providerValues[i] > chainValues[i] {
Expand All @@ -63,16 +63,16 @@ func GetDeltas(chainValues []float64, providerValues []float64, valueIndexToFeed
}

deltasString := string(deltasList)
deltas, err := StringToDeltas(deltasString)
deltas := StringToDeltas(deltasString)

return deltas, deltasString, err
return deltas, deltasString, nil
}

// StringToDeltas converts a string representation of updates into a byte slice of deltas.
// Each character in the input string represents a delta value, where '+' represents an increment of 1
// and '-' represents an increment of 3. The deltas are packed into a byte slice, with each byte
// containing 4 delta values.
func StringToDeltas(update string) ([]byte, error) {
func StringToDeltas(update string) []byte {
deltas := make([]byte, 0)
k := 0
var delta byte
Expand All @@ -95,20 +95,19 @@ func StringToDeltas(update string) ([]byte, error) {
deltas = append(deltas, delta)
}

return deltas, nil
return deltas
}

// Sorts values according to feeds order.
func sortFeedValues(feeds []FeedId, feedValues []FeedValue) ([]float64, error) {
var values []float64
func sortFeedValues(feeds []FeedId, feedValues []FeedValue) []*float64 {
var values []*float64
for _, feed := range feeds {
for _, v := range feedValues {
if v.Feed == feed {
value := v.Value
values = append(values, value)
values = append(values, v.Value)
break
}
}
}
return values, nil
return values
}
6 changes: 1 addition & 5 deletions go-client/provider/feed_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import (
func TestStringToDeltas(t *testing.T) {
update := "+-0+"
expected := []byte{113}
result, err := provider.StringToDeltas(update)

if err != nil {
t.Errorf("Unexpected error: %v", err)
}
result := provider.StringToDeltas(update)

if len(result) != len(expected) {
t.Errorf("Expected length of result to be %d, but got %d", len(expected), len(result))
Expand Down
111 changes: 53 additions & 58 deletions go-client/provider/http_feed_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,104 +5,99 @@ import (
"encoding/json"
"fast-updates-client/logger"
"fmt"
"github.com/pkg/errors"
"io"
"net/http"
)

type FeedValue struct {
Feed FeedId `json:"feed"`
Value float64 `json:"value"`
}

type HttpValuesProvider struct {
baseUrl string
httpClient *http.Client
}

func (p *HttpValuesProvider) GetValues(feeds []FeedId) ([]float64, error) {
feedValues, err := p.GetFeedValues(feeds)
if err != nil {
return nil, err
}
values, err := sortFeedValues(feeds, feedValues)
if err != nil {
return nil, err
}

return values, err
type FeedId struct {
Category byte `json:"category"`
Name string `json:"name"`
}

func NewHttpValueProvider(baseUrl string) *HttpValuesProvider {
logger.Info("Creating new feed values provider")

return &HttpValuesProvider{
baseUrl: baseUrl,
httpClient: http.DefaultClient,
}
type FeedValue struct {
Feed FeedId `json:"feed"`
Value *float64 `json:"value"`
}

// Define the struct for the payload
type FeedValuesRequest struct {
Feeds []FeedId `json:"feeds"`
}

type FeedId struct {
Category byte `json:"category"`
Name string `json:"name"`
}

type FeedValuesResponse struct {
VotingRoundId int `json:"votingRoundId"`
Data []FeedValue `json:"data"`
}

func (c *HttpValuesProvider) post(endpoint string, requestBody []byte) ([]byte, error) {
req, err := http.NewRequest("POST", c.baseUrl+endpoint, bytes.NewBuffer(requestBody))
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36")
req.Header.Set("accept", "application/json")
req.Header.Set("Content-Type", "application/json")
type HttpValuesProvider struct {
Url string
httpClient *http.Client
}

resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
func NewHttpValueProvider(url string) *HttpValuesProvider {
logger.Info("Creating new feed values provider")

if resp.StatusCode != 201 {
return nil, fmt.Errorf("%s (Code: %d)", resp.Status, resp.StatusCode)
return &HttpValuesProvider{
Url: url,
httpClient: http.DefaultClient,
}
}

responseBody, err := io.ReadAll(resp.Body)
func (p *HttpValuesProvider) GetValues(feeds []FeedId) ([]*float64, error) {
feedValues, err := p.GetFeedValues(feeds)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "error getting feed values")
}
return responseBody, nil
values := sortFeedValues(feeds, feedValues)

return values, err
}

func (c *HttpValuesProvider) GetFeedValues(feeds []FeedId) ([]FeedValue, error) {
func (p *HttpValuesProvider) GetFeedValues(feeds []FeedId) ([]FeedValue, error) {
req, err := json.Marshal(
FeedValuesRequest{
Feeds: feeds,
},
)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "error marshalling request")
}

// TODO: Should we specify voting round id instead of 0?
body, err := c.post("/feed-values/0", req)
body, err := p.post(req)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "error posting feed value request")
}

res := FeedValuesResponse{}
err = json.Unmarshal(body, &res)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "error unmarshalling response")
}

return res.Data, nil
}

func (p *HttpValuesProvider) post(requestBody []byte) ([]byte, error) {
req, err := http.NewRequest("POST", p.Url, bytes.NewBuffer(requestBody))
if err != nil {
return nil, errors.Wrap(err, "error creating request")
}
req.Header.Set("accept", "application/json")
req.Header.Set("Content-Type", "application/json")

resp, err := p.httpClient.Do(req)
if err != nil {
return nil, errors.Wrap(err, "error sending HTTP request")
}
defer resp.Body.Close()

if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("response status %s (Code: %d)", resp.Status, resp.StatusCode)
}

responseBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "error reading response body")
}
return responseBody, nil
}
2 changes: 1 addition & 1 deletion go-client/provider/http_feed_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestGetProviderFeeds(t *testing.T) {
{Category: 1, Name: "BOL/USD"},
}
// TODO: Mock endpoint and fix test
feedProvider := provider.NewHttpValueProvider("http://localhost:3101/")
feedProvider := provider.NewHttpValueProvider("http://localhost:3101/feed-values/0")

feeds, err := feedProvider.GetValues(feedsIds)
if err != nil {
Expand Down
21 changes: 0 additions & 21 deletions go-client/provider/random_provider.go

This file was deleted.

22 changes: 0 additions & 22 deletions go-client/provider/random_provider_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion go-client/tests/configs/config1.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ flare_system_manager = "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF"
incentive_manager_address = "0x78Aeff0658Fa67735fBF99Ce7CDB01Fe5D520259"
submission_window = 8
max_weight = 256
value_provider_base_url = "http://host.docker.internal:3101"
value_provider_url = "http://host.docker.internal:3101/feed-values/0"

[transactions]
accounts = [
Expand Down
2 changes: 1 addition & 1 deletion go-client/tests/configs/config2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ flare_system_manager = "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF"
incentive_manager_address = "0x78Aeff0658Fa67735fBF99Ce7CDB01Fe5D520259"
submission_window = 8
max_weight = 256
value_provider_base_url = "http://host.docker.internal:3101"
value_provider_url = "http://host.docker.internal:3101/feed-values/0"

[transactions]
accounts = [
Expand Down
2 changes: 1 addition & 1 deletion go-client/tests/configs/config3.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ flare_system_manager = "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF"
incentive_manager_address = "0x78Aeff0658Fa67735fBF99Ce7CDB01Fe5D520259"
submission_window = 8
max_weight = 256
value_provider_base_url = "http://host.docker.internal:3101"
value_provider_url = "http://host.docker.internal:3101/feed-values/0"

[transactions]
accounts = [
Expand Down
2 changes: 1 addition & 1 deletion go-client/tests/configs/config_coston2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mock_address = "0x3b9a1E27c317DdD9c256dD5a49f7f2C67E603c06"
flare_system_manager = "0x3b9a1E27c317DdD9c256dD5a49f7f2C67E603c06"
submission_window = 8
max_weight = 512
value_provider_base_url = "http://host.docker.internal:3101"
value_provider_url = "http://host.docker.internal:3101/feed-values/0"

[transactions]
accounts = [
Expand Down
Loading

0 comments on commit f1a7ac2

Please sign in to comment.