Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: add -pricePerGateway and deprecate -pricePerBroadcaster #3056

Merged
merged 8 commits into from
May 19, 2024
1 change: 1 addition & 0 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- [#3055](https://github.com/livepeer/go-livepeer/pull/3055) census: Rename broadcaster metrics to gateway metrics
- [#3053](https://github.com/livepeer/go-livepeer/pull/3053) cli: add `-gateway` flag and deprecate `-broadcaster` flag.
- [#3056](https://github.com/livepeer/go-livepeer/pull/3056) cli: add `-pricePerGateway` flag and deprecate `-pricePerBroadcaster` flag.

### Breaking Changes 🚨🚨

Expand Down
1 change: 1 addition & 0 deletions cmd/livepeer/livepeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ func parseLivepeerConfig() starter.LivepeerConfig {
cfg.PixelsPerUnit = flag.String("pixelsPerUnit", *cfg.PixelsPerUnit, "Amount of pixels per unit. Set to '> 1' to have smaller price granularity than 1 wei / pixel")
cfg.PriceFeedAddr = flag.String("priceFeedAddr", *cfg.PriceFeedAddr, "ETH address of the Chainlink price feed contract. Used for custom currencies conversion on -pricePerUnit or -maxPricePerUnit")
cfg.AutoAdjustPrice = flag.Bool("autoAdjustPrice", *cfg.AutoAdjustPrice, "Enable/disable automatic price adjustments based on the overhead for redeeming tickets")
cfg.PricePerGateway = flag.String("pricePerGateway", *cfg.PricePerGateway, `json list of price per gateway or path to json config file. Example: {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1000000000000},{"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":1000000000000}]}`)
cfg.PricePerBroadcaster = flag.String("pricePerBroadcaster", *cfg.PricePerBroadcaster, `json list of price per broadcaster or path to json config file. Example: {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1000000000000},{"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":1000000000000}]}`)
// Interval to poll for blocks
cfg.BlockPollingInterval = flag.Int("blockPollingInterval", *cfg.BlockPollingInterval, "Interval in seconds at which different blockchain event services poll for blocks")
Expand Down
50 changes: 35 additions & 15 deletions cmd/livepeer/starter/starter.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
PixelsPerUnit *string
PriceFeedAddr *string
AutoAdjustPrice *bool
PricePerGateway *string
PricePerBroadcaster *string
BlockPollingInterval *int
Redeemer *bool
Expand Down Expand Up @@ -204,6 +205,7 @@
defaultPixelsPerUnit := "1"
defaultPriceFeedAddr := "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612" // ETH / USD price feed address on Arbitrum Mainnet
defaultAutoAdjustPrice := true
defaultPricePerGateway := ""

Check warning on line 208 in cmd/livepeer/starter/starter.go

View check run for this annotation

Codecov / codecov/patch

cmd/livepeer/starter/starter.go#L208

Added line #L208 was not covered by tests
defaultPricePerBroadcaster := ""
defaultBlockPollingInterval := 5
defaultRedeemer := false
Expand Down Expand Up @@ -292,6 +294,7 @@
PixelsPerUnit: &defaultPixelsPerUnit,
PriceFeedAddr: &defaultPriceFeedAddr,
AutoAdjustPrice: &defaultAutoAdjustPrice,
PricePerGateway: &defaultPricePerGateway,

Check warning on line 297 in cmd/livepeer/starter/starter.go

View check run for this annotation

Codecov / codecov/patch

cmd/livepeer/starter/starter.go#L297

Added line #L297 was not covered by tests
PricePerBroadcaster: &defaultPricePerBroadcaster,
BlockPollingInterval: &defaultBlockPollingInterval,
Redeemer: &defaultRedeemer,
Expand Down Expand Up @@ -784,7 +787,11 @@
}
n.SetBasePrice("default", autoPrice)

broadcasterPrices := getBroadcasterPrices(*cfg.PricePerBroadcaster)
if *cfg.PricePerBroadcaster != "" {
glog.Warning("-PricePerBroadcaster flag is deprecated and will be removed in a future release. Please use -PricePerGateway instead")
cfg.PricePerGateway = cfg.PricePerBroadcaster

Check warning on line 792 in cmd/livepeer/starter/starter.go

View check run for this annotation

Codecov / codecov/patch

cmd/livepeer/starter/starter.go#L790-L792

Added lines #L790 - L792 were not covered by tests
}
broadcasterPrices := getGatewayPrices(*cfg.PricePerGateway)

Check warning on line 794 in cmd/livepeer/starter/starter.go

View check run for this annotation

Codecov / codecov/patch

cmd/livepeer/starter/starter.go#L794

Added line #L794 was not covered by tests
for _, p := range broadcasterPrices {
p := p
pricePerPixel := new(big.Rat).Quo(p.PricePerUnit, p.PixelsPerUnit)
Expand Down Expand Up @@ -1482,51 +1489,64 @@
return nil
}

type BroadcasterPrice struct {
type GatewayPrice struct {
EthAddress string
PricePerUnit *big.Rat
Currency string
PixelsPerUnit *big.Rat
}

func getBroadcasterPrices(broadcasterPrices string) []BroadcasterPrice {
if broadcasterPrices == "" {
func getGatewayPrices(gatewayPrices string) []GatewayPrice {
if gatewayPrices == "" {
return nil
}

// Format of broadcasterPrices json
// {"broadcasters":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1}, {"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":3}]}
// {"gateways":[{"ethaddress":"address1","priceperunit":0.5,"currency":"USD","pixelsperunit":1}, {"ethaddress":"address2","priceperunit":0.3,"currency":"USD","pixelsperunit":3}]}
var pricesSet struct {
Gateways []struct {
EthAddress string `json:"ethaddress"`
PixelsPerUnit json.RawMessage `json:"pixelsperunit"`
PricePerUnit json.RawMessage `json:"priceperunit"`
Currency string `json:"currency"`
} `json:"gateways"`
// TODO: Keep the old name for backwards compatibility, remove in the future
Broadcasters []struct {
EthAddress string `json:"ethaddress"`
// The fields below are specified as a number in the JSON, but we don't want to lose precision so we store the raw characters here and parse as a big.Rat.
// This also allows support for exponential notation for numbers, which is helpful for pricePerUnit which could be a value like 1e12.
EthAddress string `json:"ethaddress"`
PixelsPerUnit json.RawMessage `json:"pixelsperunit"`
PricePerUnit json.RawMessage `json:"priceperunit"`
Currency string `json:"currency"`
} `json:"broadcasters"`
}
pricesFileContent, _ := common.ReadFromFile(broadcasterPrices)
pricesFileContent, _ := common.ReadFromFile(gatewayPrices)

err := json.Unmarshal([]byte(pricesFileContent), &pricesSet)
if err != nil {
glog.Errorf("broadcaster prices could not be parsed: %s", err)
glog.Errorf("gateway prices could not be parsed: %s", err)

Check warning on line 1525 in cmd/livepeer/starter/starter.go

View check run for this annotation

Codecov / codecov/patch

cmd/livepeer/starter/starter.go#L1525

Added line #L1525 was not covered by tests
return nil
}

prices := make([]BroadcasterPrice, len(pricesSet.Broadcasters))
for i, p := range pricesSet.Broadcasters {
// Check if broadcasters field is used and display a warning
if len(pricesSet.Broadcasters) > 0 {
glog.Warning("The 'broadcaster' property in the 'pricePerGateway' config is deprecated and will be removed in a future release. Please use 'gateways' instead.")
}

// Combine broadcasters and gateways into a single slice
allGateways := append(pricesSet.Broadcasters, pricesSet.Gateways...)

prices := make([]GatewayPrice, len(allGateways))
for i, p := range allGateways {
pixelsPerUnit, ok := new(big.Rat).SetString(string(p.PixelsPerUnit))
if !ok {
glog.Errorf("Pixels per unit could not be parsed for broadcaster %v. must be a valid number, provided %s", p.EthAddress, p.PixelsPerUnit)
glog.Errorf("Pixels per unit could not be parsed for gateway %v. must be a valid number, provided %s", p.EthAddress, p.PixelsPerUnit)

Check warning on line 1541 in cmd/livepeer/starter/starter.go

View check run for this annotation

Codecov / codecov/patch

cmd/livepeer/starter/starter.go#L1541

Added line #L1541 was not covered by tests
continue
}
pricePerUnit, ok := new(big.Rat).SetString(string(p.PricePerUnit))
if !ok {
glog.Errorf("Price per unit could not be parsed for broadcaster %v. must be a valid number, provided %s", p.EthAddress, p.PricePerUnit)
glog.Errorf("Price per unit could not be parsed for gateway %v. must be a valid number, provided %s", p.EthAddress, p.PricePerUnit)

Check warning on line 1546 in cmd/livepeer/starter/starter.go

View check run for this annotation

Codecov / codecov/patch

cmd/livepeer/starter/starter.go#L1546

Added line #L1546 was not covered by tests
continue
}
prices[i] = BroadcasterPrice{
prices[i] = GatewayPrice{
EthAddress: p.EthAddress,
Currency: p.Currency,
PricePerUnit: pricePerUnit,
Expand Down
25 changes: 16 additions & 9 deletions cmd/livepeer/starter/starter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package starter

import (
"errors"
"fmt"
"math/big"
"os"
"path/filepath"
Expand Down Expand Up @@ -87,19 +88,25 @@ func TestIsLocalURL(t *testing.T) {
assert.False(isLocal)
}

func TestParseGetBroadcasterPrices(t *testing.T) {
func TestParseGetGatewayPrices(t *testing.T) {
assert := assert.New(t)

j := `{"broadcasters":[{"ethaddress":"0x0000000000000000000000000000000000000000","priceperunit":1000,"pixelsperunit":1}, {"ethaddress":"0x1000000000000000000000000000000000000000","priceperunit":2000,"pixelsperunit":3}]}`
// TODO: Keep checking old field for backwards compatibility, remove in future
jsonTemplate := `{"%s":[{"ethaddress":"0x0000000000000000000000000000000000000000","priceperunit":1000,"pixelsperunit":1}, {"ethaddress":"0x1000000000000000000000000000000000000000","priceperunit":2000,"pixelsperunit":3}]}`
testCases := []string{"gateways", "broadcasters"}

prices := getBroadcasterPrices(j)
assert.NotNil(prices)
assert.Equal(2, len(prices))
for _, tc := range testCases {
jsonStr := fmt.Sprintf(jsonTemplate, tc)

price1 := new(big.Rat).Quo(prices[0].PricePerUnit, prices[0].PixelsPerUnit)
price2 := new(big.Rat).Quo(prices[1].PricePerUnit, prices[1].PixelsPerUnit)
assert.Equal(big.NewRat(1000, 1), price1)
assert.Equal(big.NewRat(2000, 3), price2)
prices := getGatewayPrices(jsonStr)
assert.NotNil(prices)
assert.Equal(2, len(prices))

price1 := new(big.Rat).Quo(prices[0].PricePerUnit, prices[0].PixelsPerUnit)
price2 := new(big.Rat).Quo(prices[1].PricePerUnit, prices[1].PixelsPerUnit)
assert.Equal(big.NewRat(1000, 1), price1)
assert.Equal(big.NewRat(2000, 3), price2)
}
}

// Address provided to keystore file
Expand Down
Loading