Last active
January 27, 2025 14:24
-
-
Save hoffmabc/a87c20bf98d87bff984a5bf643a408cf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub fn prepare_settlement_batch(accounts: &[AccountInfo], params: &SettlementBatchParams, raw_params_data: &[u8]) -> Result<(), ProgramError> { | |
validate_account(accounts, 0, true, true, Some(AccountType::Program), None)?; | |
if ProgramState::get_settlement_hash(&accounts[0])? != EMPTY_HASH { | |
return Err(ProgramError::Custom(ERROR_SETTLEMENT_IN_PROGRESS)); | |
} | |
ProgramState::clear_events(&accounts[0])?; | |
let mut running_netting_total: i64 = 0; | |
for token_settlements in ¶ms.settlements { | |
validate_account(accounts, token_settlements.account_index, false, false, Some(AccountType::Token), Some(0))?; | |
let decrement_sum: u64 = verify_decrements(&accounts, token_settlements.account_index, &token_settlements.decrements)?; | |
let increment_sum: u64 = verify_increments(&accounts, token_settlements.account_index, &token_settlements.increments)? + token_settlements.fee_amount; | |
running_netting_total += increment_sum as i64 - decrement_sum as i64; | |
} | |
if running_netting_total != 0 { | |
msg!("Netting failed {}", running_netting_total); | |
return Err(ProgramError::Custom(ERROR_NETTING)); | |
} | |
if ProgramState::get_events_count(&accounts[0])? == 0 { | |
ProgramState::set_settlement_hash(&accounts[0], hash(raw_params_data)) | |
} else { | |
Ok(()) | |
} | |
} | |
pub fn validate_account(accounts: &[AccountInfo], index: u8, is_signer: bool, is_writable: bool, account_type: Option<AccountType>, related_account_index: Option<u8>) -> Result<(), ProgramError> { | |
if index as usize >= accounts.len() { | |
return Err(ProgramError::Custom(ERROR_INVALID_ACCOUNT_INDEX)); | |
} | |
let account = &accounts[index as usize]; | |
if account.is_signer != is_signer || account.is_writable != is_writable { | |
return Err(ProgramError::Custom(ERROR_INVALID_ACCOUNT_FLAGS)); | |
} | |
if let Some(account_type) = account_type { | |
if get_type(account)? != account_type { | |
return Err(ProgramError::Custom(ERROR_INVALID_ACCOUNT_TYPE)); | |
} | |
if let Some(related_account_index) = related_account_index{ | |
let related_key = match account_type { | |
AccountType::Program => ProgramState::get_withdraw_account_key(&account), | |
AccountType::Withdraw => WithdrawState::get_program_state_account_key(&account), | |
AccountType::Token => TokenState::get_program_state_account_key(&account), | |
AccountType::RuneReceiver => RuneReceiverState::get_program_state_account_key(&account), | |
_ => Err(ProgramError::Custom(ERROR_INVALID_ACCOUNT_TYPE)) | |
}?; | |
if related_key != *accounts[related_account_index as usize].key { | |
return Err(ProgramError::Custom(ERROR_STATE_ACCOUNT_MISMATCH)); | |
} | |
} | |
} else { | |
if !account.data_is_empty() { | |
return Err(ProgramError::Custom(ERROR_ALREADY_INITIALIZED)) | |
} | |
} | |
Ok(()) | |
} | |
pub fn validate_bitcoin_address(address: &str, network_type: &NetworkType, strict: bool) -> Result<(), ProgramError> { | |
let network_unchecked_address = Address::from_str(address) | |
.map_err(|_| ProgramError::Custom(ERROR_INVALID_ADDRESS))?; | |
if strict || *network_type == NetworkType::Bitcoin { | |
network_unchecked_address | |
.require_network(map_network_type(network_type)) | |
.map_err(|_| ProgramError::Custom(ERROR_INVALID_ADDRESS_NETWORK))?; | |
} | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment