SHA256
Миграция PDA на client.key
This commit is contained in:
@@ -28,8 +28,9 @@ const MAX_SESSIONS: usize = 64;
|
||||
const MAX_SESSION_NAME_LEN: usize = 64;
|
||||
const MAX_AUTO_REALLOC_INCREASE: usize = 10_000;
|
||||
const ZERO_HASH: [u8; 32] = [0; 32];
|
||||
const BLOCK_TYPE_RECOVERY_KEY: u8 = 0;
|
||||
const BLOCK_TYPE_ROOT_KEY: u8 = 1;
|
||||
const BLOCK_TYPE_DEVICE_KEY: u8 = 2;
|
||||
const BLOCK_TYPE_CLIENT_KEY: u8 = 2;
|
||||
const BLOCK_TYPE_BLOCKCHAIN_REGISTRY: u8 = 3;
|
||||
const BLOCK_TYPE_SERVER_PROFILE: u8 = 30;
|
||||
const BLOCK_TYPE_ACCESS_SERVERS: u8 = 40;
|
||||
@@ -113,7 +114,7 @@ pub struct SessionRecord {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UserMutableFields {
|
||||
pub device_key: Pubkey,
|
||||
pub client_key: Pubkey,
|
||||
pub blockchain_public_key: Pubkey,
|
||||
pub blockchain_name: String,
|
||||
pub used_bytes: u64,
|
||||
@@ -135,6 +136,7 @@ pub struct UserMutableFields {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CreateUserPdaArgs {
|
||||
pub login: String,
|
||||
pub recovery_key: Pubkey,
|
||||
pub root_key: Pubkey,
|
||||
pub created_at_ms: u64,
|
||||
pub additional_limit: u64,
|
||||
@@ -145,6 +147,7 @@ pub struct CreateUserPdaArgs {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UpdateUserPdaArgs {
|
||||
pub login: String,
|
||||
pub recovery_key: Pubkey,
|
||||
pub root_key: Pubkey,
|
||||
pub created_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
@@ -190,8 +193,9 @@ pub struct UserRecord {
|
||||
pub record_number: u32,
|
||||
pub prev_record_hash: [u8; 32],
|
||||
pub login: String,
|
||||
pub recovery_key: Pubkey,
|
||||
pub root_key: Pubkey,
|
||||
pub device_key: Pubkey,
|
||||
pub client_key: Pubkey,
|
||||
pub blockchain: BlockchainRecord,
|
||||
pub is_server: bool,
|
||||
pub address_format_type: u8,
|
||||
@@ -291,6 +295,7 @@ fn process_instruction(program_id: &Pubkey, accounts: &[AccountInfo], instructio
|
||||
fn parse_create_args(r: &mut Reader<'_>) -> Result<CreateUserPdaArgs, ProgramError> {
|
||||
Ok(CreateUserPdaArgs {
|
||||
login: r.read_string_u8()?,
|
||||
recovery_key: r.read_pubkey()?,
|
||||
root_key: r.read_pubkey()?,
|
||||
created_at_ms: r.read_u64()?,
|
||||
additional_limit: r.read_u64()?,
|
||||
@@ -302,6 +307,7 @@ fn parse_create_args(r: &mut Reader<'_>) -> Result<CreateUserPdaArgs, ProgramErr
|
||||
fn parse_update_args(r: &mut Reader<'_>) -> Result<UpdateUserPdaArgs, ProgramError> {
|
||||
Ok(UpdateUserPdaArgs {
|
||||
login: r.read_string_u8()?,
|
||||
recovery_key: r.read_pubkey()?,
|
||||
root_key: r.read_pubkey()?,
|
||||
created_at_ms: r.read_u64()?,
|
||||
updated_at_ms: r.read_u64()?,
|
||||
@@ -314,7 +320,7 @@ fn parse_update_args(r: &mut Reader<'_>) -> Result<UpdateUserPdaArgs, ProgramErr
|
||||
}
|
||||
|
||||
fn parse_fields(r: &mut Reader<'_>) -> Result<UserMutableFields, ProgramError> {
|
||||
let device_key = r.read_pubkey()?;
|
||||
let client_key = r.read_pubkey()?;
|
||||
let blockchain_public_key = r.read_pubkey()?;
|
||||
let blockchain_name = r.read_string_u8()?;
|
||||
let used_bytes = r.read_u64()?;
|
||||
@@ -350,7 +356,7 @@ fn parse_fields(r: &mut Reader<'_>) -> Result<UserMutableFields, ProgramError> {
|
||||
}
|
||||
let trusted_count = r.read_u8()?;
|
||||
Ok(UserMutableFields {
|
||||
device_key,
|
||||
client_key,
|
||||
blockchain_public_key,
|
||||
blockchain_name,
|
||||
used_bytes,
|
||||
@@ -438,7 +444,7 @@ fn process_create_user_pda(program_id: &Pubkey, accounts: &[AccountInfo], args:
|
||||
require!(it.next().is_none(), ShineUsersError::InvalidInstruction);
|
||||
|
||||
require!(signer.is_signer, ShineUsersError::InvalidSigner);
|
||||
require_keys_eq!(*signer.key, args.fields.device_key, ShineUsersError::InvalidSigner);
|
||||
require_keys_eq!(*signer.key, args.fields.client_key, ShineUsersError::InvalidSigner);
|
||||
require_keys_eq!(*system_program_ai.key, system_program::id(), ShineUsersError::InvalidSystemProgram);
|
||||
|
||||
validate_login(&args.login)?;
|
||||
@@ -463,8 +469,9 @@ fn process_create_user_pda(program_id: &Pubkey, accounts: &[AccountInfo], args:
|
||||
record_number: 0,
|
||||
prev_record_hash: ZERO_HASH,
|
||||
login: args.login,
|
||||
recovery_key: args.recovery_key,
|
||||
root_key: args.root_key,
|
||||
device_key: args.fields.device_key,
|
||||
client_key: args.fields.client_key,
|
||||
blockchain: BlockchainRecord {
|
||||
blockchain_type: BLOCKCHAIN_TYPE_MAIN_USER,
|
||||
blockchain_name: args.fields.blockchain_name,
|
||||
@@ -520,7 +527,7 @@ fn process_update_user_pda(program_id: &Pubkey, accounts: &[AccountInfo], args:
|
||||
require!(it.next().is_none(), ShineUsersError::InvalidInstruction);
|
||||
|
||||
require!(signer.is_signer, ShineUsersError::InvalidSigner);
|
||||
require_keys_eq!(*signer.key, args.fields.device_key, ShineUsersError::InvalidSigner);
|
||||
require_keys_eq!(*signer.key, args.fields.client_key, ShineUsersError::InvalidSigner);
|
||||
require_keys_eq!(*system_program_ai.key, system_program::id(), ShineUsersError::InvalidSystemProgram);
|
||||
|
||||
validate_login(&args.login)?;
|
||||
@@ -537,7 +544,9 @@ fn process_update_user_pda(program_id: &Pubkey, accounts: &[AccountInfo], args:
|
||||
let old_record = deserialize_record_from_pda(&read_pda_all(user_pda)?)?;
|
||||
require!(old_record.login == args.login, ShineUsersError::ImmutableFieldChanged);
|
||||
require!(old_record.created_at_ms == args.created_at_ms, ShineUsersError::ImmutableFieldChanged);
|
||||
require_keys_eq!(old_record.recovery_key, args.recovery_key, ShineUsersError::ImmutableFieldChanged);
|
||||
require_keys_eq!(old_record.root_key, args.root_key, ShineUsersError::ImmutableFieldChanged);
|
||||
require_keys_eq!(old_record.client_key, args.fields.client_key, ShineUsersError::ImmutableFieldChanged);
|
||||
require!(args.version == old_record.record_number.saturating_add(1), ShineUsersError::InvalidVersion);
|
||||
require!(hash_unsigned_record(&old_record)? == args.prev_hash, ShineUsersError::InvalidPrevHash);
|
||||
require!(args.fields.blockchain_name == old_record.blockchain.blockchain_name, ShineUsersError::ImmutableFieldChanged);
|
||||
@@ -579,8 +588,9 @@ fn build_update_record(old_record: &UserRecord, args: &UpdateUserPdaArgs, new_ba
|
||||
record_number: args.version,
|
||||
prev_record_hash: args.prev_hash,
|
||||
login: old_record.login.clone(),
|
||||
recovery_key: old_record.recovery_key,
|
||||
root_key: old_record.root_key,
|
||||
device_key: args.fields.device_key,
|
||||
client_key: args.fields.client_key,
|
||||
blockchain: BlockchainRecord {
|
||||
blockchain_type: old_record.blockchain.blockchain_type,
|
||||
blockchain_name: args.fields.blockchain_name.clone(),
|
||||
@@ -672,8 +682,9 @@ fn deserialize_record_from_pda(raw: &[u8]) -> Result<UserRecord, ProgramError> {
|
||||
let login = read_len_prefixed_string_from(useful, &mut cursor)?;
|
||||
|
||||
let blocks_count = read_u8_from(useful, &mut cursor)? as usize;
|
||||
let mut recovery_key = None;
|
||||
let mut root_key = None;
|
||||
let mut device_key = None;
|
||||
let mut client_key = None;
|
||||
let mut blockchain = None;
|
||||
let mut is_server = false;
|
||||
let mut address_format_type = 0u8;
|
||||
@@ -690,13 +701,17 @@ fn deserialize_record_from_pda(raw: &[u8]) -> Result<UserRecord, ProgramError> {
|
||||
let block_version = read_u8_from(useful, &mut cursor)?;
|
||||
require!(block_version == BLOCK_VERSION_0, ShineUsersError::InvalidRecordFormat);
|
||||
match block_type {
|
||||
BLOCK_TYPE_RECOVERY_KEY => {
|
||||
require!(recovery_key.is_none(), ShineUsersError::InvalidRecordData);
|
||||
recovery_key = Some(Pubkey::new_from_array(read_fixed_32_from(useful, &mut cursor)?));
|
||||
}
|
||||
BLOCK_TYPE_ROOT_KEY => {
|
||||
require!(root_key.is_none(), ShineUsersError::InvalidRecordData);
|
||||
root_key = Some(Pubkey::new_from_array(read_fixed_32_from(useful, &mut cursor)?));
|
||||
}
|
||||
BLOCK_TYPE_DEVICE_KEY => {
|
||||
require!(device_key.is_none(), ShineUsersError::InvalidRecordData);
|
||||
device_key = Some(Pubkey::new_from_array(read_fixed_32_from(useful, &mut cursor)?));
|
||||
BLOCK_TYPE_CLIENT_KEY => {
|
||||
require!(client_key.is_none(), ShineUsersError::InvalidRecordData);
|
||||
client_key = Some(Pubkey::new_from_array(read_fixed_32_from(useful, &mut cursor)?));
|
||||
}
|
||||
BLOCK_TYPE_BLOCKCHAIN_REGISTRY => {
|
||||
require!(blockchain.is_none(), ShineUsersError::InvalidRecordData);
|
||||
@@ -743,8 +758,9 @@ fn deserialize_record_from_pda(raw: &[u8]) -> Result<UserRecord, ProgramError> {
|
||||
record_number,
|
||||
prev_record_hash,
|
||||
login,
|
||||
recovery_key: recovery_key.ok_or(ProgramError::from(ShineUsersError::InvalidRecordData))?,
|
||||
root_key: root_key.ok_or(ProgramError::from(ShineUsersError::InvalidRecordData))?,
|
||||
device_key: device_key.ok_or(ProgramError::from(ShineUsersError::InvalidRecordData))?,
|
||||
client_key: client_key.ok_or(ProgramError::from(ShineUsersError::InvalidRecordData))?,
|
||||
blockchain: blockchain.ok_or(ProgramError::from(ShineUsersError::InvalidRecordData))?,
|
||||
is_server,
|
||||
address_format_type,
|
||||
@@ -808,10 +824,11 @@ fn serialize_unsigned_record(record: &UserRecord) -> Result<Vec<u8>, ProgramErro
|
||||
out.push(login_bytes.len() as u8);
|
||||
out.extend_from_slice(login_bytes);
|
||||
|
||||
let blocks_count = if record.is_server { 7 } else { 6 };
|
||||
let blocks_count = if record.is_server { 8 } else { 7 };
|
||||
out.push(blocks_count);
|
||||
write_recovery_key_block(&mut out, record);
|
||||
write_root_key_block(&mut out, record);
|
||||
write_device_key_block(&mut out, record);
|
||||
write_client_key_block(&mut out, record);
|
||||
write_blockchain_registry_block(&mut out, &record.blockchain)?;
|
||||
if record.is_server { write_server_profile_block(&mut out, record)?; }
|
||||
write_access_servers_block(&mut out, record)?;
|
||||
@@ -840,8 +857,9 @@ fn hash_unsigned_record(record: &UserRecord) -> Result<[u8; 32], ProgramError> {
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn write_recovery_key_block(out: &mut Vec<u8>, record: &UserRecord) { out.push(BLOCK_TYPE_RECOVERY_KEY); out.push(BLOCK_VERSION_0); out.extend_from_slice(record.recovery_key.as_ref()); }
|
||||
fn write_root_key_block(out: &mut Vec<u8>, record: &UserRecord) { out.push(BLOCK_TYPE_ROOT_KEY); out.push(BLOCK_VERSION_0); out.extend_from_slice(record.root_key.as_ref()); }
|
||||
fn write_device_key_block(out: &mut Vec<u8>, record: &UserRecord) { out.push(BLOCK_TYPE_DEVICE_KEY); out.push(BLOCK_VERSION_0); out.extend_from_slice(record.device_key.as_ref()); }
|
||||
fn write_client_key_block(out: &mut Vec<u8>, record: &UserRecord) { out.push(BLOCK_TYPE_CLIENT_KEY); out.push(BLOCK_VERSION_0); out.extend_from_slice(record.client_key.as_ref()); }
|
||||
fn write_blockchain_registry_block(out: &mut Vec<u8>, blockchain: &BlockchainRecord) -> Result<(), ProgramError> { out.push(BLOCK_TYPE_BLOCKCHAIN_REGISTRY); out.push(BLOCK_VERSION_0); out.push(1); write_blockchain_record(out, blockchain) }
|
||||
fn write_blockchain_record(out: &mut Vec<u8>, blockchain: &BlockchainRecord) -> Result<(), ProgramError> {
|
||||
out.push(blockchain.blockchain_type);
|
||||
|
||||
Reference in New Issue
Block a user