Implement chain governance via SystemContract #152
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The SystemContract is a new protocol contract that exposes a simple API for chain governance:
stake: allows any address to deposit tokens in the SystemContract (liquid)unstake: opposite ofstake(retrieve tokens)delegate: an account locks some of its deposited stake to vote for a validator keyundelegate: an account unvotes from a validator key, unlocking tokens back into liquid stakevoteSlots: an elected validator chooses to increase or decrease the total number of active validators in the network (when 2/3+1 of active validators agree, the total number of active validators in the network changes).The SystemContract is a privileged contract that has direct and full control of the CometBFT validator set, and so it cannot be deployed by transactions; only the BDK node itself can instantiate the singleton SystemContract, either on
Blockchain::initChain()orBlockchain::loadSnapshot()(which are the only two ways to initialize a Blockchain node's machine state).The default number of slots (number of validators on a BDK network) on a new chain is initialized to the number of validators given in the
genesis.jsonconfiguration option. On genesis, the SystemContract will set the voting amount of all genesis validators to zero delegated tokens, irrespective of the voting power assigned to the CometBFT protocol in the genesis.json validator list. The default, genesis validators should either receive delegations from the chain owner after chain boot, or be replaced by some validators that actually get token votes.The validator set is determined by the number of avaliable slots and by a simple voting contest among all validator keys that have received a nonzero amount of delegated native tokens (votes) to fill these slots. If there are more slots than voted validator keys, all the validator keys that were delegated at least 1 wei are elected.
A validator (public) key can only receive delegations (token votes) from other keys after it is "registered". For a validator key to register itself, all it needs to do is to delegate tokens to itself, that is, using the account address that is controlled by the validator (private) key.
NOTE: This PR also rolls in a few fixes, improvements and new features that were developed together with the SystemContract feature.