SHA256
GPT: сгенерено и не проверено (смена ключей пользователя)
This commit is contained in:
@@ -64,7 +64,7 @@ block_version: u8 = 0
|
||||
root_key: [u8;32]
|
||||
```
|
||||
|
||||
`root_key` — холодный recovery authority. Blockchain authority не может изменить root. Root authority может изменить root и остальные поля.
|
||||
`root_key` — холодный recovery authority. Обычные update не используют root. Root участвует только в полной ротации ключей: старый root разрешает переход на одновременно новые `root_key`, `client_key` и blockchain fork.
|
||||
|
||||
## ClientKeyBlock
|
||||
|
||||
@@ -74,7 +74,7 @@ block_version: u8 = 0
|
||||
client_key: [u8;32]
|
||||
```
|
||||
|
||||
Client key не является authority PDA. Он может использоваться клиентским уровнем и как fee payer Solana-транзакции.
|
||||
Client key не является authority PDA. Он может использоваться клиентским уровнем и как fee payer Solana-транзакции. В текущем протоколе смена `client_key` разрешена только как часть полной ротации вместе с root и новым blockchain fork.
|
||||
|
||||
## BlockchainRegistryBlock
|
||||
|
||||
@@ -148,12 +148,13 @@ PDA 1.2 разрешает `server_count = 0` или `1`. Count оставлен
|
||||
|
||||
- обычный update — активный blockchain key;
|
||||
- новый fork — новый blockchain key;
|
||||
- root-mode — root нового состояния;
|
||||
- смена root — новый root.
|
||||
- полная ротация root + client + blockchain fork — новый blockchain key.
|
||||
|
||||
На update программа дополнительно требует Ed25519-подпись authority предыдущего состояния по тому же hash нового unsigned state. Эта transition-подпись не хранится внутри PDA.
|
||||
|
||||
Blockchain-mode не может изменить root. Root-mode может изменить root и выполнить recovery. Одновременно менять root и добавлять blockchain fork одной транзакцией запрещено.
|
||||
Blockchain-mode не может изменить root. Для полной ротации используется root-mode: текущий root подписывает hash нового unsigned PDA state как разрешение на переход, а новый blockchain key подписывает тот же hash и его `signature[64]` сохраняется в PDA. Поскольку hash считается по всему unsigned state, обе подписи одновременно фиксируют новый root key, новый client key, новый blockchain fork и остальные поля записи.
|
||||
|
||||
Смена root считается корректной только как полная ротация: root key изменён, client key изменён и в ту же запись добавлен новый blockchain fork. Такая recovery-ротация не ограничивается обычным 72-часовым cooldown blockchain-authority.
|
||||
|
||||
## Create
|
||||
|
||||
|
||||
@@ -84,17 +84,22 @@ record_signature:[64]
|
||||
|
||||
Blockchain-mode:
|
||||
|
||||
- используется для всех обычных update;
|
||||
- старый authority = последний blockchain key;
|
||||
- root менять нельзя;
|
||||
- `signature[64]` нового состояния = активный blockchain key либо новый blockchain key, если добавляется fork;
|
||||
- root/client менять нельзя;
|
||||
- новый fork — только после 72 часов от времени активного fork.
|
||||
|
||||
Root-mode:
|
||||
|
||||
- старый authority = root;
|
||||
- root можно менять;
|
||||
- recovery fork может обходить 72-часовой cooldown.
|
||||
- допустим только для recovery/полной ротации ключей;
|
||||
- старый authority = текущий root;
|
||||
- полная ротация одной транзакцией меняет `root_key`, `client_key` и добавляет новый blockchain fork;
|
||||
- transition-подпись делает старый root, а `signature[64]` нового состояния делает новый blockchain key;
|
||||
- recovery fork может обходить 72-часовой cooldown;
|
||||
- смена root без одновременной смены client key и добавления нового blockchain fork отклоняется.
|
||||
|
||||
Root rotation и blockchain fork одной транзакцией запрещены.
|
||||
Обе Ed25519-подписи проверяются по одному и тому же hash нового unsigned PDA state, поэтому новые root/client/blockchain public keys входят в подписываемое состояние.
|
||||
|
||||
### `5 upsert_promo_seller`
|
||||
Без изменений.
|
||||
|
||||
@@ -90,6 +90,7 @@ enum ShineUsersError {
|
||||
CannotCloseCurrentFormat = 37,
|
||||
RootChangeRequiresRoot = 38,
|
||||
AmbiguousAuthorityRotation = 39,
|
||||
RootModeRequiresFullRotation = 40,
|
||||
}
|
||||
|
||||
impl From<ShineUsersError> for ProgramError {
|
||||
@@ -619,15 +620,20 @@ fn process_update_user_pda(program_id: &Pubkey, accounts: &[AccountInfo], args:
|
||||
require!(args.auth_mode == AUTH_MODE_BLOCKCHAIN || args.auth_mode == AUTH_MODE_ROOT, ShineUsersError::InvalidInstruction);
|
||||
|
||||
let root_changed = args.root_key != old_record.root_key;
|
||||
if args.auth_mode == AUTH_MODE_BLOCKCHAIN {
|
||||
require!(!root_changed, ShineUsersError::RootChangeRequiresRoot);
|
||||
}
|
||||
if root_changed && args.new_blockchain_key.is_some() {
|
||||
return Err(ProgramError::from(ShineUsersError::AmbiguousAuthorityRotation));
|
||||
let client_changed = args.client_key != old_record.client_key;
|
||||
let full_key_rotation = root_changed && client_changed && args.new_blockchain_key.is_some();
|
||||
|
||||
// root/client меняются только вместе с созданием нового blockchain fork.
|
||||
// Обычные update и обычный fork всегда авторизуются текущим blockchain key.
|
||||
if root_changed || client_changed {
|
||||
require!(full_key_rotation, ShineUsersError::AmbiguousAuthorityRotation);
|
||||
require!(args.auth_mode == AUTH_MODE_ROOT, ShineUsersError::RootChangeRequiresRoot);
|
||||
} else {
|
||||
require!(args.auth_mode == AUTH_MODE_BLOCKCHAIN, ShineUsersError::RootModeRequiresFullRotation);
|
||||
}
|
||||
|
||||
let old_active_key = old_record.active_fork()?.blockchain_key;
|
||||
let old_authority = if args.auth_mode == AUTH_MODE_ROOT { old_record.root_key } else { old_active_key };
|
||||
let old_authority = if full_key_rotation { old_record.root_key } else { old_active_key };
|
||||
let mut forks = old_record.forks.clone();
|
||||
|
||||
let additional_limit_u32 = u32::try_from(args.additional_limit).map_err(|_| ProgramError::from(ShineUsersError::PaidLimitTooLarge))?;
|
||||
@@ -636,7 +642,7 @@ fn process_update_user_pda(program_id: &Pubkey, accounts: &[AccountInfo], args:
|
||||
for fork in &forks {
|
||||
require!(fork.blockchain_key != new_key, ShineUsersError::DuplicateBlockchainKey);
|
||||
}
|
||||
if args.auth_mode == AUTH_MODE_BLOCKCHAIN {
|
||||
if !full_key_rotation {
|
||||
enforce_fork_cooldown(old_record.active_fork()?.created_at_ms, args.updated_at_ms)?;
|
||||
}
|
||||
|
||||
@@ -664,12 +670,8 @@ fn process_update_user_pda(program_id: &Pubkey, accounts: &[AccountInfo], args:
|
||||
signature: [0; 64],
|
||||
};
|
||||
|
||||
let record_signer = if root_changed {
|
||||
new_record.root_key
|
||||
} else if let Some(new_key) = appended_key {
|
||||
let record_signer = if let Some(new_key) = appended_key {
|
||||
new_key
|
||||
} else if args.auth_mode == AUTH_MODE_ROOT {
|
||||
new_record.root_key
|
||||
} else {
|
||||
new_record.active_fork()?.blockchain_key
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user