Система голосования
Система голосования в управлении Savitri обеспечивает принятие решений on-chain с взвешиванием по токенам.
Типы голосов
| Тип | Значение |
|---|---|
Yes | Поддержать предложение |
No | Выступить против предложения |
Abstain | Учитывается для кворума, но не для одобрения |
Жизненный цикл предложения
Creation (+ deposit)
│
Review Period (24 hours)
│ Pending state, no voting allowed
▼
Voting Period (7 days default)
│ ActiveVoting state
▼
Tally
├── Quorum met + Approval met → Approved
├── Quorum met + Approval not met → Rejected
└── Quorum not met → Rejected (insufficient participation)
│
▼
Execution (if Approved)
Кворум и одобрение
| Порог | Значение | Описание |
|---|---|---|
| Кворум | 10% | От общего количества токенов голосования должно участвовать |
| Одобрение | 65% | От голосов «За» (исключая «Воздержался») |
Расчёт
total_votes = yes_votes + no_votes + abstain_votes
quorum_met = total_votes >= (total_vote_supply * 0.10)
approval = yes_votes / (yes_votes + no_votes) >= 0.65
Голоса «Воздержался» учитываются для кворума, но не в расчёте одобрения.
Блокировка токенов голосования
При подаче голоса токены голосования пользователя блокируются на весь период голосования. Это предотвращает:
- Двойное голосование (голосование теми же токенами за несколько предложений)
- Перевод токенов для повторного голосования с другого адреса
Токены разблокируются после окончания периода голосования.
Механизм депозита
Создание предложения требует депозита (защита от спама):
- Депозит возвращается, если предложение достигает кворума (независимо от результата)
- Депозит удерживается, если предложение не набирает кворум
Действия предложения
| Действие | Описание |
|---|---|
SetParameter | Изменить параметры сети |
TransferTreasury | Перевести средства казны |
UpgradeContract | Обновить смарт-контракт |
SetFlPolicy | Обновить параметры обучения FL |
ApproveFlModel | Утвердить модель FL для продакшена |
AbortFlRound | Аварийное прерывание раунда обучения FL |
SlashValidator | Штрафовать нарушающего правила валидатора |
Custom | Пользовательское действие управления |
Результаты голосования
pub struct VotingResult {
pub yes_votes: u64,
pub no_votes: u64,
pub abstain_votes: u64,
pub total_eligible: u64,
pub quorum_reached: bool,
pub approved: bool,
pub participation_rate: f64,
}
Распределение токенов голосования
Токены голосования зарабатываются за участие в работе узла:
| Уровень PoU | Диапазон оценок | Токены голосования / эпоха |
|---|---|---|
| Bronze | 300–499 | 10 |
| Silver | 500–699 | 25 |
| Gold | 700–899 | 50 |
| Platinum | 900–1000 | 100 |
Через SDK
Подача голоса
use savitri_sdk::{ContractClient, Wallet};
let contract = ContractClient::from_url_and_wallet(url, wallet)?;
let gov = contract.governance();
// Vote YES on proposal #42
let tx = gov.vote(&governance_address, 42, true).await?;
// Vote NO
let tx = gov.vote(&governance_address, 42, false).await?;
Проверка статуса предложения
let status = gov.get_proposal_status(&governance_address, 42).await?;
println!("Votes: {} for / {} against", status.votes_for, status.votes_against);
println!("Status: {} (executed: {})", status.status, status.executed);
Исполнение утверждённого предложения
Любой участник может инициировать исполнение утверждённого предложения:
let tx = gov.execute(&governance_address, 42).await?;
Хранилище
| Семейство столбцов | Ключ | Значение |
|---|---|---|
CF_GOVERNANCE | proposal_id (u64 LE) | Proposal (bincode) |
CF_VOTE_TOKENS | address (32 bytes) | Баланс токенов голосования |
Хронология
| Фаза | Длительность | Состояние |
|---|---|---|
| Проверка | 24 часа | Pending |
| Голосование | 7 дней (настраивается) | ActiveVoting |
| Исполнение | Немедленно после подсчёта | Approved → Executed |