Skip to content

Remove allocations in offchain path in try_find_program_address#524

Open
4r33x wants to merge 2 commits into
anza-xyz:masterfrom
4r33x:better_try_find_program_address
Open

Remove allocations in offchain path in try_find_program_address#524
4r33x wants to merge 2 commits into
anza-xyz:masterfrom
4r33x:better_try_find_program_address

Conversation

@4r33x

@4r33x 4r33x commented Jan 10, 2026

Copy link
Copy Markdown
Contributor

The old code creates a new allocation on each iteration (unless the compiler manages to optimize it away):

    let mut bump_seed = [u8::MAX];
    for _ in 0..u8::MAX {
        {
            let mut seeds_with_bump = seeds.to_vec();
            seeds_with_bump.push(&bump_seed);
            match Self::create_program_address(&seeds_with_bump, program_id) {
                Ok(address) => return Some((address, bump_seed[0])),
                Err(AddressError::InvalidSeeds) => (),
                _ => break,
            }
        }
        bump_seed[0] -= 1;
    }
    None

Better version:

    let idx = seeds.len();
    let mut bump_storage = [0u8; 1];
    let mut seeds_with_bump: alloc::vec::Vec<&[u8]> =
        alloc::vec::Vec::with_capacity(idx + 1);
    seeds_with_bump.extend_from_slice(seeds);
    for bump in (0..=u8::MAX).rev() {
        bump_storage[0] = bump;
        // SAFETY: bump_storage is stack-allocated and outlives the vector.
        // from_raw_parts breaks the borrow chain so the compiler won't track
        // aliasing with bump_storage, but we ensure correctness by truncating
        // before each mutation.
        let bump_slice = unsafe { core::slice::from_raw_parts(bump_storage.as_ptr(), 1) };
        seeds_with_bump.push(bump_slice);

        match Self::create_program_address(&seeds_with_bump, program_id) {
            Ok(address) => return Some((address, bump)),
            Err(AddressError::InvalidSeeds) => {
                seeds_with_bump.truncate(idx);
                continue;
            }
            _ => return None,
        }
    }
    None

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant