Skip to content

Commit 886db10

Browse files
authored
chore: vendor core bridge (#3629)
* go * clean * clippy * fmt * don't edit lockfile when clippy * clean * undo this
1 parent 3564fb5 commit 886db10

59 files changed

Lines changed: 5960 additions & 8 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

target_chains/solana/Anchor.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
members = [
33
"programs/pyth-push-oracle",
44
"programs/pyth-solana-receiver",
5+
"programs/core-bridge",
56
]
67

78
[features]

target_chains/solana/Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

target_chains/solana/Cargo.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[workspace]
22
members = ["programs/*", "cli/", "program_simulator/", "common_test_utils"]
3-
43
exclude = [
54
"programs/pyth-price-store",
65
"pyth_solana_receiver_sdk",
@@ -16,11 +15,19 @@ incremental = false
1615
codegen-units = 1
1716

1817
[workspace.dependencies]
19-
wormhole-core-bridge-solana = { git = "https://github.com/wormhole-foundation/wormhole", rev = "7bd40b595e22c5512dfaa2ed8e6d7441df743a69" }
18+
wormhole-core-bridge-solana = { path = "./programs/core-bridge" }
2019
wormhole-vaas-serde = "0.1.0"
20+
wormhole-raw-vaas = { version = "0.1.3", features = [
21+
"ruint",
22+
"on-chain",
23+
], default-features = false }
2124
serde_wormhole = "0.1.0"
2225
anchor-lang = "0.28.0"
2326
anchor-client = "0.28.0"
27+
wormhole-io = "0.1.0"
28+
cfg-if = "1.0"
29+
hex = "0.4.3"
30+
ruint = "1.9.0"
2431
solana-program = "1.16.20"
2532
solana-program-test = "1.16.20"
2633
solana-sdk = "1.16.20"

target_chains/solana/cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ wormhole-solana = { git = "https://github.com/guibescos/wormhole", branch = "rei
1616
pythnet-sdk = { path = "../../../pythnet/pythnet_sdk", version = "2.0.0" }
1717
wormhole-vaas-serde = { workspace = true }
1818
serde_wormhole = { workspace = true }
19-
hex = "0.4.3"
19+
hex = { workspace = true }
2020
borsh = "0.9.3" # Old version of borsh needed for wormhole-solana
2121
wormhole-core-bridge-solana = { workspace = true }
2222
pyth-solana-receiver-sdk = "0.6.1" # This is the highest version of pyth-solana-receiver-sdk that is compatible with the anchor-lang version used in the contract (0.28.0)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[package]
2+
name = "wormhole-core-bridge-solana"
3+
description = "Wormhole Core Bridge Program for Solana"
4+
version = "0.0.1-alpha.5"
5+
edition = "2021"
6+
authors = ["Wormhole Contributors"]
7+
license = "Apache-2.0"
8+
homepage = "https://wormhole.com"
9+
repository = "https://github.com/wormhole-foundation/wormhole"
10+
11+
[lib]
12+
crate-type = ["cdylib", "lib"]
13+
14+
[features]
15+
default = ["mainnet", "cpi", "no-idl"]
16+
anchor-debug = []
17+
no-entrypoint = []
18+
no-idl = []
19+
no-log-ix-name = []
20+
cpi = ["no-entrypoint"]
21+
### A.K.A. Local Validator (via JS Integration Test) and Tilt
22+
localnet = []
23+
### A.K.A. Solana Mainnet-Beta
24+
mainnet = []
25+
### A.K.A. Solana Devnet
26+
testnet = []
27+
28+
[dependencies]
29+
wormhole-io.workspace = true
30+
wormhole-raw-vaas.workspace = true
31+
anchor-lang = { workspace = true, features = ["init-if-needed", "derive"] }
32+
solana-program.workspace = true
33+
hex.workspace = true
34+
ruint.workspace = true
35+
cfg-if.workspace = true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[target.bpfel-unknown-unknown.dependencies.std]
2+
features = []
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//! Constants used by the Core Bridge Program. For integrators, necessary constants are re-exported
2+
//! in the [sdk](crate::sdk) module.
3+
4+
use anchor_lang::prelude::constant;
5+
6+
/// Wormhole Chain (Network) ID for Solana.
7+
#[constant]
8+
pub const SOLANA_CHAIN: u16 = 1;
9+
10+
/// Seed for fee collector (Core Bridge's system account).
11+
#[constant]
12+
pub const FEE_COLLECTOR_SEED_PREFIX: &[u8] = b"fee_collector";
13+
14+
#[constant]
15+
/// Seed for upgrade authority.
16+
pub const UPGRADE_SEED_PREFIX: &[u8] = b"upgrade";
17+
18+
/// Seed for program emitters.
19+
#[constant]
20+
pub const PROGRAM_EMITTER_SEED_PREFIX: &[u8] = b"emitter";
21+
22+
/// The max payload size allowed for outbound messages is 30KB. Any messages outbound larger than
23+
/// this size will be disallowed.
24+
#[constant]
25+
pub const MAX_MESSAGE_PAYLOAD_SIZE: usize = 30 * 1_024;
26+
27+
pub(crate) const GOVERNANCE_CHAIN: u16 = 1;
28+
29+
pub(crate) const GOVERNANCE_EMITTER: [u8; 32] = [
30+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
31+
];
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
//! Errors that may arise when interacting with the Core Bridge Program.
2+
3+
use anchor_lang::prelude::error_code;
4+
5+
/// Errors relevant to Core Bridge's malfunction.
6+
///
7+
/// * \>= 0x0 -- General program related.
8+
/// * \>= 0x10 -- General Core Bridge.
9+
/// * \>= 0x20 -- General Core Bridge Governance.
10+
/// * \>= 0x100 -- Legacy Post Message.
11+
/// * \>= 0x200 -- Legacy Post VAA.
12+
/// * \>= 0x300 -- Legacy Set Message Fee.
13+
/// * \>= 0x400 -- Legacy Transfer Fees.
14+
/// * \>= 0x500 -- Legacy Upgrade Contract.
15+
/// * \>= 0x600 -- Legacy Guardian Set Update.
16+
/// * \>= 0x700 -- Legacy Verify Signatures.
17+
/// * \>= 0x800 -- Legacy Post Message Unreliable.
18+
/// * \>= 0x1000 -- Core Bridge Anchor Instruction.
19+
/// * \>= 0x2000 -- Core Bridge SDK.
20+
///
21+
/// NOTE: All of these error codes when triggered are offset by `ERROR_CODE_OFFSET` (6000). So for
22+
/// example, `U64Overflow` will return as 6006.
23+
#[error_code]
24+
pub enum CoreBridgeError {
25+
#[msg("InvalidInstructionArgument")]
26+
InvalidInstructionArgument = 0x2,
27+
28+
#[msg("AccountNotZeroed")]
29+
AccountNotZeroed = 0x3,
30+
31+
#[msg("InvalidDataConversion")]
32+
InvalidDataConversion = 0x4,
33+
34+
#[msg("U64Overflow")]
35+
U64Overflow = 0x6,
36+
37+
#[msg("InvalidComputeSize")]
38+
InvalidComputeSize = 0x8,
39+
40+
#[msg("InvalidChain")]
41+
InvalidChain = 0x10,
42+
43+
#[msg("InvalidGovernanceEmitter")]
44+
InvalidGovernanceEmitter = 0x20,
45+
46+
#[msg("InvalidGovernanceAction")]
47+
InvalidGovernanceAction = 0x22,
48+
49+
#[msg("LatestGuardianSetRequired")]
50+
LatestGuardianSetRequired = 0x24,
51+
52+
#[msg("GovernanceForAnotherChain")]
53+
GovernanceForAnotherChain = 0x26,
54+
55+
#[msg("InvalidGovernanceVaa")]
56+
InvalidGovernanceVaa = 0x28,
57+
58+
#[msg("InsufficientFees")]
59+
InsufficientFees = 0x100,
60+
61+
#[msg("EmitterMismatch")]
62+
EmitterMismatch = 0x102,
63+
64+
#[msg("NotReadyForPublishing")]
65+
NotReadyForPublishing = 0x104,
66+
67+
#[msg("InvalidPreparedMessage")]
68+
InvalidPreparedMessage = 0x106,
69+
70+
#[msg("ExecutableEmitter")]
71+
ExecutableEmitter = 0x108,
72+
73+
#[msg("LegacyEmitter")]
74+
LegacyEmitter = 0x10a,
75+
76+
#[msg("InvalidSignatureSet")]
77+
InvalidSignatureSet = 0x200,
78+
79+
#[msg("InvalidMessageHash")]
80+
InvalidMessageHash = 0x202,
81+
82+
#[msg("NoQuorum")]
83+
NoQuorum,
84+
85+
#[msg("MessageMismatch")]
86+
MessageMismatch = 0x204,
87+
88+
#[msg("NotEnoughLamports")]
89+
NotEnoughLamports = 0x400,
90+
91+
#[msg("InvalidFeeRecipient")]
92+
InvalidFeeRecipient = 0x402,
93+
94+
#[msg("ImplementationMismatch")]
95+
ImplementationMismatch = 0x500,
96+
97+
#[msg("InvalidGuardianSetIndex")]
98+
InvalidGuardianSetIndex = 0x600,
99+
100+
#[msg("GuardianSetMismatch")]
101+
GuardianSetMismatch = 0x700,
102+
103+
#[msg("InstructionAtWrongIndex")]
104+
InstructionAtWrongIndex = 0x702,
105+
106+
#[msg("EmptySigVerifyInstruction")]
107+
EmptySigVerifyInstruction = 0x703,
108+
109+
#[msg("InvalidSigVerifyInstruction")]
110+
InvalidSigVerifyInstruction = 0x704,
111+
112+
#[msg("GuardianSetExpired")]
113+
GuardianSetExpired = 0x706,
114+
115+
#[msg("InvalidGuardianKeyRecovery")]
116+
InvalidGuardianKeyRecovery = 0x708,
117+
118+
#[msg("SignerIndicesMismatch")]
119+
SignerIndicesMismatch = 0x70a,
120+
121+
#[msg("PayloadSizeMismatch")]
122+
PayloadSizeMismatch = 0x800,
123+
124+
#[msg("ZeroGuardians")]
125+
ZeroGuardians = 0x1010,
126+
127+
#[msg("GuardianZeroAddress")]
128+
GuardianZeroAddress = 0x1020,
129+
130+
#[msg("DuplicateGuardianAddress")]
131+
DuplicateGuardianAddress = 0x1030,
132+
133+
#[msg("MessageAlreadyPublished")]
134+
MessageAlreadyPublished = 0x1040,
135+
136+
#[msg("VaaWritingDisallowed")]
137+
VaaWritingDisallowed = 0x1050,
138+
139+
#[msg("VaaAlreadyVerified")]
140+
VaaAlreadyVerified = 0x1060,
141+
142+
#[msg("InvalidGuardianIndex")]
143+
InvalidGuardianIndex = 0x1070,
144+
145+
#[msg("InvalidSignature")]
146+
InvalidSignature = 0x1080,
147+
148+
#[msg("UnverifiedVaa")]
149+
UnverifiedVaa = 0x10a0,
150+
151+
#[msg("VaaStillProcessing")]
152+
VaaStillProcessing = 0x10a2,
153+
154+
#[msg("InWritingStatus")]
155+
InWritingStatus = 0x10a4,
156+
157+
#[msg("NotInWritingStatus")]
158+
NotInWritingStatus = 0x10a6,
159+
160+
#[msg("InvalidMessageStatus")]
161+
InvalidMessageStatus = 0x10a8,
162+
163+
#[msg("HashNotComputed")]
164+
HashNotComputed = 0x10aa,
165+
166+
#[msg("InvalidVaaVersion")]
167+
InvalidVaaVersion = 0x10ac,
168+
169+
#[msg("InvalidCreatedAccountSize")]
170+
InvalidCreatedAccountSize = 0x10ae,
171+
172+
#[msg("DataOverflow")]
173+
DataOverflow = 0x10b0,
174+
175+
#[msg("ExceedsMaxPayloadSize (30KB)")]
176+
ExceedsMaxPayloadSize = 0x10b2,
177+
178+
#[msg("CannotParseVaa")]
179+
CannotParseVaa = 0x10b4,
180+
181+
#[msg("EmitterAuthorityMismatch")]
182+
EmitterAuthorityMismatch = 0x10b6,
183+
184+
#[msg("InvalidProgramEmitter")]
185+
InvalidProgramEmitter = 0x10b8,
186+
187+
#[msg("WriteAuthorityMismatch")]
188+
WriteAuthorityMismatch = 0x10ba,
189+
190+
#[msg("PostedVaaPayloadTooLarge")]
191+
PostedVaaPayloadTooLarge = 0x10bc,
192+
193+
#[msg("ExecutableDisallowed")]
194+
ExecutableDisallowed = 0x10be,
195+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//! A set of structs mirroring the structs deriving [Accounts](anchor_lang::prelude::Accounts),
2+
//! where each field is a [Pubkey]. This is useful for specifying self for a client.
3+
//!
4+
//! NOTE: This is similar to how [accounts](mod@crate::accounts) is generated via Anchor's
5+
//! [program][anchor_lang::prelude::program] macro.
6+
7+
use anchor_lang::{prelude::Pubkey, ToAccountMetas};
8+
use solana_program::instruction::AccountMeta;
9+
10+
/// Context to post a new Core Bridge message.
11+
pub struct PostMessage {
12+
pub config: Pubkey,
13+
pub message: Pubkey,
14+
pub emitter: Option<Pubkey>,
15+
pub emitter_sequence: Pubkey,
16+
pub payer: Pubkey,
17+
pub fee_collector: Option<Pubkey>,
18+
pub system_program: Pubkey,
19+
}
20+
21+
impl ToAccountMetas for PostMessage {
22+
fn to_account_metas(&self, message_is_signer: Option<bool>) -> Vec<AccountMeta> {
23+
// Using `message_is_signer` above is a hack. But because we do not want to return a result,
24+
// we assume that the caller of this is passing in whether a message is a signer, which is
25+
// the case when a new message account is created when someone invokes this instruction.
26+
// Otherwise the message was already prepared so it does not have to be a signer.
27+
28+
// If the emitter is None, we do not require it to be a signer.
29+
let (emitter, emitter_is_signer) = match self.emitter {
30+
Some(emitter) => (emitter, true),
31+
None => (crate::ID, false),
32+
};
33+
34+
vec![
35+
AccountMeta::new_readonly(self.config, false),
36+
AccountMeta::new(self.message, message_is_signer.unwrap_or(true)),
37+
AccountMeta::new_readonly(emitter, emitter_is_signer),
38+
AccountMeta::new(self.emitter_sequence, false),
39+
AccountMeta::new(self.payer, true),
40+
AccountMeta::new(self.fee_collector.unwrap_or(crate::ID), false),
41+
AccountMeta::new_readonly(crate::ID, false), // _clock
42+
AccountMeta::new_readonly(self.system_program, false),
43+
]
44+
}
45+
}
46+
47+
/// Context to post a new or reuse an existing Core Bridge message.
48+
pub struct PostMessageUnreliable {
49+
pub config: Pubkey,
50+
pub message: Pubkey,
51+
pub emitter: Pubkey,
52+
pub emitter_sequence: Pubkey,
53+
pub payer: Pubkey,
54+
pub fee_collector: Option<Pubkey>,
55+
pub system_program: Pubkey,
56+
}
57+
58+
impl ToAccountMetas for PostMessageUnreliable {
59+
fn to_account_metas(&self, _is_signer: Option<bool>) -> Vec<AccountMeta> {
60+
vec![
61+
AccountMeta::new_readonly(self.config, false),
62+
AccountMeta::new(self.message, true),
63+
AccountMeta::new_readonly(self.emitter, true),
64+
AccountMeta::new(self.emitter_sequence, false),
65+
AccountMeta::new(self.payer, true),
66+
AccountMeta::new(self.fee_collector.unwrap_or(crate::ID), false),
67+
AccountMeta::new_readonly(crate::ID, false), // _clock
68+
AccountMeta::new_readonly(self.system_program, false),
69+
]
70+
}
71+
}

0 commit comments

Comments
 (0)