Core Contract (Solana)#
The Wormhole Core Program on Solana is a native Solana program responsible for posting, verifying, and relaying Wormhole messages (VAAs). It implements core messaging functionality, Guardian set updates, and upgradeability.
Structure Overview#
The Wormhole Core program on Solana is implemented using modular Rust files. Logic is separated across instruction dispatch, account definitions, core types, and signature verification.
lib.rs
├── instructions.rs
├── accounts.rs
├── api.rs
│ ├── post_message
│ ├── verify_signatures
│ ├── post_vaa
│ ├── upgrade_contract
│ └── upgrade_guardian_set
├── types.rs
└── vaa.rs
Key Components:
- lib.rs: Program entry point and instruction dispatcher. Registers all handlers and exposes the on-chain processor.
- instructions.rs: Defines the
WormholeInstruction
enum and maps it to individual instruction handlers. - accounts.rs: Specifies the account constraints and validation logic for each instruction.
- api.rs: Contains the main logic for processing instructions such as message posting, VAA verification, upgrades, and governance actions.
- types.rs: Defines shared structs and enums used throughout the program, including configuration and
GuardianSet
formats. - vaa.rs: Implements VAA parsing, hashing, and signature-related logic used to verify Wormhole messages.
- error.rs (not listed above): Defines custom error types used across the program for precise failure handling.
- wasm.rs (not listed above): Provides WebAssembly bindings for testing and external tooling; not used on-chain.
State Accounts#
Below are on-chain PDAs used to store persistent state for the core contract. All are derived using deterministic seeds with the program ID.
bridge
BridgeData: Stores global config like the active Guardian set index, message fee, and Guardian set expiration time. (Derived at PDA seed["Bridge"]
)guardianSets
GuardianSetData: Mapping of Guardian sets by index. Each Guardian set includes public key hashes and creation/expiration times. (Derived at PDA seed["GuardianSet", index]
)sequences
SequenceTracker: Tracks the last sequence number used by each emitter, enforcing strict message ordering. (Derived at PDA seed["Sequence", emitter]
)postedVAAs
PostedVAAData: Stores verified and finalized VAAs, preventing replay. (Derived at PDA seed["PostedVAA", hash]
)claims
ClaimData: Tracks consumed governance VAAs to ensure replay protection. (Derived at PDA seed["Claim", emitter, sequence]
)feeCollector
FeeCollector: Holds lamports collected via message fees, and can be drained via governance. (Derived at PDA seed["fee_collector"]
)
Instructions#
initialize#
Initializes the Wormhole Core contract on Solana with a Guardian set and fee configuration. This should be called only once at deployment time. (Defined in api/initialize.rs)
initialize(
payer: Pubkey,
fee: u64,
guardian_set_expiration_time: u32,
initial_guardians: &[[u8; 20]]
)
Accounts
Bridge
: PDA to store global configuration.GuardianSet
: PDA for Guardian set at index 0.FeeCollector
: PDA to collect message posting fees.Payer
: Funds account creation.Clock
,Rent
,SystemProgram
: Solana system accounts.
Parameters
fee
u64
Fee in lamports required to post messages.
guardian_set_expiration_time
u32
Time in seconds after which the Guardian set expires.
initial_guardians
[[u8; 20]]
List of Guardian public key hashes (Ethereum-style addresses).
post_message#
Posts a Wormhole message to the Solana Core contract. (Defined in api/post_message.rs)
Accounts
Bridge
: PDA for global config.Message
: PDA where the posted message will be stored.Emitter
: The emitting account (must sign).Sequence
: PDA tracking the emitter’s message sequence.Payer
: Pays for account creation and fees.FeeCollector
: PDA that collects message fees.Clock
,Rent
,SystemProgram
: Solana system accounts.
Parameters
nonce
u32
Unique nonce to disambiguate messages with the same payload.
payload
Vec<u8>
The arbitrary message payload to be posted.
consistency_level
u8
Level of finality required before the message is processed.
1
= Confirmed, 32
= Finalized.
post_message_unreliable#
Posts a Wormhole message without requiring reliable delivery. Used for lightweight publishing when finality isn't critical. (Defined in api/post_message.rs)
Accounts
Bridge
: PDA for global config.Message
: PDA where the posted message will be stored.Emitter
: The emitting account (must sign).Sequence
: PDA tracking the emitter’s message sequence.Payer
: Pays for account creation and fees.FeeCollector
: PDA that collects message fees.Clock
,Rent
,SystemProgram
: Solana system accounts.
Parameters
nonce
u32
Unique nonce to disambiguate messages with the same payload.
payload
Vec<u8>
The arbitrary message payload to be posted.
consistency_level
u8
Level of finality required before the message is processed. 1
= Confirmed, 32
= Finalized.
verify_signatures#
Verifies Guardian signatures over a VAA body hash. This is the first step in VAA processing and is required before posting the VAA. (Defined in api/verify_signature.rs)
Accounts
Payer
: Pays for account creation and fees.GuardianSet
: PDA holding the current Guardian set.SignatureSet
: PDA that will store the verified signature data.InstructionsSysvar
: Required to access prior instructions (e.g., secp256k1 sigverify).Rent
,SystemProgram
: Solana system accounts.
Parameters
signers
[i8; 19]
A mapping from Guardian index to its position in the instruction payload (or -1 if not present).
Used to correlate secp256k1 verify instructions with Guardian set entries.
post_vaa#
Finalizes a VAA after signature verification. This stores the message on-chain and marks it as consumed. (Defined in api/post_vaa.rs)
PostVAA {
version: u8,
guardian_set_index: u32,
timestamp: u32,
nonce: u32,
emitter_chain: u16,
emitter_address: [u8; 32],
sequence: u64,
consistency_level: u8,
payload: Vec<u8>
}
Accounts
GuardianSet
: PDA of the Guardian set used to verify the VAA.Bridge
: Global Wormhole state.SignatureSet
: Verified signature PDA (from verify_signatures).PostedVAA
: PDA where the VAA will be stored.Payer
: Funds the account creation.Clock
,Rent
,SystemProgram
: Solana system accounts.
Parameters
version
u8
VAA protocol version.
guardian_set_index
u32
Index of the Guardian Set that signed this VAA.
timestamp
u32
The time the emitter submitted the message.
nonce
u32
Unique identifier for the message.
emitter_chain
u16
ID of the chain where the message originated.
emitter_address
[u8; 32]
Address of the contract or account that emitted the message.
sequence
u64
Monotonically increasing sequence number for the emitter.
consistency_level
u8
Required confirmation level before the message is accepted.
1
= Confirmed, 32
= Finalized.
payload
Vec<u8>
Arbitrary data being transferred in the message.
set_fees#
Updates the message posting fee for the core bridge contract. (Defined in api/governance.rs)
This function is called via governance and requires a valid governance VAA. The VAA payload must contain the new fee value.
Accounts
Payer
: Funds transaction execution.Bridge
: PDA storing global Wormhole state.Message
: The PostedVAA account containing the governance message.Claim
: PDA that ensures this governance message hasn't been processed already.SystemProgram
: Required by Solana for creating/initializing accounts.
transfer_fees#
Transfers the accumulated message posting fees from the contract to a specified recipient. (Defined in api/governance.rs)
This function is triggered via a governance VAA and transfers the fee balance from the FeeCollector
to the recipient address specified in the VAA payload.
Accounts
Payer
: Funds transaction execution.Bridge
: PDA storing global Wormhole state.Message
: PostedVAA account containing the governance message.FeeCollector
: PDA holding the accumulated fees.Recipient
: The account that will receive the fees.Claim
: PDA that ensures this governance message hasn't been processed already.Rent
,SystemProgram
: Standard Solana system accounts.
upgrade_contract#
Upgrades the deployed Wormhole program using a governance VAA. (Defined in api/governance.rs)
This instruction allows authorized governance messages to trigger an upgrade of the on-chain Wormhole program logic to a new address.
Accounts
Payer
: Funds transaction execution.Bridge
: PDA storing global Wormhole state.Message
: PostedVAA account containing the governance message.Claim
: PDA that ensures this governance message hasn't been processed already.UpgradeAuthority
: PDA with authority to perform the upgrade (seeded with "upgrade").Spill
: Account that receives remaining funds from the upgrade buffer.NewContract
: Account holding the new program data.ProgramData
: Metadata account for the upgradable program.Program
: Current program to be upgraded.Rent
,Clock
: System accounts used during the upgrade process.BPFLoaderUpgradeable
: Solana system program for upgrades.SystemProgram
: Required by Solana for creating/initializing accounts.
upgrade_guardian_set#
Upgrades the current Guardian set using a governance VAA. (Defined in api/governance.rs)
This instruction replaces the active Guardian set with a new one, allowing the Wormhole network to rotate its validator keys securely through governance.
Accounts
Payer
: Funds transaction execution.Bridge
: PDA storing global Wormhole state.Message
: PostedVAA account containing the governance message.Claim
: PDA that ensures this governance message hasn't been processed already.GuardianSetOld
: Current (active) Guardian set PDA.GuardianSetNew
: PDA for the newly proposed Guardian set.SystemProgram
: Standard Solana system accounts.
Errors#
GuardianSetMismatch#
The Guardian set index does not match the expected value. (Defined in error.rs)
InstructionAtWrongIndex#
The instruction was found at the wrong index. (Defined in error.rs)
InsufficientFees#
Insufficient fees were provided to post the message. (Defined in error.rs)
InvalidFeeRecipient#
The recipient address does not match the one specified in the governance VAA. (Defined in error.rs)
InvalidGovernanceAction#
The action specified in the governance payload is invalid. (Defined in error.rs)
InvalidGovernanceChain#
The governance VAA was not emitted by a valid governance chain. (Defined in error.rs)
InvalidGovernanceKey#
The emitter address in the governance VAA is not the expected governance key. (Defined in error.rs)
InvalidGovernanceModule#
The module string in the governance VAA header is invalid. (Defined in error.rs)
InvalidGovernanceWithdrawal#
Fee withdrawal would cause the fee collector account to drop below rent-exempt balance. (Defined in error.rs)
InvalidGuardianSetUpgrade#
The Guardian set upgrade VAA is invalid (e.g., skipped index or mismatched current index). (Defined in error.rs)
InvalidHash#
The hash computed from the VAA does not match the expected result. (Defined in error.rs)
InvalidSecpInstruction#
The SECP256k1 instruction used for signature verification is malformed. (Defined in error.rs)
MathOverflow#
An arithmetic overflow occurred during computation. (Defined in error.rs)
PostVAAConsensusFailed#
Not enough valid signatures were collected to achieve quorum. (Defined in error.rs)
PostVAAGuardianSetExpired#
The Guardian set used to verify the VAA has already expired. (Defined in error.rs)
TooManyGuardians#
The Guardian set exceeds the maximum allowed number of guardians. (Defined in error.rs)
VAAAlreadyExecuted#
The VAA has already been executed and cannot be processed again. (Defined in error.rs)
VAAInvalid#
The VAA is structurally invalid or fails to decode. (Defined in error.rs)
InvalidPayloadLength#
The payload length is incorrect or malformed. (Defined in error.rs)
EmitterChanged#
The emitter address changed unexpectedly. (Defined in error.rs)