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

allow orchestrator to set ticket maxfacevalue #2290

Merged
merged 4 commits into from
Jun 10, 2022

Conversation

ad-astra-video
Copy link
Contributor

@ad-astra-video ad-astra-video commented Feb 24, 2022

What does this pull request do? Explain your changes. (required)
Allows Orchestrator nodes to specify ticket max face value while node is running. Default is no max face value.

Specific updates (required)

  • Add new fields to pm/recipient.go for maxfacevalue to adjust TicketParams faceValue. Update also included adding new methods to Recipient interface to provide means to update the values.
  • Add launch flag to specify value at startup
  • Add functions to core/livepeernode.go to update orchestrator node settings for above pm/recipient.go updates.
  • Add webserver endpoint /setMaxFaceValue to enable updating new maxfacevalue setting.

How did you test each of these updates (required)
After updates completed, ran orchestrator node on mainnet and monitored logs after updating settings with webserver endpoints.

Ticket was redeemed for 0.01 ETH by remote redeemer node for orchestrator. https://discord.com/channels/423160867534929930/808142181679235083/945862545527439370.

How to use webserver endpoints:

curl -F maxfacevalue=[face value in wei] http://127.0.0.1:7935/setMaxFaceValue

Does this pull request close any open issues?
No

Checklist:

  • Read the contribution guide
  • make runs successfully - with these changes applied to v0.5.29 source code
  • All tests in ./test.sh pass
  • README and other documentation updated
  • Pending changelog updated

@leszko leszko self-requested a review February 25, 2022 08:25
Copy link
Contributor

@leszko leszko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@0xB79 Thanks a lot for the PR. Great to see the community contribution!

Before we dig into the code review, could you please explain the use cases for the changes you made?

  1. I understand that one of the changes is to make -ticketEV flag configurable at runtime. In which scenarios would the Broadcaster need it?
  2. You added two configuration parameters faceValueLimit and faceValueFixed. When would you configure each of them? Maybe we will need to also at them to the flags, but first I need to understand the use cases.

Thanks!

@ad-astra-video
Copy link
Contributor Author

Hello @leszko

These updates are to allow the Orchestrator more control when setting the TicketParams sent to the Broadcasters.

  1. Updating ticketEV while Orchestrator node is running just updates the frequency the orchestrator gets tickets. With each update to ticketEV the winProb changes proportionally to the faceValue. To note, updating ticketEV to amount higher than current value while node is running may drop streams because the Orchestrator node, I believe, determines that the Broadcaster has not sent enough payment for transcoding. This happened when running the tests below on an Orchestrator node running on mainnet but streams picked back up within a few minutes.
  2. These allow Orchestrator ability to override the default faceValue calculated in pm/recipient.go. faceValueLimit would be to set an upper limit on the faceValue calculated and fixedFaceValue would be to override to any faceValue.

These could be added as command line flags and be set at run time. Another addition that would be helpful is adding ability to set these options with livepeer_cli.

Some examples of tickets received by orchestrator after updating running Orchestrator node:
Default TicketParams
Feb 25 11:37:49 s1155 livepeer[2190226]: I0225 11:37:49.080371 2190226 orchestrator.go:170] manifestID=7e1ef526-de34-4a00-8cb9-ea4e1a00f346 seqNo=6361 orchSessionID=6e38d210 clientIP=84.17.50.99 sender=0xc3c7c4C8f7061B7d6A72766Eee5359fE4F36e61E Receiving ticket sessionID=6e38d210 faceValue=0.09300341136 ETH winProb=0.0000107523 ev=1000000000000.00

Set faceValueLimit to 0.02ETH: curl -F facevaluelimit=20000000000000000 http://127.0.0.1:7935/setFaceValueLimit
Feb 25 11:41:17 s1155 livepeer[2190226]: I0225 11:41:17.673767 2190226 orchestrator.go:170] manifestID=747fa4e9-53e6-415d-9311-9a850433071b seqNo=14709 orchSessionID=3146c688 clientIP=89.187.178.130 sender=0xc3c7c4C8f7061B7d6A72766Eee5359fE4F36e61E Receiving ticket sessionID=3146c688 faceValue=0.02 ETH winProb=0.0000500000 ev=1000000000000.00

Set fixedFaceValue to 0.11 ETH, just above calculated faceValue: curl -F fixedfacevalue=110000000000000000 http://127.0.0.1:7935/setFixedFaceValue
Feb 25 11:43:39 s1155 livepeer[2190226]: I0225 11:43:39.443904 2190226 orchestrator.go:170] manifestID=747fa4e9-53e6-415d-9311-9a850433071b seqNo=14780 orchSessionID=3146c688 clientIP=89.187.178.130 sender=0xc3c7c4C8f7061B7d6A72766Eee5359fE4F36e61E Receiving ticket sessionID=3146c688 faceValue=0.11 ETH winProb=0.0000090909 ev=1000000000000.00

Set fixedFaceValue to 0.50 ETH: curl -F fixedfacevalue=500000000000000000 http://127.0.0.1:7935/setFixedFaceValue
Feb 25 12:07:08 s1155 livepeer[2190226]: I0225 12:07:08.629615 2190226 orchestrator.go:170] manifestID=5db2e08f-6e4c-4740-abbc-4a6f421feb46 seqNo=413 orchSessionID=e3a42ac7 clientIP=195.181.174.39 sender=0xc3c7c4C8f7061B7d6A72766Eee5359fE4F36e61E Receiving ticket sessionID=e3a42ac7 faceValue=0.5 ETH winProb=0.0000020000 ev=1000000000000.00

Set ticketEV to double default ticketEV to get less tickets with higher winProb: curl -F ticketev=2000000000000 http://127.0.0.1:7935/setTicketEV
Feb 25 11:49:25 s1155 livepeer[2190226]: I0225 11:49:25.614930 2190226 orchestrator.go:170] manifestID=d8b0370ycw1jkeop seqNo=26 orchSessionID=d4cfc904 clientIP=143.244.61.193 sender=0xc3c7c4C8f7061B7d6A72766Eee5359fE4F36e61E Receiving ticket sessionID=d4cfc904 faceValue=0.11 ETH winProb=0.0000181818 ev=2000000000000.00

@leszko
Copy link
Contributor

leszko commented Feb 28, 2022

@0xB79 Thanks for the explanation!

I add @yondonfu and @hthillman to decide if we want to add these faceValueLimit and fixedFaceValue parameters. I suggest that if we add the endpoints, we should also add livepeer flags to be consistent here.

Concerning ticketEV, I think it's ok to change it at runtime, so adding this endpoints is a good idea in my opinion.

I'll add some comments wrt the code itself after the comments from @yondonfu and/or @hthillman .

@yondonfu
Copy link
Member

I think giving Os more control over the faceValue used for tickets makes sense. However, I'm in favor of a configurable flag to adjust the maximum faceValue to use for a ticket, but not a configurable flag to set a fixed faceValue to use for a ticket right now because the security of the PM protocol right now depends on an O using a faceValue that does not exceed the reserve allocation that a B commits to the O (i.e. the B's reserve divided by the # of active Os). If an O uses a faceValue that exceeds this reserve allocation then the difference between the faceValue and the reserve allocation is the value that O risks losing out on in the even that a B's deposit is depleted before the O redeems a winning ticket. So, I'd advocate for the node to behave as safely as possible as a default to avoid scenarios where an O sets a fixed faceValue that causes it to lose out on value if a B's deposit is depleted.

If O can set the maximum faceValue to use then in the scenario where the B's reserve allocation is less than the maximum faceValue the node will still automatically set the faceValue to the reserve allocation as the "safe" value to use. In the scenario where the B's reserve allocation is greater than the maximum faceValue the node will just use the maximum faceValue as the faceValue. I believe this is more or less the behavior of the -faceValueLimit flag included in the current PR. In order to be consistent with naming, since we already have a -maxTicketEV flag, I suggest using the name -maxFaceValue.

