|
8 | 8 | find_stake_program_address, find_transient_stake_program_address, |
9 | 9 | find_withdraw_authority_program_address, |
10 | 10 | inline_mpl_token_metadata::{self, pda::find_metadata_account}, |
11 | | - state::{Fee, FeeType, StakePool, ValidatorList}, |
| 11 | + state::{Fee, FeeType, StakePool, ValidatorList, ValidatorStakeInfo}, |
12 | 12 | MAX_VALIDATORS_TO_UPDATE, |
13 | 13 | }, |
14 | 14 | borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, |
15 | 15 | solana_program::{ |
16 | 16 | instruction::{AccountMeta, Instruction}, |
| 17 | + program_error::ProgramError, |
17 | 18 | pubkey::Pubkey, |
18 | 19 | stake, system_program, sysvar, |
19 | 20 | }, |
@@ -1363,6 +1364,10 @@ pub fn decrease_additional_validator_stake_with_vote( |
1363 | 1364 |
|
1364 | 1365 | /// Creates `UpdateValidatorListBalance` instruction (update validator stake |
1365 | 1366 | /// account balances) |
| 1367 | +#[deprecated( |
| 1368 | + since = "1.1.0", |
| 1369 | + note = "please use `update_validator_list_balance_chunk`" |
| 1370 | +)] |
1366 | 1371 | pub fn update_validator_list_balance( |
1367 | 1372 | program_id: &Pubkey, |
1368 | 1373 | stake_pool: &Pubkey, |
@@ -1423,6 +1428,74 @@ pub fn update_validator_list_balance( |
1423 | 1428 | } |
1424 | 1429 | } |
1425 | 1430 |
|
| 1431 | +/// Creates an `UpdateValidatorListBalance` instruction (update validator stake |
| 1432 | +/// account balances) to update `validator_list[start_index..start_index + |
| 1433 | +/// len]`. |
| 1434 | +/// |
| 1435 | +/// Returns `Err(ProgramError::InvalidInstructionData)` if: |
| 1436 | +/// - `start_index..start_index + len` is out of bounds for |
| 1437 | +/// `validator_list.validators` |
| 1438 | +pub fn update_validator_list_balance_chunk( |
| 1439 | + program_id: &Pubkey, |
| 1440 | + stake_pool: &Pubkey, |
| 1441 | + stake_pool_withdraw_authority: &Pubkey, |
| 1442 | + validator_list_address: &Pubkey, |
| 1443 | + reserve_stake: &Pubkey, |
| 1444 | + validator_list: &ValidatorList, |
| 1445 | + len: usize, |
| 1446 | + start_index: usize, |
| 1447 | + no_merge: bool, |
| 1448 | +) -> Result<Instruction, ProgramError> { |
| 1449 | + let mut accounts = vec![ |
| 1450 | + AccountMeta::new_readonly(*stake_pool, false), |
| 1451 | + AccountMeta::new_readonly(*stake_pool_withdraw_authority, false), |
| 1452 | + AccountMeta::new(*validator_list_address, false), |
| 1453 | + AccountMeta::new(*reserve_stake, false), |
| 1454 | + AccountMeta::new_readonly(sysvar::clock::id(), false), |
| 1455 | + AccountMeta::new_readonly(sysvar::stake_history::id(), false), |
| 1456 | + AccountMeta::new_readonly(stake::program::id(), false), |
| 1457 | + ]; |
| 1458 | + let validator_list_subslice = validator_list |
| 1459 | + .validators |
| 1460 | + .get(start_index..start_index.saturating_add(len)) |
| 1461 | + .ok_or(ProgramError::InvalidInstructionData)?; |
| 1462 | + accounts.extend(validator_list_subslice.iter().flat_map( |
| 1463 | + |ValidatorStakeInfo { |
| 1464 | + vote_account_address, |
| 1465 | + validator_seed_suffix, |
| 1466 | + transient_seed_suffix, |
| 1467 | + .. |
| 1468 | + }| { |
| 1469 | + let (validator_stake_account, _) = find_stake_program_address( |
| 1470 | + program_id, |
| 1471 | + vote_account_address, |
| 1472 | + stake_pool, |
| 1473 | + NonZeroU32::new((*validator_seed_suffix).into()), |
| 1474 | + ); |
| 1475 | + let (transient_stake_account, _) = find_transient_stake_program_address( |
| 1476 | + program_id, |
| 1477 | + vote_account_address, |
| 1478 | + stake_pool, |
| 1479 | + (*transient_seed_suffix).into(), |
| 1480 | + ); |
| 1481 | + [ |
| 1482 | + AccountMeta::new(validator_stake_account, false), |
| 1483 | + AccountMeta::new(transient_stake_account, false), |
| 1484 | + ] |
| 1485 | + }, |
| 1486 | + )); |
| 1487 | + Ok(Instruction { |
| 1488 | + program_id: *program_id, |
| 1489 | + accounts, |
| 1490 | + data: StakePoolInstruction::UpdateValidatorListBalance { |
| 1491 | + start_index: start_index.try_into().unwrap(), |
| 1492 | + no_merge, |
| 1493 | + } |
| 1494 | + .try_to_vec() |
| 1495 | + .unwrap(), |
| 1496 | + }) |
| 1497 | +} |
| 1498 | + |
1426 | 1499 | /// Creates `UpdateStakePoolBalance` instruction (pool balance from the stake |
1427 | 1500 | /// account list balances) |
1428 | 1501 | pub fn update_stake_pool_balance( |
@@ -1482,31 +1555,29 @@ pub fn update_stake_pool( |
1482 | 1555 | stake_pool_address: &Pubkey, |
1483 | 1556 | no_merge: bool, |
1484 | 1557 | ) -> (Vec<Instruction>, Vec<Instruction>) { |
1485 | | - let vote_accounts: Vec<Pubkey> = validator_list |
1486 | | - .validators |
1487 | | - .iter() |
1488 | | - .map(|item| item.vote_account_address) |
1489 | | - .collect(); |
1490 | | - |
1491 | 1558 | let (withdraw_authority, _) = |
1492 | 1559 | find_withdraw_authority_program_address(program_id, stake_pool_address); |
1493 | 1560 |
|
1494 | | - let mut update_list_instructions: Vec<Instruction> = vec![]; |
1495 | | - let mut start_index = 0; |
1496 | | - for accounts_chunk in vote_accounts.chunks(MAX_VALIDATORS_TO_UPDATE) { |
1497 | | - update_list_instructions.push(update_validator_list_balance( |
1498 | | - program_id, |
1499 | | - stake_pool_address, |
1500 | | - &withdraw_authority, |
1501 | | - &stake_pool.validator_list, |
1502 | | - &stake_pool.reserve_stake, |
1503 | | - validator_list, |
1504 | | - accounts_chunk, |
1505 | | - start_index, |
1506 | | - no_merge, |
1507 | | - )); |
1508 | | - start_index = start_index.saturating_add(MAX_VALIDATORS_TO_UPDATE as u32); |
1509 | | - } |
| 1561 | + let update_list_instructions = validator_list |
| 1562 | + .validators |
| 1563 | + .chunks(MAX_VALIDATORS_TO_UPDATE) |
| 1564 | + .enumerate() |
| 1565 | + .map(|(i, chunk)| { |
| 1566 | + // unwrap-safety: chunk len and offset are derived |
| 1567 | + update_validator_list_balance_chunk( |
| 1568 | + program_id, |
| 1569 | + stake_pool_address, |
| 1570 | + &withdraw_authority, |
| 1571 | + &stake_pool.validator_list, |
| 1572 | + &stake_pool.reserve_stake, |
| 1573 | + validator_list, |
| 1574 | + chunk.len(), |
| 1575 | + i.saturating_mul(MAX_VALIDATORS_TO_UPDATE), |
| 1576 | + no_merge, |
| 1577 | + ) |
| 1578 | + .unwrap() |
| 1579 | + }) |
| 1580 | + .collect(); |
1510 | 1581 |
|
1511 | 1582 | let final_instructions = vec![ |
1512 | 1583 | update_stake_pool_balance( |
|
0 commit comments