coral-xyz / anchor

⚓ Solana Sealevel Framework
https://anchor-lang.com
Apache License 2.0
3.63k stars 1.33k forks source link

zero_copy accounts are not working properly on aarch64-apple-darwin #2689

Open Arrowana opened 11 months ago

Arrowana commented 11 months ago

Problem

There might be something incompatible in zero_copy with anchor slicing of the account and aarch64-apple-darwin

Repro with this branch cd tests/zero_copy/programs/zero_copy && cargo test-sbf https://github.com/Arrowana/anchor/commit/64d8ac663da210a6c78d193d99a48b05a89f5c23

---- test_repro_zc_bug stdout ----
thread 'test_repro_zc_bug' panicked at 'from_bytes>TargetAlignmentGreaterAndInputNotAligned', /Users/arowana/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bytemuck-1.14.0/src/internal.rs:32:3
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

caused by

let zc_bug_account = banks_client
        .get_account(zc_bug_pubkey)
        .await
        .unwrap()
        .unwrap();
    let zc_bug = zero_copy::ZcBug::try_deserialize(&mut zc_bug_account.data.as_slice()).unwrap();

The ZcBug account struct itself is aligned, a single u128

https://github.com/Lokathor/bytemuck/blob/ff0b14dae9a4f0650f17c15c16acbd75df1cc4b5/src/internal.rs#L185

is_aligned_to(s.as_ptr() as *const (), align_of::<T>()) is false

Which seems to be caused by try_deserialize_unchecked doing data[8..], the original account data is obviously not aligned on aarch64-apple-darwin due to the 8 bytes discriminator.

Interestingly there has been a PR on this exact line last month, but it looks like it was for an optimization rather than anything else. I tried to build with feature align_offset but it doesn't change the outcome.

Quite an inconvenience that this build fine but blows up later, unclear how it could be fixed.

Workaround

  1. Build client binary with --target x86_64-apple-darwin

  2. Doing this on client instead makes it work, this can be added to the test

    let data = zc_bug_account.data;
    let mut data_without_discriminator = data[8..].to_vec();
    let zc_bug_again: &mut zero_copy::ZcBug =
        bytemuck::from_bytes_mut(&mut data_without_discriminator);
    println!("{}", zc_bug_again.a);
acheroncrypto commented 11 months ago

Could you share an example of the memory address of the account data and the alignment of the zero_copy::ZcBug type when it fails?

Related: https://github.com/coral-xyz/anchor/issues/2614

diyahir commented 5 months ago

Running into this issue now, and i'm not able to successfully move forward using --target x86_64-apple-darwin to fix the issue but it still persists

adding .cargo.config.toml

[build]
target = "x86_64-apple-darwin"

also does not fix the issue, any suggestions?

diyahir commented 5 months ago

This is actually not related to M1,2,3 arm chips at all, i tried it on my intel machine and confirmed the same behavior

I'm using Anchor 0.30.0 and solana-program 1.18.11

you can create a new anchor program, and then add this to the program

#[account(zero_copy)]
#[repr(C)]
pub struct ZeroCopyWithError {
    pub var1: u64,  // 8 bytes
    pub var2: u128, // 16 bytes
}

You will encounter this error:

cannot transmute between types of different sizes, or dependently-sized types
source type: `ZeroCopyWithError` (256 bits)
target type: `TypeWithoutPadding` (192 bits)rustc[Click for full compiler diagnostic](rust-analyzer-diagnostics-view:/diagnostic%20message%20%5B0%5D?0#file%3A%2F%2F%2FUsers%2Fdiyahircampos%2FFiles%2FGithub%2Ftic-tac-toe%2Fprograms%2Ftic-tac-toe%2Fsrc%2Flib.rs)
acheroncrypto commented 5 months ago

@diyahir The error you're getting is not related to the error mentioned in this issue, and it's expected. Check out https://github.com/coral-xyz/anchor/issues/2759#issuecomment-1874845771 to learn why you run into that error and how to fix it.