@ad-astra-video
Copy link
Contributor Author

ad-astra-video commented May 10, 2022

I have updated to add command line flag and remove fixedFaceValue option. Tested by adding these commits to v0.5.29 code and building.

Also, added livepeer_cli option to update while orchestrator node is running.

Copy link
Contributor

@leszko leszko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes @0xB79 !

Added two comments. In short, the change about setting maxFaceValue is fine, however I'm not sure about the changes related to setting EV. I thought we only want to add the ability to set max face value in this PR.

Also, please rebase you branch to master since there are some conflicts.

glog.Errorf("-maxFaceValue must be a valid integer, but %v provided. Restart the node with a different valid value for -maxFaceValue", *maxFaceValue)
return
} else {
n.SetFaceValueLimit(mfv)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the sake of consistency, maybe let's name it n.SetMaxFaceValue() instead of n.SetFaceValueLimit()?

@@ -633,10 +634,19 @@ func main() {
timeWatcher,
cfg,
)
n.SetTicketEV(ev)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that line setting the fixed face value? I think we wanted to allow only setting max face value, why do we need this line then?

@ad-astra-video
Copy link
Contributor Author

Hello,

I applied the changes to dev branch using master branch code base. I am not sure I did this correctly...if I did not, commit [https://github.com/0xB79/go-livepeer/commit/280f67ff398b62e935f5a01e689df2056222cea1](this commit) should be able to applied to master branch. Would you prefer I do a pull request for that commit on master branch?

I incorporated the changes requested where it only allows setting a max face value. I tested by building and running on working orchestrator node.

There was one bug fix in starter.go where the cfg variable was changed to a TicketParamsConfig variable. It seemed to me this was not intentional so I updated the variable name to tcfg. I needed the cfg variable that had MaxFaceValue set from flag/config file after the lines below to set the value in the pm recipient.

@@ -705,7 +708,7 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) {
			sm.Start()
			defer sm.Stop()

			cfg := pm.TicketParamsConfig{
			tcfg := pm.TicketParamsConfig{
				EV:               ev,
				RedeemGas:        redeemGas,
				TxCostMultiplier: txCostMultiplier,
@@ -717,12 +720,20 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) {
				gpm,
				sm,
				timeWatcher,
				cfg,
				tcfg,
			)
			if err != nil {
				glog.Errorf("Error setting up PM recipient: %v", err)
				return
			}

Copy link
Contributor

@leszko leszko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update @0xB79

I think there is something wrong with the PR:

  • it's sent against livepeer:dev, not livepeer:master
  • It shows way too many changes in GH (140 files changed).

Could you please clean it up?

@ad-astra-video ad-astra-video changed the base branch from dev to master May 20, 2022 14:21
@ad-astra-video
Copy link
Contributor Author

@leszko I changed it to the livepeer:master branch and it shows 9 files changed now.

Copy link
Contributor

@leszko leszko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some minor comments. Other than that, please rebase to master. Thanks!

Comment on lines 731 to 732
glog.Errorf("-maxFaceValue must be a valid integer, but %v provided. Restart the node with a different valid value for -maxFaceValue", *cfg.MaxFaceValue)
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
glog.Errorf("-maxFaceValue must be a valid integer, but %v provided. Restart the node with a different valid value for -maxFaceValue", *cfg.MaxFaceValue)
return
panic(fmt.Errorf("-maxFaceValue must be a valid integer, but %v provided. Restart the node with a different valid value for -maxFaceValue", *cfg.MaxFaceValue))

Please use panic() instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

pm/recipient.go Outdated
//if faceValue > maxfacevalue, set faceValue=maxfacevalue
if r.maxfacevalue.Cmp(faceValue) < 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//if faceValue > maxfacevalue, set faceValue=maxfacevalue
if r.maxfacevalue.Cmp(faceValue) < 0 {
if r.maxfacevalue.Cmp(faceValue) < 0 {

Nit: There is no need for this comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, not used to Go with using .Cmp. Will remove comment.

@@ -517,6 +517,25 @@ func (s *LivepeerServer) setServiceURI(client eth.LivepeerEthClient, serviceURI
return nil
}

func (s *LivepeerServer) setMaxFaceValueHandler() http.Handler {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if you could add a unit test in handlers_test.go.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit tests added for maxfacevalue handler. Took some time for me to get up to speed on how to make a mock recipient in unit tests for the stub livepeer server.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit tests added.

Copy link
Contributor

@leszko leszko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the changes @0xB79 LGTM 👍

)
if err != nil {
glog.Errorf("Error setting up PM recipient: %v", err)
return
}
mfv, _ := new(big.Int).SetString(*cfg.MaxFaceValue, 10)
Copy link
Contributor

@thomshutt thomshutt Jun 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also check the returned bool that indicates success here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding was SetString returns nil if it fails. Is this correct? This is same pattern used on lines 675 and 740. I can update if prefer to check bool rather than value or prefer to check both.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From looking at the SetString code, it seems like the way you've done it probably is safe:

If SetString fails, the value of z is undefined but the returned value is nil

but I think to be safe and not depend on that behavior never changing, let's also check the success bool isn't false

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that for this one, for the sake of consistency, we can keep it as it is. And later convert all calls mfv, _ := new(big.Int).SetString(*cfg.MaxFaceValue, 10) to what Thom suggested.

Copy link
Contributor

@thomshutt thomshutt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - Could you update the PR description to reflect what the changes now look like please and then we'll merge

@leszko
Copy link
Contributor

leszko commented Jun 9, 2022

@0xB79 Last comments from Thom and we can merge your PR 🥳

Also, please run go fmt, because the GH Action test failed on the formatting.

@ad-astra-video ad-astra-video changed the title allow orchestrator to set ticket faceValue allow orchestrator to set ticket maxfacevalue Jun 9, 2022
@ad-astra-video
Copy link
Contributor Author

Updated title and pull request description to remove the items dropped from review comments.

@codecov
Copy link

codecov bot commented Jun 9, 2022

Codecov Report

Merging #2290 (ef3e916) into master (d360781) will decrease coverage by 0.06557%.
The diff coverage is 38.80597%.

❗ Current head ef3e916 differs from pull request most recent head 6cabe4c. Consider uploading reports for the commit 6cabe4c to get more accurate results

Impacted file tree graph

@@                 Coverage Diff                 @@
##              master       #2290         +/-   ##
===================================================
- Coverage   55.02775%   54.96218%   -0.06558%     
===================================================
  Files             94          94                 
  Lines          19641       19699         +58     
===================================================
+ Hits           10808       10827         +19     
- Misses          8236        8274         +38     
- Partials         597         598          +1     
Impacted Files Coverage Δ
cmd/livepeer/starter/starter.go 2.35525% <0.00000%> (-0.02100%) ⬇️
cmd/livepeer_cli/livepeer_cli.go 0.00000% <ø> (ø)
cmd/livepeer_cli/wizard_transcoder.go 0.00000% <0.00000%> (ø)
core/livepeernode.go 71.05263% <0.00000%> (-10.76556%) ⬇️
pm/stub.go 56.98113% <0.00000%> (-0.43333%) ⬇️
pm/recipient.go 89.63964% <57.14286%> (-2.45338%) ⬇️
server/handlers.go 53.62053% <84.21053%> (+0.54216%) ⬆️
cmd/livepeer/livepeer.go 46.62921% <100.00000%> (+0.30152%) ⬆️
server/webserver.go 95.87629% <100.00000%> (+0.04295%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d360781...6cabe4c. Read the comment docs.

@leszko leszko merged commit 35560ad into livepeer:master Jun 10, 2022
@leszko
Copy link
Contributor

leszko commented Jun 10, 2022

Thanks again for the PR @0xB79

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants