wip, 0.6.1

This commit is contained in:
Conner Gallagher 2023-06-26 18:58:29 -06:00
parent 48e99d04a8
commit 314a3302d0
12 changed files with 5579 additions and 66 deletions

View File

@ -1980,9 +1980,9 @@ dependencies = [
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.7.2" version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
[[package]] [[package]]
name = "itertools" name = "itertools"
@ -4322,9 +4322,9 @@ checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
[[package]] [[package]]
name = "switchboard-common" name = "switchboard-common"
version = "0.5.3" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfdba3cdca0076ce8db2bd2df851e079bbac393240dc63147de71943c5c5ae81" checksum = "59120b4a1fcc0e72443648f41b8fab8c36f6789c28eb3d5a689e8b111c1a6c13"
dependencies = [ dependencies = [
"getrandom 0.2.10", "getrandom 0.2.10",
"hex", "hex",
@ -4337,7 +4337,9 @@ dependencies = [
[[package]] [[package]]
name = "switchboard-solana" name = "switchboard-solana"
version = "0.6.0" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "262f116e5eb73928e944837e4dbf400360b1241b37d57f038fa0a9db70e1826b"
dependencies = [ dependencies = [
"anchor-client", "anchor-client",
"anchor-lang", "anchor-lang",
@ -4349,6 +4351,7 @@ dependencies = [
"rust_decimal", "rust_decimal",
"sgx-quote", "sgx-quote",
"solana-address-lookup-table-program", "solana-address-lookup-table-program",
"solana-client",
"solana-program", "solana-program",
"superslice", "superslice",
"switchboard-common", "switchboard-common",

View File

@ -18,6 +18,6 @@ default = []
[dependencies] [dependencies]
# anchor-lang = "0.28.0" # anchor-lang = "0.28.0"
# switchboard-solana = "0.5.3" switchboard-solana = "0.6.1"
switchboard-solana = { path = "../../../rust/switchboard-solana" } # switchboard-solana = { version = "0.6", path = "../../../rust/switchboard-solana" }
bytemuck = "^1" bytemuck = "^1"

View File

@ -5,7 +5,7 @@ target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock # Cargo.lock
# These are backup files generated by rustfmt # These are backup files generated by rustfmt
**/*.rs.bk **/*.rs.bk

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@ tokio = "^1"
futures = "0.3" futures = "0.3"
serde = "^1" serde = "^1"
serde_json = "^1" serde_json = "^1"
# switchboard-utils = "0.5.0" switchboard-utils = "0.6"
# switchboard-solana = "0.5.3" # switchboard-utils = { version = "0.6", path = "../../../../../sbv2-core/rust/switchboard-utils" }
switchboard-solana = { path = "../../../../rust/switchboard-solana" } switchboard-solana = "0.6.1"
# switchboard-solana = { version = "0.6", path = "../../../../rust/switchboard-solana" }

View File

@ -2,7 +2,7 @@
use crate::*; use crate::*;
// pub use switchboard_utils::reqwest; pub use switchboard_utils::reqwest;
use serde::Deserialize; use serde::Deserialize;

View File

@ -5,7 +5,7 @@ pub struct RefreshPrices<'info> {
#[account( #[account(
seeds = [PROGRAM_SEED], seeds = [PROGRAM_SEED],
bump = program_state.load()?.bump, bump = program_state.load()?.bump,
// constraint = program.load()?.is_valid_enclave(&quote.load()?.mr_enclave) @ BasicOracleError::InvalidMrEnclave has_one = function @ BasicOracleError::IncorrectSwitchboardFunction,
)] )]
pub program_state: AccountLoader<'info, MyProgramState>, pub program_state: AccountLoader<'info, MyProgramState>,
@ -16,22 +16,20 @@ pub struct RefreshPrices<'info> {
)] )]
pub oracle: AccountLoader<'info, MyOracleState>, pub oracle: AccountLoader<'info, MyOracleState>,
pub function: AccountLoader<'info, FunctionAccountData>, // We use this to derive and verify the functions enclave state
#[account( #[account(
seeds = [QUOTE_SEED, function.key().as_ref()],
bump = quote.load()?.bump,
seeds::program = SWITCHBOARD_ATTESTATION_PROGRAM_ID,
has_one = enclave_signer @ BasicOracleError::InvalidTrustedSigner,
constraint = constraint =
quote.load()?.mr_enclave != [0u8; 32] @ BasicOracleError::EmptySwitchboardQuote FunctionAccountData::validate_enclave(
&function.to_account_info(),
&enclave.to_account_info(),
&enclave_signer.to_account_info()
)?
)] )]
pub quote: AccountLoader<'info, EnclaveAccountData>, pub function: AccountLoader<'info, FunctionAccountData>,
pub enclave: AccountLoader<'info, EnclaveAccountData>,
pub enclave_signer: Signer<'info>, pub enclave_signer: Signer<'info>,
} }
#[derive(Clone, AnchorSerialize, AnchorDeserialize)] #[derive(Clone, AnchorSerialize, AnchorDeserialize)]
pub struct RefreshPricesParams { pub struct RefreshPricesParams {
pub rows: Vec<OracleDataWithTradingSymbol>, pub rows: Vec<OracleDataWithTradingSymbol>,
@ -50,28 +48,6 @@ impl RefreshPrices<'_> {
let oracle = &mut ctx.accounts.oracle.load_mut()?; let oracle = &mut ctx.accounts.oracle.load_mut()?;
oracle.save_rows(&params.rows)?; oracle.save_rows(&params.rows)?;
// for data in params.data
// if let Some(btc) = params.btc {
// oracle.btc = btc;
// }
// if let Some(eth) = params.eth {
// oracle.eth = eth;
// }
// if let Some(sol) = params.sol {
// oracle.sol = sol;
// }
// if let Some(usdt) = params.usdt {
// oracle.usdt = usdt;
// }
// if let Some(usdc) = params.usdc {
// oracle.usdc = usdc;
// }
Ok(()) Ok(())
} }
} }

