-- current validator state, in memory.
create table validator (
staking_address primary key,
bonded_coins btree_indexed,
voting_power = bonded_coins / 10000_0000,
validator_address unique_indexed,
council_node_info json,
proposer_stat int, -- or vote_stat
punishment json null,
);
-- validator state snapshoted at last commit time, persisted.
create table validator_committed copy of validator;
-- produce `Vec<ValidatorUpdate>` at end_block
-- get new validators
new = select validator_address, voting_power from validator
order by bonded_coins, staking_address desc
where punishment is not null
limit max_validators
-- get old validators from validator_committed
old = select validator_address, voting_power from validator_committed
order by bonded_coins, staking_address desc
where punishment is not null
limit max_validators
updates = diff(old, new)
-- bond/unbond
update validator set bonded_coins += ? where staking_address=?
-- update reward stat
update validator set proposer_stat=proposer_stat+1 where validator_address=?
-- get reward distribution proportion
select sum(proposer_stat) into num_blocks from validator
where proposer_stat > 0;
select *, proposer_stat / num_blocks as proportion from validator
where proposer_stat > 0;
-- clear reward stat
update validator set proposer_stat=0;
-- punishment
update validator set punishment = something where staking_address=?
-- remove punishment
update validator set punishment = null where staking_address=?
-- commit
copy validator to validator_committed