shine_users: switch user record to v1.0 status-key layout and login<=25
This commit is contained in:
parent
61fcfd0e3b
commit
8ce804eb77
@ -69,7 +69,7 @@
|
|||||||
10. `login`
|
10. `login`
|
||||||
Размер: `login_len` байт (UTF-8).
|
Размер: `login_len` байт (UTF-8).
|
||||||
Назначение: логин пользователя.
|
Назначение: логин пользователя.
|
||||||
Текущие ограничения: от 1 до 20 символов, только `a-z`, `0-9`, `_`.
|
Текущие ограничения: от 1 до 25 символов, только `a-z`, `0-9`, `_`.
|
||||||
|
|
||||||
11. `root_key_status`
|
11. `root_key_status`
|
||||||
Размер: 1 байт (`u8`).
|
Размер: 1 байт (`u8`).
|
||||||
|
|||||||
@ -14,6 +14,7 @@ use std::str::FromStr;
|
|||||||
const MAGIC: &[u8; 5] = b"SHiNE";
|
const MAGIC: &[u8; 5] = b"SHiNE";
|
||||||
const FORMAT_MAJOR: u8 = 1;
|
const FORMAT_MAJOR: u8 = 1;
|
||||||
const FORMAT_MINOR: u8 = 0;
|
const FORMAT_MINOR: u8 = 0;
|
||||||
|
const KEY_STATUS_CREATED: u8 = 0;
|
||||||
const RESERVED_BYTES: [u8; 5] = [0, 0, 0, 0, 0];
|
const RESERVED_BYTES: [u8; 5] = [0, 0, 0, 0, 0];
|
||||||
const ZERO_HASH: [u8; 32] = [0; 32];
|
const ZERO_HASH: [u8; 32] = [0; 32];
|
||||||
|
|
||||||
@ -58,8 +59,11 @@ pub struct UserRecord {
|
|||||||
pub version: u32,
|
pub version: u32,
|
||||||
pub prev_hash: [u8; 32],
|
pub prev_hash: [u8; 32],
|
||||||
pub login: String,
|
pub login: String,
|
||||||
|
pub root_key_status: u8,
|
||||||
pub root_key: Pubkey,
|
pub root_key: Pubkey,
|
||||||
|
pub blockchain_key_status: u8,
|
||||||
pub blockchain_key: Pubkey,
|
pub blockchain_key: Pubkey,
|
||||||
|
pub device_key_status: u8,
|
||||||
pub device_key: Pubkey,
|
pub device_key: Pubkey,
|
||||||
pub chain_number: u16,
|
pub chain_number: u16,
|
||||||
pub balance: u64,
|
pub balance: u64,
|
||||||
@ -133,8 +137,11 @@ pub fn create_user_pda(ctx: Context<CreateUserPda>, args: CreateUserPdaArgs) ->
|
|||||||
version: 0,
|
version: 0,
|
||||||
prev_hash: ZERO_HASH,
|
prev_hash: ZERO_HASH,
|
||||||
login: args.login.clone(),
|
login: args.login.clone(),
|
||||||
|
root_key_status: KEY_STATUS_CREATED,
|
||||||
root_key: args.root_key,
|
root_key: args.root_key,
|
||||||
|
blockchain_key_status: KEY_STATUS_CREATED,
|
||||||
blockchain_key: args.fields.blockchain_key,
|
blockchain_key: args.fields.blockchain_key,
|
||||||
|
device_key_status: KEY_STATUS_CREATED,
|
||||||
device_key: args.fields.device_key,
|
device_key: args.fields.device_key,
|
||||||
chain_number: args.fields.chain_number,
|
chain_number: args.fields.chain_number,
|
||||||
balance: start_balance,
|
balance: start_balance,
|
||||||
@ -226,6 +233,12 @@ pub fn update_user_pda(ctx: Context<UpdateUserPda>, args: UpdateUserPdaArgs) ->
|
|||||||
args.root_key,
|
args.root_key,
|
||||||
ErrCode::ImmutableFieldChanged
|
ErrCode::ImmutableFieldChanged
|
||||||
);
|
);
|
||||||
|
require!(
|
||||||
|
old_record.root_key_status == KEY_STATUS_CREATED
|
||||||
|
&& old_record.blockchain_key_status == KEY_STATUS_CREATED
|
||||||
|
&& old_record.device_key_status == KEY_STATUS_CREATED,
|
||||||
|
ErrCode::InvalidRecordData
|
||||||
|
);
|
||||||
require!(
|
require!(
|
||||||
args.version == old_record.version.saturating_add(1),
|
args.version == old_record.version.saturating_add(1),
|
||||||
ErrCode::InvalidVersion
|
ErrCode::InvalidVersion
|
||||||
@ -250,8 +263,11 @@ pub fn update_user_pda(ctx: Context<UpdateUserPda>, args: UpdateUserPdaArgs) ->
|
|||||||
version: args.version,
|
version: args.version,
|
||||||
prev_hash: provided_prev_hash,
|
prev_hash: provided_prev_hash,
|
||||||
login: old_record.login.clone(),
|
login: old_record.login.clone(),
|
||||||
|
root_key_status: old_record.root_key_status,
|
||||||
root_key: old_record.root_key,
|
root_key: old_record.root_key,
|
||||||
|
blockchain_key_status: old_record.blockchain_key_status,
|
||||||
blockchain_key: args.fields.blockchain_key,
|
blockchain_key: args.fields.blockchain_key,
|
||||||
|
device_key_status: old_record.device_key_status,
|
||||||
device_key: args.fields.device_key,
|
device_key: args.fields.device_key,
|
||||||
chain_number: args.fields.chain_number,
|
chain_number: args.fields.chain_number,
|
||||||
balance: new_balance,
|
balance: new_balance,
|
||||||
@ -320,8 +336,11 @@ fn serialize_unsigned_record(record: &UserRecord) -> Result<Vec<u8>> {
|
|||||||
out.push(login_bytes.len() as u8);
|
out.push(login_bytes.len() as u8);
|
||||||
out.extend_from_slice(login_bytes);
|
out.extend_from_slice(login_bytes);
|
||||||
|
|
||||||
|
out.push(record.root_key_status);
|
||||||
out.extend_from_slice(record.root_key.as_ref());
|
out.extend_from_slice(record.root_key.as_ref());
|
||||||
|
out.push(record.blockchain_key_status);
|
||||||
out.extend_from_slice(record.blockchain_key.as_ref());
|
out.extend_from_slice(record.blockchain_key.as_ref());
|
||||||
|
out.push(record.device_key_status);
|
||||||
out.extend_from_slice(record.device_key.as_ref());
|
out.extend_from_slice(record.device_key.as_ref());
|
||||||
|
|
||||||
out.extend_from_slice(&record.chain_number.to_le_bytes());
|
out.extend_from_slice(&record.chain_number.to_le_bytes());
|
||||||
@ -384,8 +403,11 @@ fn deserialize_record_from_pda(raw: &[u8]) -> Result<UserRecord> {
|
|||||||
let prev_hash = read_fixed_32(useful, &mut cursor)?;
|
let prev_hash = read_fixed_32(useful, &mut cursor)?;
|
||||||
let login = read_len_prefixed_string(useful, &mut cursor)?;
|
let login = read_len_prefixed_string(useful, &mut cursor)?;
|
||||||
|
|
||||||
|
let root_key_status = read_u8(useful, &mut cursor)?;
|
||||||
let root_key = Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?);
|
let root_key = Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?);
|
||||||
|
let blockchain_key_status = read_u8(useful, &mut cursor)?;
|
||||||
let blockchain_key = Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?);
|
let blockchain_key = Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?);
|
||||||
|
let device_key_status = read_u8(useful, &mut cursor)?;
|
||||||
let device_key = Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?);
|
let device_key = Pubkey::new_from_array(read_fixed_32(useful, &mut cursor)?);
|
||||||
|
|
||||||
let chain_number = read_u16(useful, &mut cursor)?;
|
let chain_number = read_u16(useful, &mut cursor)?;
|
||||||
@ -423,8 +445,11 @@ fn deserialize_record_from_pda(raw: &[u8]) -> Result<UserRecord> {
|
|||||||
version,
|
version,
|
||||||
prev_hash,
|
prev_hash,
|
||||||
login,
|
login,
|
||||||
|
root_key_status,
|
||||||
root_key,
|
root_key,
|
||||||
|
blockchain_key_status,
|
||||||
blockchain_key,
|
blockchain_key,
|
||||||
|
device_key_status,
|
||||||
device_key,
|
device_key,
|
||||||
chain_number,
|
chain_number,
|
||||||
balance,
|
balance,
|
||||||
@ -551,7 +576,7 @@ fn le_u16(data: &[u8], offset: usize) -> Result<u16> {
|
|||||||
|
|
||||||
fn validate_login(login: &str) -> Result<()> {
|
fn validate_login(login: &str) -> Result<()> {
|
||||||
require!(!login.is_empty(), ErrCode::InvalidLogin);
|
require!(!login.is_empty(), ErrCode::InvalidLogin);
|
||||||
require!(login.len() <= 30, ErrCode::InvalidLogin);
|
require!(login.len() <= 25, ErrCode::InvalidLogin);
|
||||||
for ch in login.chars() {
|
for ch in login.chars() {
|
||||||
if !(ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '_') {
|
if !(ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '_') {
|
||||||
return Err(error!(ErrCode::InvalidLogin));
|
return Err(error!(ErrCode::InvalidLogin));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user