Skip to content

Commit

Permalink
refactor: add -pricePerGateway and deprecate -pricePerBroadcaster (#3061
Browse files Browse the repository at this point in the history
)

This commit adds the `pricePerGateway` flag and deprecates the
`pricePerBroadcaster` flag
per core team decision (details:
https://discord.com/channels/423160867534929930/1051963444598943784/1210356864643109004).
  • Loading branch information
rickstaa committed May 20, 2024
1 parent add7368 commit 35db3f2
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 28 deletions.
1 change: 1 addition & 0 deletions cmd/livepeer/livepeer.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func parseLivepeerConfig() starter.LivepeerConfig {
// Unit of pixels for both O's basePriceInfo and B's MaxBroadcastPrice
cfg.PixelsPerUnit = flag.Int("pixelsPerUnit", *cfg.PixelsPerUnit, "Amount of pixels per unit. Set to '> 1' to have smaller price granularity than 1 wei / pixel")
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: {"gateways":[{"ethaddress":"address1","priceperunit":1000,"pixelsperunit":1},{"ethaddress":"address2","priceperunit":1200,"pixelsperunit":1}]}`)
cfg.PricePerBroadcaster = flag.String("pricePerBroadcaster", *cfg.PricePerBroadcaster, `json list of price per broadcaster or path to json config file. Example: {"broadcasters":[{"ethaddress":"address1","priceperunit":1000,"pixelsperunit":1},{"ethaddress":"address2","priceperunit":1200,"pixelsperunit":1}]}`)
// 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
82 changes: 63 additions & 19 deletions cmd/livepeer/starter/starter.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ type LivepeerConfig struct {
PricePerUnit *int
PixelsPerUnit *int
AutoAdjustPrice *bool
PricePerGateway *string
PricePerBroadcaster *string
BlockPollingInterval *int
Redeemer *bool
Expand Down Expand Up @@ -210,6 +211,7 @@ func DefaultLivepeerConfig() LivepeerConfig {
defaultMaxPricePerUnit := 0
defaultPixelsPerUnit := 1
defaultAutoAdjustPrice := true
defaultPricePerGateway := ""
defaultPricePerBroadcaster := ""
defaultBlockPollingInterval := 5
defaultRedeemer := false
Expand Down Expand Up @@ -300,6 +302,7 @@ func DefaultLivepeerConfig() LivepeerConfig {
MaxPricePerUnit: &defaultMaxPricePerUnit,
PixelsPerUnit: &defaultPixelsPerUnit,
AutoAdjustPrice: &defaultAutoAdjustPrice,
PricePerGateway: &defaultPricePerGateway,
PricePerBroadcaster: &defaultPricePerBroadcaster,
BlockPollingInterval: &defaultBlockPollingInterval,
Redeemer: &defaultRedeemer,
Expand Down Expand Up @@ -892,12 +895,14 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) {
}

if *cfg.PricePerBroadcaster != "" {
ppb := getBroadcasterPrices(*cfg.PricePerBroadcaster)
for _, p := range ppb {
price := big.NewRat(p.PricePerUnit, p.PixelsPerUnit)
n.SetBasePrice(p.EthAddress, price)
glog.Infof("Price: %v set for broadcaster %v", price.RatString(), p.EthAddress)
}
glog.Warning("-PricePerBroadcaster flag is deprecated and will be removed in a future release. Please use -PricePerGateway instead")
cfg.PricePerGateway = cfg.PricePerBroadcaster
}
gatewayPrices := getGatewayPrices(*cfg.PricePerGateway)
for _, p := range gatewayPrices {
price := big.NewRat(p.PricePerUnit, p.PixelsPerUnit)
n.SetBasePrice(p.EthAddress, price)
glog.Infof("Price: %v set for broadcaster %v", price.RatString(), p.EthAddress)
}

n.AutoSessionLimit = *cfg.MaxSessions == "auto"
Expand Down Expand Up @@ -1564,29 +1569,68 @@ func checkOrStoreChainID(dbh *common.DB, chainID *big.Int) error {
return nil
}

// Format of broadcasterPrices json
// {"broadcasters":[{"ethaddress":"address1","priceperunit":1000,"pixelsperunit":1}, {"ethaddress":"address2","priceperunit":2000,"pixelsperunit":3}]}
type BroadcasterPrices struct {
Prices []BroadcasterPrice `json:"broadcasters"`
}

type BroadcasterPrice struct {
type GatewayPrice struct {
EthAddress string `json:"ethaddress"`
PricePerUnit int64 `json:"priceperunit"`
PixelsPerUnit int64 `json:"pixelsperunit"`
}

func getBroadcasterPrices(broadcasterPrices string) []BroadcasterPrice {
var pricesSet BroadcasterPrices
prices, _ := common.ReadFromFile(broadcasterPrices)
func getGatewayPrices(gatewayPrices string) []GatewayPrice {
if gatewayPrices == "" {
return nil
}

err := json.Unmarshal([]byte(prices), &pricesSet)
// Format of gatewayPrices json
// {"gateways":[{"ethaddress":"address1","priceperunit":1000,"pixelsperunit":1}, {"ethaddress":"address2","priceperunit":2000,"pixelsperunit":3}]}
var pricesSet struct {
Gateways []struct {
EthAddress string `json:"ethaddress"`
PixelsPerUnit json.RawMessage `json:"pixelsperunit"`
PricePerUnit json.RawMessage `json:"priceperunit"`
} `json:"gateways"`
// TODO: Keep the old name for backwards compatibility, remove in the future
Broadcasters []struct {
EthAddress string `json:"ethaddress"`
PixelsPerUnit json.RawMessage `json:"pixelsperunit"`
PricePerUnit json.RawMessage `json:"priceperunit"`
} `json:"broadcasters"`
}
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)
return nil
}

return pricesSet.Prices
// 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, err := strconv.ParseInt(string(p.PixelsPerUnit), 10, 64)
if err != nil {
glog.Errorf("Pixels per unit could not be parsed for gateway %v. must be a valid number, provided %s", p.EthAddress, p.PixelsPerUnit)
continue
}
pricePerUnit, err := strconv.ParseInt(string(p.PricePerUnit), 10, 64)
if err != nil {
glog.Errorf("Price per unit could not be parsed for gateway %v. must be a valid number, provided %s", p.EthAddress, p.PricePerUnit)
continue
}
prices[i] = GatewayPrice{
EthAddress: p.EthAddress,
PricePerUnit: pricePerUnit,
PixelsPerUnit: pixelsPerUnit,
}
}

return prices
}

func createSelectionAlgorithm(cfg LivepeerConfig) (common.SelectionAlgorithm, error) {
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 := big.NewRat(prices[0].PricePerUnit, prices[0].PixelsPerUnit)
price2 := big.NewRat(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 := big.NewRat(prices[0].PricePerUnit, prices[0].PixelsPerUnit)
price2 := big.NewRat(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

0 comments on commit 35db3f2

Please sign in to comment.