Difference between Reward() and ClaimEarnings()


In the first weeks of the Livepeer network being live, one thing that has constantly confused users of the protocol is the difference between the reward() transaction and the claimEarnings() transaction.


From explorer.livepeer.org/me/delegating


TLDR Summary

  • If you’re a transcoder, make sure to call reward() once per round. Don’t miss this.
  • Everyone who stakes needs to eventually call claimEarnings() to calculate how much token and fees they generated each round, but there is no rush to invoke this proactively. It happens behind the scenes when you change bonding status (unbonding, bonding more, or changing who you are bonded to).


reward() is a transaction that only transcoders need to invoke. When they invoke reward(), it generates newly minted LPT that gets split amongst them and their delegators.

  • Only transcoders invoke reward
  • They can only do this 1x/round (once per day)
  • If they fail to invoke reward() during a round, then they miss out on the newly minted LPT, and so do their delegators. It is very bad to not call reward, as it’s a big missed opportunity. that does not come back. Delegators will not be happy.
  • The newly generated LPT are automatically credited to the total delegated stake for the transcoder, and the delegated stake for each delegator. So they count towards stake for election in the next round’s active set.
  • The livepeer node should call reward() automatically at the very start of a round. But sometimes a shaky connection to an Ethereum node, or high gas prices, can cause this txn to not be submitted. Transcoders should always check if they called reward(), and call it manually via the CLI if they have not seen their txn get confirmed yet. The --gasPrice flag to the livepeer node can also help to get the txn through.


claimEarnings() is more of an accounting necessity than something that’s useful or valuable to a user as far as LPT is concerned. As mentioned above, when a transcoder calls reward() the newly generated token sit in a pool that’s credited towards their total stake. Each delegator is entitled to some of this token. How much they’re owed needs to be calculated on a round-by-round basis and credited to their account. Hence, when they call claimEarnings() they are paying for this calculation to take place on the blockchain, and the token to move from sitting in a big pool, to being allocated towards them individually.

Fees that a transcoder earns in ETH, are immediately distributed into a delegator’s account when they call claimEarnings() however.

While delegators do need to do this calculation for every single round (day), one call to claimEarnings() can do the calculation for 20 rounds.

  • Delegators or transcoders call claimEarnings() whenever they want to change their delegation status: unbond, bond towards another transcoder, bond more.
  • One call to claimEarnings() can update their status for up to 20 rounds. So if it’s been longer than 20 rounds since the last update, you may have to call claimEarnings() multiple times.
  • If it’s been less than 20 rounds, this happens in the background when you bond or unbond, you you don’t need to proactively call claimEarnings().
  • If you are not changing your bond, the most efficient strategy is to just call claimEarnings() once every 20 rounds. Or you can just wait and not do anything, and then call it, say 3 times if it’s been 60 rounds.
  • There’s no benefit to calling claimEarnings() more frequently if you aren’t changing bonding status, unless you prefer the ETH fees to be sitting in your account instead of in the Livepeer contract.
  • CAUTION: After you call claimEarnings() for a round, you can not call it again for that round. That means that if the transcoder earns more fees or calls reward() later in that round, you can not access those rewards or fees. To really optimize, change your bonding status late in the round after most of the fees have been collected and reward() has been called.

Network Economics Update - 5/13 - Transcoder Performance
How to restart a transcoder and verify it's active?