View File

@ -17,4 +17,8 @@ pub enum BasicOracleError {
EmptySwitchboardQuote, EmptySwitchboardQuote,
#[msg("Failed to find a valid trading symbol for this price")] #[msg("Failed to find a valid trading symbol for this price")]
InvalidSymbol, InvalidSymbol,
#[msg("FunctionAccount pubkey did not match program_state.function")]
IncorrectSwitchboardFunction,
#[msg("FunctionAccount pubkey did not match program_state.function")]
InvalidSwitchboardFunction,
} }

View File

@ -4292,9 +4292,9 @@ checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
[[package]] [[package]]
name = "switchboard-common" name = "switchboard-common"
version = "0.5.3" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfdba3cdca0076ce8db2bd2df851e079bbac393240dc63147de71943c5c5ae81" checksum = "59120b4a1fcc0e72443648f41b8fab8c36f6789c28eb3d5a689e8b111c1a6c13"
dependencies = [ dependencies = [
"getrandom 0.2.10", "getrandom 0.2.10",
"hex", "hex",
@ -4319,6 +4319,7 @@ dependencies = [
"rust_decimal", "rust_decimal",
"sgx-quote", "sgx-quote",
"solana-address-lookup-table-program", "solana-address-lookup-table-program",
"solana-client",
"solana-program", "solana-program",
"superslice", "superslice",
"switchboard-common", "switchboard-common",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "switchboard-solana" name = "switchboard-solana"
version = "0.6.0" version = "0.6.1"
edition = "2021" edition = "2021"
description = "A Rust library to interact with Switchboard accounts." description = "A Rust library to interact with Switchboard accounts."
readme = "README.md" readme = "README.md"
@ -22,19 +22,20 @@ cpi = ["no-entrypoint"]
[dependencies] [dependencies]
anchor-spl = "0.28.0" anchor-spl = "0.28.0"
solana-program = ">= 1.16, < 1.17" solana-program = ">= 1.16.1, < 1.17"
solana-address-lookup-table-program = ">= 1.16, < 1.17" solana-address-lookup-table-program = ">= 1.16.1, < 1.17"
rust_decimal = "^1" rust_decimal = "^1"
bytemuck = "^1" bytemuck = "^1"
superslice = "1" superslice = "1"
[target.'cfg(target_os = "solana")'.dependencies] [target.'cfg(target_os = "solana")'.dependencies]
switchboard-common = { version = "0.5.3" } switchboard-common = { version = "0.6" }
anchor-lang = { version = "0.28.0" } anchor-lang = { version = "0.28.0" }
[target.'cfg(not(target_os = "solana"))'.dependencies] [target.'cfg(not(target_os = "solana"))'.dependencies]
switchboard-common = { version = "0.5.3", features = ["sgx"] } switchboard-common = { version = "0.6", features = ["client"] }
anchor-client = { version = "0.28.0" } anchor-client = { version = "0.28.0" }
solana-client = ">= 1.16.1, < 1.17"
bincode = { version = "^1" } bincode = { version = "^1" }
sgx-quote = { version = "0.1.0" } sgx-quote = { version = "0.1.0" }
cron = { version = "0.12.0" } cron = { version = "0.12.0" }

View File

@ -197,7 +197,7 @@ impl FunctionAccountData {
)) ))
} }
pub fn get_quote_pda(fn_key: &Pubkey) -> Pubkey { pub fn get_enclave_pda(fn_key: &Pubkey) -> Pubkey {
let (pda_key, _) = Pubkey::find_program_address( let (pda_key, _) = Pubkey::find_program_address(
&[QUOTE_SEED, &fn_key.to_bytes()], &[QUOTE_SEED, &fn_key.to_bytes()],
&SWITCHBOARD_ATTESTATION_PROGRAM_ID, &SWITCHBOARD_ATTESTATION_PROGRAM_ID,
@ -222,25 +222,41 @@ impl FunctionAccountData {
/// # Arguments /// # Arguments
/// ///
/// * `function_account_info` - Solana AccountInfo for a FunctionAccountData /// * `function_account_info` - Solana AccountInfo for a FunctionAccountData
/// * `quote_account_info` - Solana AccountInfo for a EnclaveAccountData /// * `enclave_account_info` - Solana AccountInfo for a EnclaveAccountData
/// * `signer` - Solana AccountInfo for a signer /// * `signer` - Solana AccountInfo for a signer
pub fn validate_quote<'a>( pub fn validate_enclave<'a>(
function_account_info: &'a AccountInfo<'a>, function_account_info: &AccountInfo<'a>,
quote_account_info: &'a AccountInfo<'a>, enclave_account_info: &AccountInfo<'a>,
signer: &AccountInfo<'a>, signer: &AccountInfo<'a>,
) -> anchor_lang::Result<bool> { ) -> anchor_lang::Result<bool> {
// deserialize accounts and verify the owner
FunctionAccountData::new(function_account_info)?;
let quote = EnclaveAccountData::new(quote_account_info)?;
// validate function PDA matches the expected derivation // validate function PDA matches the expected derivation
let expected_quote_key = EnclaveAccountData::get_pda_pubkey(&function_account_info.key())?; let expected_enclave_key =
if quote_account_info.key() != expected_quote_key { EnclaveAccountData::get_pda_pubkey(&function_account_info.key())?;
if enclave_account_info.key() != expected_enclave_key {
return Ok(false); return Ok(false);
} }
// validate the quotes delegated signer matches // deserialize accounts and verify the owner
if quote.enclave_signer != signer.key() { let function_loader =
AccountLoader::<'_, FunctionAccountData>::try_from(&function_account_info.clone())?;
let func = function_loader.load()?;
let enclave_loader =
AccountLoader::<'_, EnclaveAccountData>::try_from(&enclave_account_info.clone())?;
let enclave = enclave_loader.load()?;
// validate the enclaves enclave is not empty
if enclave.mr_enclave == [0u8; 32] {
return Ok(false);
}
// validate the enclaves measurement is present in FunctionAccount config
if !func.is_valid_enclave(&enclave.mr_enclave) {
return Ok(false);
}
// validate the enclaves delegated signer matches
if enclave.enclave_signer != signer.key() {
return Ok(false); return Ok(false);
} }

View File

@ -211,7 +211,7 @@ impl ToAccountMetas for FunctionVerifyAccounts {
is_writable: false, is_writable: false,
}, },
AccountMeta { AccountMeta {
pubkey: FunctionAccountData::get_quote_pda(&self.function), pubkey: FunctionAccountData::get_enclave_pda(&self.function),
is_signer: false, is_signer: false,
is_writable: true, is_writable: true,
}, },