Add reward caller (using transcoder-to-reward caller mapping direction)#648
Conversation
Additional notes on the implementationNote-01:It is possible for a transcoder to set the RewardCaller as themself and call functions designated for RewardCallers. By doing so, the transcoder itself will be able to use the Note-02:It is possible for a TranscoderA to set the TranscoderB as RewardCaller. In this case, TranscoderB will be able to claim reward for themself by calling Note-03:In this implementation it is possible that multiple different transcoders set the same address as their RewardCaller. It will allow the same RewardCaller to call Note-04:It is not part of the current implementation, but it's possible to add a functionality to self-revoke RewardCaller. Currently, only the transcoder which set the RewardCaller can unset it by calling |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## delta #648 +/- ##
===============================================
Coverage 100.00000% 100.00000%
===============================================
Files 29 29
Lines 1338 1349 +11
Branches 225 226 +1
===============================================
+ Hits 1338 1349 +11
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
* docs: add Delegated Reward Calling draft LIP Add a draft LIP for delegating the reward() call to a separate low-privilege address so an orchestrator's stake-holding wallet can stay cold. Based on the implementation in livepeer/protocol#648. * Update sidestream author name Co-authored-by: SidestreamCrunchyCarrot <crunchycarrot@sidestream.tech> * chore: add forum discussion thread * docs: assign LIP 118 Assign 118 to this LIP according to the convention to allign it with the authoring PR nr. --------- Co-authored-by: SidestreamCrunchyCarrot <crunchycarrot@sidestream.tech>
|
Non-blocking test suggestion: the auth require is never tested with a wrong caller while one is set (mapping = A, sender = B). It's somewhat implicit in the existing unset-caller test given the current implementation, but a specific test would guard future changes — it pins the check to "only the authorized address" vs "anyone once set": it("should fail if caller is not the reward caller set by the transcoder", async () => {
await bondingManager.connect(transcoder).setRewardCaller(nonTranscoder.address)
await expect(
bondingManager.connect(signers[2]).rewardForTranscoder(transcoder.address)
).to.be.revertedWith("caller must be a reward caller set by the transcoder")
}) |
rickstaa
left a comment
There was a problem hiding this comment.
@SidestreamSweatyPumpkin Implementation is correct, my personal security and code review found no exploits and no griefing angles (full notes in Notion). Summary: setter is self-scoped and revocable; delegated reward is economically identical to a self-call; no new external call sites; storage layout append-safe; all BondingManager unit tests pass.
Biggest finding was that we need to patch the explorer HistoryView in the explorer with the upgrade to ensure reward events still show up correctly for people using this new function. The change is not breaking the subgraph or go-livepeer. For go-livepeer as discussed before the changes are only addative.
Left some minor comments regarding wording and tests.
SidestreamCrunchyCarrot
left a comment
There was a problem hiding this comment.
Sanity checks:
- ✅ No changes unrelated to the PR description
- ✅ CI pass at the latest commit 99c0008
- ✅ Hardhat-based tests run locally on the latest block (
939 passing (6m)) - ✅ Test coverage is at 100%
dob
left a comment
There was a problem hiding this comment.
I'm comfortable with the logic introduced in this change. Though I did leave one open question about the modifiers on the rewardWithHint function to address.
| currentRoundInitialized | ||
| autoCheckpoint(msg.sender) | ||
| { | ||
| function rewardWithHint(address _newPosPrev, address _newPosNext) public { |
There was a problem hiding this comment.
Why did we do away with the whenSystemNotPaused, currentRoundInitialized, autoCheckpoint modifiers on this function?
What does this pull request do? Explain your changes. (required)
This PR adds a new feature to the livepeer protocol which will allow transcoders to set a single address they trust to claim the rewards every on round without requiring the main wallet to stay unlocked.
Specific updates (required)
contracts/bonding/BondingManager.solcontract is modified to includetranscoderToRewardCallerpublic mappingsetRewardCallerfunction to set or unset arewardCallerrewardForTranscoder,rewardForTranscoderWithHintfunctions to claim rewards usingrewardCalleraccounttest/unit/BondingManager.jstest is modified to include new "reward delegation" sectionyarn test:coverage:checkcommand is added to the CI to insure 100% test coverageHow did you test each of these updates (required)
A new "reward delegation" section contains tests that ensure:
rewardForTranscoderrewardForTranscoderDoes this pull request close any open issues?
No
Checklist:
README and other documentation updatedyarn testpass