go-algorand
go-algorand copied to clipboard
Incentives: Suspend "absentee" accounts that don't propose.
Building on #5740, this PR "suspends" accounts that claim to be online but don't appear to be participating. With the addition of block incentives comes the concern that participants, eager to earn incentives, will begin participating without being as careful as we'd like. They might run a node without paying enough attention to uptime. Two of the biggest concerns:
- An entity with a lot of stake (say an exchange) runs their node to earn incentives, but doesn't worry (enough) about uptime. A 5% node can go down without harming the protocol, but it would be scary. And in a decentralized network, one might wonder who they are and when they will get around to fixing it.
- Many entities, each with a little stake, decide to participate. Over time, they might get bored or distracted, and not notice that the proverbial "node in their basement" has failed.
This PR proposes that the network suspend nodes if they go too long without participating, as determined by their lack of proposals. A proposer can suspend accounts that have not proposed in a "long" time, currently 10x the interval over which one would have expected them to propose. A node with 1% stake should propose once every 100 rounds. If they have not proposed for 1,000 rounds, they can be suspended. Large stakeholders with failed nodes would be noticed relatively quickly (on the scale of an hour). Small stakeholders with broken nodes would be noticed more slowly, but would also slowly be removed, presumably before too many accumulate.
keyreg can be somewhat arduous for large stake holders who use multisig, Ledgers, cold storage wallets, and so on. Therefore, we would not want false positive suspensions which would require a new keyreg to go back online. So, a follow-on will add a "heartbeat" mechanism (#5799). If a node notices that it it has been unlucky, and is perhaps approaching 8 or 9 times their expected proposal interval, they can issue a special kind of keyreg that simply renews their existing voting keys. Since it's hard to get transactions signed by secure, high-stake accounts, this special keyreg can be signed by the participation keys of the account, not the spending key. For accounts that separate the job of node running and (spending) key management, we want the node runner to be able to issue these keep-alives. However, care must be taken to ensure that participation keys can only sign these keep-alive transactions, and that they can not be "spammed", wasting fees, by a node runner gone rogue.
While "suspension" removes the account's balance from online stake, it it does not remove voting key material from the node's account record. Therefore, in the case of a long lasting network partition that cause an account to be suspended, the node can return to service when the network heals by sending a keep-alive (again, no laborious keyreg is required).
Many things remain to do:
- [x] Add new account fields to REST API and AVM
- [x] Update an account's LastProposed field during the mining payout
- [x] And bring them back online if they were suspended
- [x] Mark a newly online account with
LastHeartbeat= current round. - [ ] Note suspendible accounts, verify them, and suspend them
- [ ] Account for pending rewards in calculation
- [ ] Get acct and total stake from the same round
- [ ] Use a grace period so that accounts don't have to predict their suspension
this special keyreg can be signed by the participation keys of the account, not the spending key.
This is very interesting to me. I wonder if a similar mechanism can be used for online registration in-general. For example, Alice wants to participate for X rounds, but only wants to generate the keys for some number of rounds less than X right now. Alice signs the initial keyreg with her signing key, but the node will automate the key generation and future keyregs at some interval up until round X.
this special keyreg can be signed by the participation keys of the account, not the spending key.
This is very interesting to me. I wonder if a similar mechanism can be used for online registration in-general. For example, Alice wants to participate for X rounds, but only wants to generate the keys for some number of rounds less than X right now. Alice signs the initial keyreg with her signing key, but the node will automate the key generation and future keyregs at some interval up until round X.
That's is approximately how it works today. Alice generates a "root" participation key pair. That's the one she supplies at keyreg time. Before doing so, she generates a bunch, say 1,000, "batch keys", which she signs with the root key. Then she throws away the root private key, so that no more batch keys can ever be signed. Finally, as needed, she takes one of the batch keys, generates and signs another 1,000 or so keys that are intended for use in specific rounds of the protocol, throws away that batch key. Those are true "participation keys" and are used for only one round, then deleted.
In this way, Alice "virtually" has a million keys, but never actually has more than 2,000 in existence. Agreement performs three signatures check when checking an agreement signature. The signature of the message, and then two signatures to work up the chain and ensure that the root key is the root of trust. Only that root key was signed by the spending key (to prepare the keyreg)
That's for normal agreement keys. Some of this is different for state proof keys, I don't know that system as well.
In this proposal, I'm advocating for the derived key that is usable for agreement in round X to also be usable to construct and sign a heartbeat transaction with firstvalid=X.
Codecov Report
Attention: Patch coverage is 61.18068% with 217 lines in your changes are missing coverage. Please review.
Project coverage is 55.88%. Comparing base (
0e7087b) to head (3d2fbc4). Report is 2 commits behind head on master.
Additional details and impacted files
@@ Coverage Diff @@
## master #5757 +/- ##
==========================================
+ Coverage 55.78% 55.88% +0.10%
==========================================
Files 490 491 +1
Lines 68125 68473 +348
==========================================
+ Hits 38004 38269 +265
- Misses 27562 27613 +51
- Partials 2559 2591 +32
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.