Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only compile wasm-bindgen when target_arch = "wasm32" #1658

Merged
merged 10 commits into from
Jun 18, 2024
2 changes: 1 addition & 1 deletion sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ solana-program = { workspace = true }
solana-sdk-macro = { workspace = true }
thiserror = { workspace = true }
uriparse = { workspace = true }
wasm-bindgen = { workspace = true }

[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.1", features = ["wasm-bindgen"] }
js-sys = { workspace = true }
wasm-bindgen = { workspace = true }

[dev-dependencies]
anyhow = { workspace = true }
Expand Down
28 changes: 0 additions & 28 deletions sdk/macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,34 +378,6 @@ pub fn pubkeys(input: TokenStream) -> TokenStream {
TokenStream::from(quote! {#pubkeys})
}

// The normal `wasm_bindgen` macro generates a .bss section which causes the resulting
// SBF program to fail to load, so for now this stub should be used when building for SBF
#[proc_macro_attribute]
pub fn wasm_bindgen_stub(_attr: TokenStream, item: TokenStream) -> TokenStream {
match parse_macro_input!(item as syn::Item) {
syn::Item::Struct(mut item_struct) => {
if let syn::Fields::Named(fields) = &mut item_struct.fields {
// Strip out any `#[wasm_bindgen]` added to struct fields. This is custom
// syntax supplied by the normal `wasm_bindgen` macro.
for field in fields.named.iter_mut() {
field.attrs.retain(|attr| {
!attr
.path()
.segments
.iter()
.any(|segment| segment.ident == "wasm_bindgen")
});
}
}
quote! { #item_struct }
}
item => {
quote!(#item)
}
}
.into()
}

// Sets padding in structures to zero explicitly.
// Otherwise padding could be inconsistent across the network and lead to divergence / consensus failures.
#[proc_macro_derive(CloneZeroed)]
Expand Down
2 changes: 1 addition & 1 deletion sdk/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ itertools = { workspace = true }
libsecp256k1 = { workspace = true }
num-bigint = { workspace = true }
rand = { workspace = true }
wasm-bindgen = { workspace = true }

[target.'cfg(not(target_os = "solana"))'.dev-dependencies]
arbitrary = { workspace = true, features = ["derive"] }
Expand All @@ -69,6 +68,7 @@ console_error_panic_hook = { workspace = true }
console_log = { workspace = true }
getrandom = { workspace = true, features = ["js", "wasm-bindgen"] }
js-sys = { workspace = true }
wasm-bindgen = { workspace = true }

[target.'cfg(not(target_pointer_width = "64"))'.dependencies]
parking_lot = { workspace = true }
Expand Down
6 changes: 4 additions & 2 deletions sdk/program/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
//! [SHA-256]: https://en.wikipedia.org/wiki/SHA-2
//! [`Hash`]: struct@Hash

#[cfg(target_arch = "wasm32")]
use crate::wasm_bindgen;
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use {
crate::{sanitize::Sanitize, wasm_bindgen},
crate::sanitize::Sanitize,
bytemuck::{Pod, Zeroable},
sha2::{Digest, Sha256},
std::{convert::TryFrom, fmt, mem, str::FromStr},
Expand All @@ -28,7 +30,7 @@ const MAX_BASE58_LEN: usize = 44;
/// [blake3]: https://github.com/BLAKE3-team/BLAKE3
/// [`blake3`]: crate::blake3
/// [`Message::hash`]: crate::message::Message::hash
#[wasm_bindgen]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
#[cfg_attr(
feature = "borsh",
Expand Down
21 changes: 17 additions & 4 deletions sdk/program/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@

#![allow(clippy::arithmetic_side_effects)]

#[cfg(target_arch = "wasm32")]
use crate::wasm_bindgen;
#[cfg(feature = "borsh")]
use borsh::BorshSerialize;
use {
crate::{pubkey::Pubkey, sanitize::Sanitize, short_vec, wasm_bindgen},
crate::{pubkey::Pubkey, sanitize::Sanitize, short_vec},
bincode::serialize,
serde::Serialize,
thiserror::Error,
Expand Down Expand Up @@ -325,16 +327,27 @@ pub enum InstructionError {
/// Programs may require signatures from some accounts, in which case they
/// should be specified as signers during `Instruction` construction. The
/// program must still validate during execution that the account is a signer.
#[wasm_bindgen]
#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct Instruction {
/// Pubkey of the program that executes this instruction.
#[wasm_bindgen(skip)]
pub program_id: Pubkey,
/// Metadata describing accounts that should be passed to the program.
#[wasm_bindgen(skip)]
pub accounts: Vec<AccountMeta>,
/// Opaque data passed to the program for its own interpretation.
pub data: Vec<u8>,
}

/// wasm-bindgen version of the Instruction struct.
/// This duplication is required until https://github.com/rustwasm/wasm-bindgen/issues/3671
/// is fixed. This must not diverge from the regular non-wasm Instruction struct.
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub struct Instruction {
#[wasm_bindgen(skip)]
pub program_id: Pubkey,
#[wasm_bindgen(skip)]
pub accounts: Vec<AccountMeta>,
kevinheavey marked this conversation as resolved.
Show resolved Hide resolved
#[wasm_bindgen(skip)]
pub data: Vec<u8>,
}
Expand Down
7 changes: 1 addition & 6 deletions sdk/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,12 +545,7 @@ pub mod address_lookup_table_account {
pub use crate::address_lookup_table::AddressLookupTableAccount;
}

#[cfg(target_os = "solana")]
pub use solana_sdk_macro::wasm_bindgen_stub as wasm_bindgen;
/// Re-export of [wasm-bindgen].
///
/// [wasm-bindgen]: https://rustwasm.github.io/docs/wasm-bindgen/
#[cfg(not(target_os = "solana"))]
#[cfg(target_arch = "wasm32")]
pub use wasm_bindgen::prelude::wasm_bindgen;

/// The [config native program][np].
Expand Down
35 changes: 31 additions & 4 deletions sdk/program/src/message/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

#![allow(clippy::arithmetic_side_effects)]

#[cfg(target_arch = "wasm32")]
use crate::wasm_bindgen;
#[allow(deprecated)]
pub use builtins::{BUILTIN_PROGRAMS_KEYS, MAYBE_BUILTIN_KEY_OR_SYSVAR};
use {
Expand All @@ -21,7 +23,7 @@ use {
message::{compiled_keys::CompiledKeys, MessageHeader},
pubkey::Pubkey,
sanitize::{Sanitize, SanitizeError},
short_vec, system_instruction, system_program, sysvar, wasm_bindgen,
short_vec, system_instruction, system_program, sysvar,
},
std::{collections::HashSet, convert::TryFrom, str::FromStr},
};
Expand Down Expand Up @@ -117,7 +119,7 @@ fn compile_instructions(ixs: &[Instruction], keys: &[Pubkey]) -> Vec<CompiledIns
/// redundantly specifying the fee-payer is not strictly required.
// NOTE: Serialization-related changes must be paired with the custom serialization
// for versioned messages in the `RemainingLegacyMessage` struct.
#[wasm_bindgen]
#[cfg(not(target_arch = "wasm32"))]
#[cfg_attr(
feature = "frozen-abi",
frozen_abi(digest = "2KnLEqfLcTBQqitE22Pp8JYkaqVVbAkGbCfdeHoyxcAU"),
Expand All @@ -128,11 +130,9 @@ fn compile_instructions(ixs: &[Instruction], keys: &[Pubkey]) -> Vec<CompiledIns
pub struct Message {
/// The message header, identifying signed and read-only `account_keys`.
// NOTE: Serialization-related changes must be paired with the direct read at sigverify.
#[wasm_bindgen(skip)]
pub header: MessageHeader,

/// All the account keys used by this transaction.
#[wasm_bindgen(skip)]
#[serde(with = "short_vec")]
pub account_keys: Vec<Pubkey>,

Expand All @@ -141,6 +141,33 @@ pub struct Message {

/// Programs that will be executed in sequence and committed in one atomic transaction if all
/// succeed.
#[serde(with = "short_vec")]
pub instructions: Vec<CompiledInstruction>,
}

/// wasm-bindgen version of the Message struct.
/// This duplication is required until https://github.com/rustwasm/wasm-bindgen/issues/3671
/// is fixed. This must not diverge from the regular non-wasm Message struct.
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
#[cfg_attr(
feature = "frozen-abi",
frozen_abi(digest = "2KnLEqfLcTBQqitE22Pp8JYkaqVVbAkGbCfdeHoyxcAU"),
derive(AbiExample)
)]
#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Message {
#[wasm_bindgen(skip)]
pub header: MessageHeader,

#[wasm_bindgen(skip)]
#[serde(with = "short_vec")]
pub account_keys: Vec<Pubkey>,

/// The id of a recent ledger entry.
pub recent_blockhash: Hash,

kevinheavey marked this conversation as resolved.
Show resolved Hide resolved
#[wasm_bindgen(skip)]
#[serde(with = "short_vec")]
pub instructions: Vec<CompiledInstruction>,
Expand Down
6 changes: 4 additions & 2 deletions sdk/program/src/pubkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

#![allow(clippy::arithmetic_side_effects)]

#[cfg(target_arch = "wasm32")]
use crate::wasm_bindgen;
#[cfg(test)]
use arbitrary::Arbitrary;
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use {
crate::{decode_error::DecodeError, hash::hashv, wasm_bindgen},
crate::{decode_error::DecodeError, hash::hashv},
bytemuck::{Pod, Zeroable},
num_derive::{FromPrimitive, ToPrimitive},
std::{
Expand Down Expand Up @@ -68,7 +70,7 @@ impl From<u64> for PubkeyError {
/// [ed25519]: https://ed25519.cr.yp.to/
/// [pdas]: https://solana.com/docs/core/cpi#program-derived-addresses
/// [`Keypair`]: https://docs.rs/solana-sdk/latest/solana_sdk/signer/keypair/struct.Keypair.html
#[wasm_bindgen]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
#[repr(transparent)]
#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
#[cfg_attr(
Expand Down
4 changes: 3 additions & 1 deletion sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ pub use signer::signers;
pub use solana_program::program_stubs;
// These solana_program imports could be *-imported, but that causes a bunch of
// confusing duplication in the docs due to a rustdoc bug. #26211
#[cfg(target_arch = "wasm32")]
pub use solana_program::wasm_bindgen;
pub use solana_program::{
account_info, address_lookup_table, alt_bn128, big_mod_exp, blake3, bpf_loader,
bpf_loader_deprecated, bpf_loader_upgradeable, clock, config, custom_heap_default,
Expand All @@ -51,7 +53,7 @@ pub use solana_program::{
program_memory, program_option, program_pack, rent, sanitize, secp256k1_program,
secp256k1_recover, serde_varint, serialize_utils, short_vec, slot_hashes, slot_history,
stable_layout, stake, stake_history, syscalls, system_instruction, system_program, sysvar,
unchecked_div_by_const, vote, wasm_bindgen,
unchecked_div_by_const, vote,
};
#[allow(deprecated)]
pub use solana_program::{address_lookup_table_account, sdk_ids};
Expand Down
5 changes: 3 additions & 2 deletions sdk/src/signer/keypair.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#![cfg(feature = "full")]

#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
use {
crate::{
derivation_path::DerivationPath,
Expand All @@ -16,11 +18,10 @@ use {
io::{Read, Write},
path::Path,
},
wasm_bindgen::prelude::*,
};

/// A vanilla Ed25519 key pair
#[wasm_bindgen]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
#[derive(Debug)]
pub struct Keypair(ed25519_dalek::Keypair);

Expand Down
25 changes: 22 additions & 3 deletions sdk/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@

#![cfg(feature = "full")]

#[cfg(target_arch = "wasm32")]
use crate::wasm_bindgen;
use {
crate::{
hash::Hash,
Expand All @@ -124,7 +126,6 @@ use {
short_vec,
signature::{Signature, SignerError},
signers::Signers,
wasm_bindgen,
},
serde::Serialize,
solana_program::{system_instruction::SystemInstruction, system_program},
Expand Down Expand Up @@ -167,7 +168,7 @@ pub type Result<T> = result::Result<T, TransactionError>;
/// if the caller has knowledge that the first account of the constructed
/// transaction's `Message` is both a signer and the expected fee-payer, then
/// redundantly specifying the fee-payer is not strictly required.
#[wasm_bindgen]
#[cfg(not(target_arch = "wasm32"))]
#[cfg_attr(
feature = "frozen-abi",
derive(AbiExample),
Expand All @@ -184,11 +185,29 @@ pub struct Transaction {
/// [`MessageHeader`]: crate::message::MessageHeader
/// [`num_required_signatures`]: crate::message::MessageHeader::num_required_signatures
// NOTE: Serialization-related changes must be paired with the direct read at sigverify.
#[wasm_bindgen(skip)]
#[serde(with = "short_vec")]
pub signatures: Vec<Signature>,

/// The message to sign.
pub message: Message,
}

/// wasm-bindgen version of the Transaction struct.
/// This duplication is required until https://github.com/rustwasm/wasm-bindgen/issues/3671
/// is fixed. This must not diverge from the regular non-wasm Transaction struct.
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
#[cfg_attr(
feature = "frozen-abi",
derive(AbiExample),
frozen_abi(digest = "FZtncnS1Xk8ghHfKiXE5oGiUbw2wJhmfXQuNgQR3K6Mc")
)]
#[derive(Debug, PartialEq, Default, Eq, Clone, Serialize, Deserialize)]
pub struct Transaction {
#[wasm_bindgen(skip)]
#[serde(with = "short_vec")]
pub signatures: Vec<Signature>,

kevinheavey marked this conversation as resolved.
Show resolved Hide resolved
#[wasm_bindgen(skip)]
pub message: Message,
}
Expand Down
Loading