add instruction constructors
This commit is contained in:
parent
86dd02e0e6
commit
ff0b4766ae
|
@ -28,13 +28,11 @@ Parameters:
|
|||
| ----- | -------- | ------------------- | ------ | --------- | ----- | ------- |
|
||||
| 0 | sys | SystemProgram | | | ️ | |
|
||||
| 1 | token_program | SplToken | | | ️ | |
|
||||
| 2 | clock | Sysvar | | | ️ | ✅ |
|
||||
| 3 | sender | TokenAccount | | ✅ | | |
|
||||
| 4 | bridge | BridgeConfig | | | | |
|
||||
| 5 | proposal | TransferOutProposal | | ✅ | ✅ | ✅ |
|
||||
| 6 | token | WrappedAsset | | ✅ | | ✅ |
|
||||
| 7 | payer | Account | ✅ | | | |
|
||||
| 8-n | sender_owner | Account | ✅ | | | |
|
||||
| 2 | token_account | TokenAccount | | ✅ | | |
|
||||
| 3 | bridge | BridgeConfig | | | | |
|
||||
| 4 | proposal | TransferOutProposal | | ✅ | ✅ | ✅ |
|
||||
| 5 | token | WrappedAsset | | ✅ | | ✅ |
|
||||
| 6 | payer | Account | ✅ | | | |
|
||||
|
||||
#### TransferOutNative
|
||||
|
||||
|
@ -47,14 +45,12 @@ The transfer proposal will be tracked at a new account `proposal` where a VAA wi
|
|||
| ----- | --------------- | ------------------- | ------ | --------- | ----- | ------- |
|
||||
| 0 | sys | SystemProgram | | | ️ | |
|
||||
| 1 | token_program | SplToken | | | ️ | |
|
||||
| 2 | clock | Sysvar | | | ️ | ✅ |
|
||||
| 3 | sender | TokenAccount | | ✅ | | |
|
||||
| 4 | bridge | BridgeConfig | | | | |
|
||||
| 5 | proposal | TransferOutProposal | | ✅ | ✅ | ✅ |
|
||||
| 6 | token | Mint | | ✅ | | |
|
||||
| 2 | token_account | TokenAccount | | ✅ | | |
|
||||
| 3 | bridge | BridgeConfig | | | | |
|
||||
| 4 | proposal | TransferOutProposal | | ✅ | ✅ | ✅ |
|
||||
| 5 | token | Mint | | ✅ | | |
|
||||
| 6 | payer | Account | ✅ | | | |
|
||||
| 7 | custody_account | TokenAccount | | ✅ | opt | ✅ |
|
||||
| 8 | payer | Account | ✅ | | | |
|
||||
| 9-n | sender_owner | Account | ✅ | | | |
|
||||
|
||||
#### EvictTransferOut
|
||||
|
||||
|
@ -108,9 +104,8 @@ followed by:
|
|||
| Index | Name | Type | signer | writeable | empty | derived |
|
||||
| ----- | ------------ | ------------ | ------ | --------- | ----- | ------- |
|
||||
| 6 | token_program | SplToken | | | ️ | |
|
||||
| 7 | token | WrappedAsset | | | opt | ✅ |
|
||||
| 7 | token | WrappedAsset | | | opt | ✅ |
|
||||
| 8 | destination | TokenAccount | | ✅ | opt | |
|
||||
| 9 | sender | Account | ✅ | | | |
|
||||
|
||||
##### Transfer: Ethereum (wrapped) -> Solana (native)
|
||||
|
||||
|
@ -125,7 +120,6 @@ followed by:
|
|||
|
||||
| Index | Name | Type | signer | writeable | empty | derived |
|
||||
| ----- | ------------ | ------------------- | ------ | --------- | ----- | ------- |
|
||||
| 6 | token_program | SplToken | | | ️ | |
|
||||
| 7 | out_proposal | TransferOutProposal | | ✅ | | ✅ |
|
||||
| 8 | sender | Account | ✅ | | | |
|
||||
|
||||
|
|
|
@ -91,6 +91,9 @@ pub enum Error {
|
|||
/// Invalid transfer with src=dst
|
||||
#[error("SameChainTransfer")]
|
||||
SameChainTransfer,
|
||||
/// VAA is longer than the maximum size
|
||||
#[error("VAATooLong")]
|
||||
VAATooLong,
|
||||
}
|
||||
|
||||
impl From<Error> for ProgramError {
|
||||
|
|
|
@ -35,6 +35,7 @@ impl PrintProgramError for Error {
|
|||
Error::ExpectedTransferOutProposal => info!("Error: ExpectedTransferOutProposal"),
|
||||
Error::VAAProposalMismatch => info!("Error: VAAProposalMismatch"),
|
||||
Error::SameChainTransfer => info!("Error: SameChainTransfer"),
|
||||
Error::VAATooLong => info!("Error: VAATooLong"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,21 +10,23 @@ use solana_sdk::{
|
|||
pubkey::Pubkey,
|
||||
};
|
||||
|
||||
use crate::error::Error::VAATooLong;
|
||||
use crate::instruction::BridgeInstruction::Initialize;
|
||||
use crate::state::{AssetMeta, BridgeConfig};
|
||||
use crate::state::{AssetMeta, Bridge, BridgeConfig};
|
||||
use crate::syscalls::RawKey;
|
||||
use crate::vaa::{VAABody, VAA};
|
||||
|
||||
/// chain id of this chain
|
||||
pub const CHAIN_ID_SOLANA: u8 = 1;
|
||||
|
||||
/// size of a VAA in bytes
|
||||
const VAA_SIZE: usize = 100;
|
||||
const VAA_SIZE: usize = 200;
|
||||
|
||||
/// size of a foreign address in bytes
|
||||
const FOREIGN_ADDRESS_SIZE: usize = 32;
|
||||
|
||||
/// validator payment approval
|
||||
pub type VAA_BODY = [u8; VAA_SIZE];
|
||||
/// length-prefixed serialized validator payment approval data
|
||||
pub type VAAData = [u8; VAA_SIZE];
|
||||
/// X and Y point of P for guardians
|
||||
pub type GuardianKey = [u8; 64];
|
||||
/// address on a foreign chain
|
||||
|
@ -50,6 +52,8 @@ pub struct TransferOutPayload {
|
|||
pub asset: AssetMeta,
|
||||
/// address on the foreign chain to transfer to
|
||||
pub target: ForeignAddress,
|
||||
/// unique nonce of the transfer
|
||||
pub nonce: u32,
|
||||
}
|
||||
|
||||
/// Instructions supported by the SwapInfo program.
|
||||
|
@ -91,7 +95,7 @@ pub enum BridgeInstruction {
|
|||
|
||||
/// Submits a VAA signed by `guardian` on a valid `proposal`.
|
||||
/// See docs for accounts
|
||||
PostVAA(VAA_BODY),
|
||||
PostVAA(VAAData),
|
||||
|
||||
/// Deletes a `proposal` after the `VAA_EXPIRATION_TIME` is over to free up space on chain.
|
||||
/// This returns the rent to the sender.
|
||||
|
@ -143,7 +147,7 @@ impl BridgeInstruction {
|
|||
output[0] = 2;
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
let value =
|
||||
unsafe { &mut *(&mut output[size_of::<u8>()] as *mut u8 as *mut VAA_BODY) };
|
||||
unsafe { &mut *(&mut output[size_of::<u8>()] as *mut u8 as *mut VAAData) };
|
||||
*value = payload;
|
||||
}
|
||||
Self::EvictTransferOut() => {
|
||||
|
@ -161,7 +165,6 @@ impl BridgeInstruction {
|
|||
pub fn initialize(
|
||||
program_id: &Pubkey,
|
||||
sender: &Pubkey,
|
||||
bridge: &Pubkey,
|
||||
initial_guardian: RawKey,
|
||||
config: &BridgeConfig,
|
||||
) -> Result<Instruction, ProgramError> {
|
||||
|
@ -171,9 +174,15 @@ pub fn initialize(
|
|||
})
|
||||
.serialize()?;
|
||||
|
||||
let bridge_key = Bridge::derive_bridge_id(program_id)?;
|
||||
let guardian_set_key = Bridge::derive_guardian_set_id(program_id, &bridge_key, 0)?;
|
||||
|
||||
let accounts = vec![
|
||||
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
|
||||
AccountMeta::new_readonly(solana_sdk::sysvar::clock::id(), false),
|
||||
AccountMeta::new(bridge_key, false),
|
||||
AccountMeta::new(guardian_set_key, false),
|
||||
AccountMeta::new(*sender, true),
|
||||
AccountMeta::new(*bridge, false),
|
||||
];
|
||||
|
||||
Ok(Instruction {
|
||||
|
@ -183,6 +192,138 @@ pub fn initialize(
|
|||
})
|
||||
}
|
||||
|
||||
/// Creates an 'TransferOut' instruction.
|
||||
pub fn transfer_out(
|
||||
program_id: &Pubkey,
|
||||
payer: &Pubkey,
|
||||
token_account: &Pubkey,
|
||||
token_mint: &Pubkey,
|
||||
t: &TransferOutPayload,
|
||||
) -> Result<Instruction, ProgramError> {
|
||||
let data = BridgeInstruction::TransferOut(*t).serialize()?;
|
||||
|
||||
let bridge_key = Bridge::derive_bridge_id(program_id)?;
|
||||
let transfer_key = Bridge::derive_transfer_id(
|
||||
program_id,
|
||||
&bridge_key,
|
||||
t.asset.chain,
|
||||
t.asset.address,
|
||||
t.chain_id,
|
||||
t.target,
|
||||
token_account.to_bytes(),
|
||||
t.nonce,
|
||||
)?;
|
||||
|
||||
let mut accounts = vec![
|
||||
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
|
||||
AccountMeta::new_readonly(spl_token::id(), false),
|
||||
AccountMeta::new(*token_account, false),
|
||||
AccountMeta::new(bridge_key, false),
|
||||
AccountMeta::new(transfer_key, false),
|
||||
AccountMeta::new(*token_mint, false),
|
||||
AccountMeta::new(*payer, true),
|
||||
];
|
||||
|
||||
// If the token is a native solana token add a custody account
|
||||
if t.asset.chain == CHAIN_ID_SOLANA {
|
||||
let custody_key = Bridge::derive_custody_id(program_id, &bridge_key, token_mint)?;
|
||||
accounts.push(AccountMeta::new(custody_key, false));
|
||||
}
|
||||
|
||||
Ok(Instruction {
|
||||
program_id: *program_id,
|
||||
accounts,
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a 'PostVAA' instruction.
|
||||
pub fn post_vaa(
|
||||
program_id: &Pubkey,
|
||||
payer: &Pubkey,
|
||||
v: &[u8],
|
||||
) -> Result<Instruction, ProgramError> {
|
||||
// VAA must be <= VAA_SIZE-1 to allow for the length prefix
|
||||
if v.len() > VAA_SIZE - 1 {
|
||||
return Err(VAATooLong.into());
|
||||
}
|
||||
// Convert data to length-prefixed on-chain format
|
||||
let mut vaa_data: Vec<u8> = vec![];
|
||||
vaa_data.push(v.len() as u8);
|
||||
vaa_data.append(&mut v.to_vec());
|
||||
|
||||
let mut vaa_chain: [u8; 200] = [0; 200];
|
||||
vaa_chain.copy_from_slice(vaa_data.as_slice());
|
||||
|
||||
let data = BridgeInstruction::PostVAA(vaa_chain).serialize()?;
|
||||
|
||||
// Parse VAA
|
||||
let vaa = VAA::deserialize(&v[..])?;
|
||||
|
||||
let bridge_key = Bridge::derive_bridge_id(program_id)?;
|
||||
let guardian_set_key =
|
||||
Bridge::derive_guardian_set_id(program_id, &bridge_key, vaa.guardian_set_index)?;
|
||||
let claim_key = Bridge::derive_claim_id(program_id, &bridge_key, &vaa.body_hash()?)?;
|
||||
|
||||
let mut accounts = vec![
|
||||
AccountMeta::new_readonly(solana_sdk::system_program::id(), false),
|
||||
AccountMeta::new_readonly(solana_sdk::sysvar::clock::id(), false),
|
||||
AccountMeta::new(bridge_key, false),
|
||||
AccountMeta::new(guardian_set_key, false),
|
||||
AccountMeta::new(claim_key, false),
|
||||
AccountMeta::new(*payer, true),
|
||||
];
|
||||
|
||||
match vaa.payload.unwrap() {
|
||||
VAABody::UpdateGuardianSet(u) => {
|
||||
let guardian_set_key =
|
||||
Bridge::derive_guardian_set_id(program_id, &bridge_key, u.new_index)?;
|
||||
accounts.push(AccountMeta::new(guardian_set_key, false));
|
||||
}
|
||||
VAABody::Transfer(t) => {
|
||||
if t.source_chain == CHAIN_ID_SOLANA {
|
||||
// Solana (any) -> Ethereum (any)
|
||||
let transfer_key = Bridge::derive_transfer_id(
|
||||
program_id,
|
||||
&bridge_key,
|
||||
t.asset.chain,
|
||||
t.asset.address,
|
||||
t.target_chain,
|
||||
t.target_address,
|
||||
t.source_address,
|
||||
t.nonce,
|
||||
)?;
|
||||
accounts.push(AccountMeta::new(transfer_key, false))
|
||||
} else if t.asset.chain == CHAIN_ID_SOLANA {
|
||||
// Foreign (wrapped) -> Solana (native)
|
||||
let mint_key = Pubkey::new(&t.asset.address);
|
||||
let custody_key = Bridge::derive_custody_id(program_id, &bridge_key, &mint_key)?;
|
||||
accounts.push(AccountMeta::new_readonly(spl_token::id(), false));
|
||||
accounts.push(AccountMeta::new(mint_key, false));
|
||||
accounts.push(AccountMeta::new(Pubkey::new(&t.target_address), false));
|
||||
accounts.push(AccountMeta::new(custody_key, false));
|
||||
} else {
|
||||
// Foreign (native) -> Solana (wrapped)
|
||||
let wrapped_key = Bridge::derive_wrapped_asset_id(
|
||||
program_id,
|
||||
&bridge_key,
|
||||
t.asset.chain,
|
||||
t.asset.address,
|
||||
)?;
|
||||
accounts.push(AccountMeta::new_readonly(spl_token::id(), false));
|
||||
accounts.push(AccountMeta::new(wrapped_key, false));
|
||||
accounts.push(AccountMeta::new(Pubkey::new(&t.target_address), false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Instruction {
|
||||
program_id: *program_id,
|
||||
accounts,
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
/// Unpacks a reference from a bytes buffer.
|
||||
pub fn unpack<T>(input: &[u8]) -> Result<&T, ProgramError> {
|
||||
if input.len() < size_of::<u8>() + size_of::<T>() {
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
//! Program instruction processing logic
|
||||
#![cfg(feature = "program")]
|
||||
|
||||
use std::io::Write;
|
||||
use std::mem::size_of;
|
||||
use std::slice::Iter;
|
||||
|
||||
use num_traits::AsPrimitive;
|
||||
use primitive_types::U256;
|
||||
use sha3::Digest;
|
||||
use solana_sdk::clock::Clock;
|
||||
#[cfg(not(target_arch = "bpf"))]
|
||||
use solana_sdk::instruction::Instruction;
|
||||
|
@ -24,7 +22,7 @@ use spl_token::state::Mint;
|
|||
|
||||
use crate::error::Error;
|
||||
use crate::instruction::BridgeInstruction::*;
|
||||
use crate::instruction::{BridgeInstruction, TransferOutPayload, CHAIN_ID_SOLANA};
|
||||
use crate::instruction::{BridgeInstruction, TransferOutPayload, VAAData, CHAIN_ID_SOLANA};
|
||||
use crate::state::*;
|
||||
use crate::syscalls::RawKey;
|
||||
use crate::vaa::{BodyTransfer, BodyUpdateGuardianSet, VAABody, VAA};
|
||||
|
@ -59,13 +57,9 @@ impl Bridge {
|
|||
let vaa_data = &vaa_body[..len];
|
||||
let vaa = VAA::deserialize(vaa_data)?;
|
||||
|
||||
let mut k = sha3::Keccak256::default();
|
||||
if let Err(_) = k.write(vaa_data) {
|
||||
return Err(Error::ParseFailed.into());
|
||||
};
|
||||
let hash = k.finalize();
|
||||
let hash = vaa.body_hash()?;
|
||||
|
||||
Self::process_vaa(program_id, accounts, &vaa_body, &vaa, hash.as_ref())
|
||||
Self::process_vaa(program_id, accounts, vaa_body, &vaa, &hash)
|
||||
}
|
||||
_ => panic!(""),
|
||||
}
|
||||
|
@ -88,7 +82,7 @@ impl Bridge {
|
|||
let clock = Clock::from_account_info(clock_info)?;
|
||||
|
||||
// Create bridge account
|
||||
let bridge_seed = Bridge::derive_bridge_seeds(program_id);
|
||||
let bridge_seed = Bridge::derive_bridge_seeds();
|
||||
Bridge::check_and_create_account::<BridgeConfig>(
|
||||
program_id,
|
||||
accounts,
|
||||
|
@ -142,7 +136,6 @@ impl Bridge {
|
|||
let account_info_iter = &mut accounts.iter();
|
||||
next_account_info(account_info_iter)?; // System program
|
||||
next_account_info(account_info_iter)?; // Token program
|
||||
let clock_info = next_account_info(account_info_iter)?;
|
||||
let sender_account_info = next_account_info(account_info_iter)?;
|
||||
let bridge_info = next_account_info(account_info_iter)?;
|
||||
let transfer_info = next_account_info(account_info_iter)?;
|
||||
|
@ -150,7 +143,6 @@ impl Bridge {
|
|||
let payer_info = next_account_info(account_info_iter)?;
|
||||
let authority_info = next_account_info(account_info_iter)?;
|
||||
|
||||
let clock = Clock::from_account_info(clock_info)?;
|
||||
let sender = Bridge::token_account_deserialize(sender_account_info)?;
|
||||
let bridge = Bridge::bridge_deserialize(bridge_info)?;
|
||||
let mint = Bridge::mint_deserialize(mint_info)?;
|
||||
|
@ -184,7 +176,7 @@ impl Bridge {
|
|||
t.chain_id,
|
||||
t.target,
|
||||
sender.owner.to_bytes(),
|
||||
clock.slot.as_(), //TODO use nonce
|
||||
t.nonce,
|
||||
);
|
||||
Bridge::check_and_create_account::<TransferOutProposal>(
|
||||
program_id,
|
||||
|
@ -229,16 +221,13 @@ impl Bridge {
|
|||
let account_info_iter = &mut accounts.iter();
|
||||
next_account_info(account_info_iter)?; // System program
|
||||
next_account_info(account_info_iter)?; // Token program
|
||||
let clock_info = next_account_info(account_info_iter)?;
|
||||
let sender_account_info = next_account_info(account_info_iter)?;
|
||||
let bridge_info = next_account_info(account_info_iter)?;
|
||||
let transfer_info = next_account_info(account_info_iter)?;
|
||||
let mint_info = next_account_info(account_info_iter)?;
|
||||
let custody_info = next_account_info(account_info_iter)?;
|
||||
let payer_info = next_account_info(account_info_iter)?;
|
||||
let sender_info = next_account_info(account_info_iter)?;
|
||||
let custody_info = next_account_info(account_info_iter)?;
|
||||
|
||||
let clock = Clock::from_account_info(clock_info)?;
|
||||
let sender = Bridge::token_account_deserialize(sender_account_info)?;
|
||||
let bridge = Bridge::bridge_deserialize(bridge_info)?;
|
||||
let mint = Bridge::mint_deserialize(mint_info)?;
|
||||
|
@ -260,8 +249,8 @@ impl Bridge {
|
|||
t.asset.address,
|
||||
t.chain_id,
|
||||
t.target,
|
||||
sender.owner.to_bytes(),
|
||||
clock.slot.as_(), //TODO use nonce
|
||||
sender_account_info.key.to_bytes(),
|
||||
t.nonce,
|
||||
);
|
||||
Bridge::check_and_create_account::<TransferOutProposal>(
|
||||
program_id,
|
||||
|
@ -310,7 +299,7 @@ impl Bridge {
|
|||
&bridge.config.token_program,
|
||||
sender_account_info.key,
|
||||
custody_info.key,
|
||||
sender_info.key,
|
||||
bridge_info.key,
|
||||
t.amount,
|
||||
)?;
|
||||
|
||||
|
@ -333,7 +322,7 @@ impl Bridge {
|
|||
pub fn process_vaa(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
vaa_data: &[u8; 100],
|
||||
vaa_data: VAAData,
|
||||
vaa: &VAA,
|
||||
hash: &[u8; 32],
|
||||
) -> ProgramResult {
|
||||
|
@ -508,6 +497,7 @@ impl Bridge {
|
|||
bridge: &mut Bridge,
|
||||
b: &BodyTransfer,
|
||||
) -> ProgramResult {
|
||||
next_account_info(account_info_iter)?; // Token program
|
||||
let mint_info = next_account_info(account_info_iter)?;
|
||||
let destination_info = next_account_info(account_info_iter)?;
|
||||
|
||||
|
@ -578,7 +568,7 @@ impl Bridge {
|
|||
bridge_info: &AccountInfo,
|
||||
vaa: &VAA,
|
||||
b: &BodyTransfer,
|
||||
vaa_data: &[u8; 100],
|
||||
vaa_data: VAAData,
|
||||
) -> ProgramResult {
|
||||
let proposal_info = next_account_info(account_info_iter)?;
|
||||
|
||||
|
@ -603,7 +593,7 @@ impl Bridge {
|
|||
}
|
||||
|
||||
// Set vaa
|
||||
proposal.vaa = *vaa_data;
|
||||
proposal.vaa = vaa_data;
|
||||
proposal.vaa_time = vaa.timestamp;
|
||||
|
||||
Ok(())
|
||||
|
@ -671,7 +661,7 @@ impl Bridge {
|
|||
all_signers.as_slice(),
|
||||
amount,
|
||||
)?;
|
||||
invoke_signed(&ix, accounts, &[])
|
||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
||||
}
|
||||
|
||||
/// Mint a wrapped asset to account
|
||||
|
@ -691,7 +681,7 @@ impl Bridge {
|
|||
&[],
|
||||
amount,
|
||||
)?;
|
||||
invoke_signed(&ix, accounts, &[&[&bridge.to_bytes()[..32]][..]])
|
||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
||||
}
|
||||
|
||||
/// Transfer tokens from a caller
|
||||
|
@ -703,19 +693,15 @@ impl Bridge {
|
|||
authority: &Pubkey,
|
||||
amount: U256,
|
||||
) -> Result<(), ProgramError> {
|
||||
let all_signers: Vec<&Pubkey> = accounts
|
||||
.iter()
|
||||
.filter_map(|item| if item.is_signer { Some(item.key) } else { None })
|
||||
.collect();
|
||||
let ix = spl_token::instruction::transfer(
|
||||
token_program_id,
|
||||
source,
|
||||
destination,
|
||||
authority,
|
||||
all_signers.as_slice(),
|
||||
&[],
|
||||
amount,
|
||||
)?;
|
||||
invoke_signed(&ix, accounts, &[])
|
||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
||||
}
|
||||
|
||||
/// Transfer tokens from a custody account
|
||||
|
@ -735,7 +721,7 @@ impl Bridge {
|
|||
&[],
|
||||
amount,
|
||||
)?;
|
||||
invoke_signed(&ix, accounts, &[&[&bridge.to_bytes()[..32]][..]])
|
||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
||||
}
|
||||
|
||||
/// Create a new account
|
||||
|
@ -756,7 +742,7 @@ impl Bridge {
|
|||
&Self::derive_custody_seeds(bridge, mint),
|
||||
)?;
|
||||
let ix = spl_token::instruction::initialize_account(token_program, account, mint, bridge)?;
|
||||
invoke_signed(&ix, accounts, &[&[&bridge.to_bytes()[..32]][..]])
|
||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
||||
}
|
||||
|
||||
/// Create a mint for a wrapped asset
|
||||
|
@ -784,7 +770,7 @@ impl Bridge {
|
|||
U256::from(0),
|
||||
8,
|
||||
)?;
|
||||
invoke_signed(&ix, accounts, &[&[&bridge.to_bytes()[..32]][..]])
|
||||
invoke_signed(&ix, accounts, &[&["bridge".as_bytes()]])
|
||||
}
|
||||
|
||||
/// Check that a key was derived correctly and create account
|
||||
|
|
|
@ -2,15 +2,14 @@
|
|||
|
||||
use std::mem::size_of;
|
||||
|
||||
use primitive_types::U256;
|
||||
use solana_sdk::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey};
|
||||
|
||||
use crate::instruction::{ForeignAddress, VAA_BODY};
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::instruction::{ForeignAddress, VAAData};
|
||||
use crate::syscalls::RawKey;
|
||||
use crate::vaa::BodyTransfer;
|
||||
use primitive_types::U256;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
/// fee rate as a ratio
|
||||
#[repr(C)]
|
||||
|
@ -58,7 +57,7 @@ pub struct TransferOutProposal {
|
|||
/// asset that is being transferred
|
||||
pub asset: AssetMeta,
|
||||
/// vaa to unlock the tokens on the foreign chain
|
||||
pub vaa: VAA_BODY,
|
||||
pub vaa: VAAData,
|
||||
/// time the vaa was submitted
|
||||
pub vaa_time: u32,
|
||||
|
||||
|
@ -244,8 +243,8 @@ impl Bridge {
|
|||
}
|
||||
|
||||
/// Calculates derived seeds for a bridge
|
||||
pub fn derive_bridge_seeds(program_id: &Pubkey) -> Vec<Vec<u8>> {
|
||||
vec![program_id.to_bytes().to_vec()]
|
||||
pub fn derive_bridge_seeds() -> Vec<Vec<u8>> {
|
||||
vec!["bridge".as_bytes().to_vec()]
|
||||
}
|
||||
|
||||
/// Calculates derived seeds for a custody account
|
||||
|
@ -268,7 +267,7 @@ impl Bridge {
|
|||
|
||||
/// Calculates a derived address for this program
|
||||
pub fn derive_bridge_id(program_id: &Pubkey) -> Result<Pubkey, Error> {
|
||||
Self::derive_key(program_id, &Self::derive_bridge_seeds(program_id))
|
||||
Self::derive_key(program_id, &Self::derive_bridge_seeds())
|
||||
}
|
||||
|
||||
/// Calculates a derived address for a custody account
|
||||
|
|
|
@ -55,6 +55,18 @@ impl VAA {
|
|||
sol_verify_schnorr(&schnorr_input)
|
||||
}
|
||||
|
||||
pub fn body_hash(&self) -> Result<[u8; 32], Error> {
|
||||
let body_bytes = self.signature_body()?;
|
||||
|
||||
let mut k = sha3::Keccak256::default();
|
||||
if let Err(_) = k.write(body_bytes.as_slice()) {
|
||||
return Err(Error::ParseFailed.into());
|
||||
};
|
||||
let hash = k.finalize();
|
||||
|
||||
return Ok(hash.into());
|
||||
}
|
||||
|
||||
pub fn serialize(&self) -> Result<Vec<u8>, Error> {
|
||||
let mut v = Cursor::new(Vec::new());
|
||||
|
||||
|
@ -252,7 +264,6 @@ impl BodyTransfer {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use hex;
|
||||
use primitive_types::U256;
|
||||
|
||||
|
|
Loading…
Reference in New Issue