Implement optional persistence in Solana wormhole

Also reformatted the token_bridge

Change-Id: I195d7e2e13295c8b28e2a0b63620e3d306dc07e6
This commit is contained in:
Hendrik Hofstadt 2021-07-02 19:59:59 +02:00
parent 3fd60e822a
commit d9fde6d7cc
19 changed files with 246 additions and 360 deletions

View File

@ -10,6 +10,8 @@ WORKDIR /usr/src/solana
ADD solana /usr/src/solana ADD solana /usr/src/solana
ADD proto /usr/src/proto ADD proto /usr/src/proto
ENV EMITTER_ADDRESS="11111111111111111111111111111115"
RUN --mount=type=cache,target=/usr/local/cargo,from=rust,source=/usr/local/cargo \ RUN --mount=type=cache,target=/usr/local/cargo,from=rust,source=/usr/local/cargo \
--mount=type=cache,target=/root/.cache \ --mount=type=cache,target=/root/.cache \
--mount=type=cache,target=target \ --mount=type=cache,target=target \

View File

@ -120,7 +120,13 @@ func (s *SolanaWatcher) Run(ctx context.Context) error {
}, },
{ {
Memcmp: &rpc.RPCFilterMemcmp{ Memcmp: &rpc.RPCFilterMemcmp{
Offset: 4, // Offset of VaaTime Offset: 4, // Start of the Persist flag
Bytes: solana.Base58{0x01}, // Only grab messages that need to be persisted
},
},
{
Memcmp: &rpc.RPCFilterMemcmp{
Offset: 5, // Offset of VaaTime
Bytes: solana.Base58{0, 0, 0, 0}, // This means this VAA hasn't been signed yet Bytes: solana.Base58{0, 0, 0, 0}, // This means this VAA hasn't been signed yet
}, },
}, },
@ -188,7 +194,9 @@ func (s *SolanaWatcher) Run(ctx context.Context) error {
type ( type (
MessagePublicationAccount struct { MessagePublicationAccount struct {
VaaVersion uint8 VaaVersion uint8
// Borsh does not seem to support booleans, so 0=false / 1=true
Persist uint8
VaaTime uint32 VaaTime uint32
VaaSignatureAccount vaa.Address VaaSignatureAccount vaa.Address
SubmissionTime uint32 SubmissionTime uint32

View File

@ -10,6 +10,7 @@ RUN sh -c "$(curl -sSfL https://release.solana.com/edge/install)"
ENV PATH="/root/.local/share/solana/install/active_release/bin:$PATH" ENV PATH="/root/.local/share/solana/install/active_release/bin:$PATH"
ENV RUST_LOG="solana_runtime::system_instruction_processor=trace,solana_runtime::message_processor=trace,solana_bpf_loader=debug,solana_rbpf=debug" ENV RUST_LOG="solana_runtime::system_instruction_processor=trace,solana_runtime::message_processor=trace,solana_bpf_loader=debug,solana_rbpf=debug"
ENV EMITTER_ADDRESS="11111111111111111111111111111115"
COPY bridge bridge COPY bridge bridge
COPY modules modules COPY modules modules

View File

@ -111,6 +111,7 @@ fn command_post_message(
bridge: &Pubkey, bridge: &Pubkey,
nonce: u32, nonce: u32,
payload: Vec<u8>, payload: Vec<u8>,
persist: bool,
) -> CommmandResult { ) -> CommmandResult {
println!("Posting a message to the wormhole"); println!("Posting a message to the wormhole");
@ -134,6 +135,7 @@ fn command_post_message(
config.fee_payer.pubkey(), config.fee_payer.pubkey(),
nonce, nonce,
payload, payload,
persist,
) )
.unwrap(); .unwrap();
let mut transaction = let mut transaction =
@ -267,6 +269,13 @@ fn main() {
.index(3) .index(3)
.required(true) .required(true)
.help("Payload of the message"), .help("Payload of the message"),
)
.arg(
Arg::with_name("persist")
.short("p")
.long("persist")
.takes_value(false)
.help("Indicates that the VAA should be persisted on-chain"),
), ),
) )
.get_matches(); .get_matches();
@ -322,8 +331,9 @@ fn main() {
let data_str: String = value_of(arg_matches, "data").unwrap(); let data_str: String = value_of(arg_matches, "data").unwrap();
let data = hex::decode(data_str).unwrap(); let data = hex::decode(data_str).unwrap();
let nonce: u32 = value_of(arg_matches, "nonce").unwrap(); let nonce: u32 = value_of(arg_matches, "nonce").unwrap();
let persist = arg_matches.is_present("persist");
command_post_message(&config, &bridge, nonce, data) command_post_message(&config, &bridge, nonce, data, persist)
} }
_ => unreachable!(), _ => unreachable!(),

View File

@ -71,6 +71,9 @@ pub struct PostMessageData {
/// Message payload /// Message payload
pub payload: Vec<u8>, pub payload: Vec<u8>,
/// Should the VAA for this message be persisted on-chain
pub persist: bool,
} }
pub fn post_message( pub fn post_message(
@ -127,6 +130,7 @@ pub fn post_message(
accs.message.nonce = data.nonce; accs.message.nonce = data.nonce;
accs.message.payload = data.payload; accs.message.payload = data.payload;
accs.message.sequence = accs.sequence.sequence; accs.message.sequence = accs.sequence.sequence;
accs.message.persist = data.persist;
// Create message account // Create message account
accs.message accs.message

View File

@ -79,6 +79,7 @@ pub fn post_message(
emitter: Pubkey, emitter: Pubkey,
nonce: u32, nonce: u32,
payload: Vec<u8>, payload: Vec<u8>,
persist: bool,
) -> solitaire::Result<(Pubkey, Instruction)> { ) -> solitaire::Result<(Pubkey, Instruction)> {
let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id); let bridge = Bridge::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
let fee_collector = FeeCollector::<'_>::key(None, &program_id); let fee_collector = FeeCollector::<'_>::key(None, &program_id);
@ -99,27 +100,31 @@ pub fn post_message(
&program_id, &program_id,
); );
Ok((message, Instruction { Ok((
program_id, message,
Instruction {
program_id,
accounts: vec![ accounts: vec![
AccountMeta::new(bridge, false), AccountMeta::new(bridge, false),
AccountMeta::new(message, false), AccountMeta::new(message, false),
AccountMeta::new(emitter, true), AccountMeta::new(emitter, true),
AccountMeta::new(sequence, false), AccountMeta::new(sequence, false),
AccountMeta::new(payer, true), AccountMeta::new(payer, true),
AccountMeta::new(fee_collector, false), AccountMeta::new(fee_collector, false),
AccountMeta::new_readonly(sysvar::clock::id(), false), AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::rent::id(), false), AccountMeta::new_readonly(sysvar::rent::id(), false),
AccountMeta::new_readonly(solana_program::system_program::id(), false), AccountMeta::new_readonly(solana_program::system_program::id(), false),
], ],
data: crate::instruction::Instruction::PostMessage(PostMessageData { data: crate::instruction::Instruction::PostMessage(PostMessageData {
nonce, nonce,
payload: payload.clone(), payload: payload.clone(),
}) persist,
.try_to_vec()?, })
})) .try_to_vec()?,
},
))
} }
pub fn verify_signatures( pub fn verify_signatures(

View File

@ -162,6 +162,9 @@ pub struct PostedMessageData {
/// Header of the posted VAA /// Header of the posted VAA
pub vaa_version: u8, pub vaa_version: u8,
/// Whether the VAA for this message should be persisted
pub persist: bool,
/// Time the vaa was submitted /// Time the vaa was submitted
pub vaa_time: u32, pub vaa_time: u32,

View File

@ -1,48 +1,29 @@
use borsh::BorshSerialize; use borsh::BorshSerialize;
use bridge::{ use bridge::{api, types};
api,
types,
};
use clap::Clap; use clap::Clap;
use solana_client::{ use solana_client::{rpc_client::RpcClient, rpc_config::RpcSendTransactionConfig};
rpc_client::RpcClient,
rpc_config::RpcSendTransactionConfig,
};
use solana_program::pubkey::Pubkey; use solana_program::pubkey::Pubkey;
use solana_sdk::{ use solana_sdk::{
commitment_config::CommitmentConfig, commitment_config::CommitmentConfig,
signature::{ signature::{read_keypair_file, Signer as SolSigner},
read_keypair_file,
Signer as SolSigner,
},
transaction::Transaction, transaction::Transaction,
}; };
use solitaire_client::{ use solitaire_client::{AccEntry, ToInstruction};
AccEntry,
ToInstruction,
};
use bridge::accounts::{ use bridge::accounts::{GuardianSet, GuardianSetDerivationData};
GuardianSet,
GuardianSetDerivationData,
};
use solitaire::{
processors::seeded::Seeded,
AccountState,
};
use std::error;
use solana_sdk::instruction::Instruction;
use solana_sdk::signature::Keypair;
use solana_sdk::client::Client;
use solana_client::rpc_request::RpcError;
use solana_client::client_error::{ClientError, ClientErrorKind}; use solana_client::client_error::{ClientError, ClientErrorKind};
use solana_client::rpc_request::RpcError;
use solana_sdk::client::Client;
use solana_sdk::instruction::Instruction;
use solana_sdk::program_pack::Pack; use solana_sdk::program_pack::Pack;
use solana_sdk::rent::Rent; use solana_sdk::rent::Rent;
use token_bridge::api::{AttestTokenData, TransferNativeData}; use solana_sdk::signature::Keypair;
use solitaire::{processors::seeded::Seeded, AccountState};
use solitaire_client::solana_sdk::account::ReadableAccount;
use spl_token::instruction::TokenInstruction::Transfer; use spl_token::instruction::TokenInstruction::Transfer;
use spl_token::state::Mint; use spl_token::state::Mint;
use solitaire_client::solana_sdk::account::ReadableAccount; use std::error;
use token_bridge::api::{AttestTokenData, TransferNativeData};
#[derive(Clap)] #[derive(Clap)]
pub struct Opts { pub struct Opts {
@ -95,62 +76,137 @@ fn main() -> Result<(), ErrBox> {
let payer = read_keypair_file(&*shellexpand::tilde("~/.config/solana/id.json")) let payer = read_keypair_file(&*shellexpand::tilde("~/.config/solana/id.json"))
.expect("Example requires a keypair file"); .expect("Example requires a keypair file");
let token_program_id = opts.token_address; let token_program_id = opts.token_address;
let init_token = token_bridge::instructions::initialize(token_program_id, payer.pubkey(), program_id).unwrap(); let init_token =
token_bridge::instructions::initialize(token_program_id, payer.pubkey(), program_id)
.unwrap();
send_ix_in_tx(&client, init_token, &payer, vec![&payer])?; send_ix_in_tx(&client, init_token, &payer, vec![&payer])?;
// Create a token // Create a token
let mint_authority = Keypair::new(); let mint_authority = Keypair::new();
let mint = Keypair::new(); let mint = Keypair::new();
let init_mint_account = solana_sdk::system_instruction::create_account(&payer.pubkey(), &mint.pubkey(), Rent::default().minimum_balance(spl_token::state::Mint::LEN), spl_token::state::Mint::LEN as u64, &spl_token::id()); let init_mint_account = solana_sdk::system_instruction::create_account(
let init_mint = spl_token::instruction::initialize_mint(&spl_token::id(), &mint.pubkey(), &mint_authority.pubkey(), None, 8)?; &payer.pubkey(),
&mint.pubkey(),
Rent::default().minimum_balance(spl_token::state::Mint::LEN),
spl_token::state::Mint::LEN as u64,
&spl_token::id(),
);
let init_mint = spl_token::instruction::initialize_mint(
&spl_token::id(),
&mint.pubkey(),
&mint_authority.pubkey(),
None,
8,
)?;
send_ix_in_tx(&client, init_mint_account, &payer, vec![&payer, &mint])?; send_ix_in_tx(&client, init_mint_account, &payer, vec![&payer, &mint])?;
send_ix_in_tx(&client, init_mint, &payer, vec![&payer])?; send_ix_in_tx(&client, init_mint, &payer, vec![&payer])?;
// Attest a token // Attest a token
let rando = Keypair::new(); let rando = Keypair::new();
let mint_data = get_mint(&client, &mint.pubkey())?; let mint_data = get_mint(&client, &mint.pubkey())?;
let attest_token = token_bridge::instructions::attest(token_program_id, program_id, payer.pubkey(), mint.pubkey(), mint_data, rando.pubkey(), 0).unwrap(); let attest_token = token_bridge::instructions::attest(
token_program_id,
program_id,
payer.pubkey(),
mint.pubkey(),
mint_data,
rando.pubkey(),
0,
)
.unwrap();
send_ix_in_tx(&client, attest_token, &payer, vec![&payer])?; send_ix_in_tx(&client, attest_token, &payer, vec![&payer])?;
// Create a token account // Create a token account
let token_authority = Keypair::new(); let token_authority = Keypair::new();
let token_acc = Keypair::new(); let token_acc = Keypair::new();
let init_token_sys = solana_sdk::system_instruction::create_account(&payer.pubkey(), &token_acc.pubkey(), Rent::default().minimum_balance(spl_token::state::Account::LEN), spl_token::state::Account::LEN as u64, &spl_token::id()); let init_token_sys = solana_sdk::system_instruction::create_account(
let init_token_account = spl_token::instruction::initialize_account(&spl_token::id(), &token_acc.pubkey(), &mint.pubkey(), &token_authority.pubkey())?; &payer.pubkey(),
&token_acc.pubkey(),
Rent::default().minimum_balance(spl_token::state::Account::LEN),
spl_token::state::Account::LEN as u64,
&spl_token::id(),
);
let init_token_account = spl_token::instruction::initialize_account(
&spl_token::id(),
&token_acc.pubkey(),
&mint.pubkey(),
&token_authority.pubkey(),
)?;
send_ix_in_tx(&client, init_token_sys, &payer, vec![&payer, &token_acc])?; send_ix_in_tx(&client, init_token_sys, &payer, vec![&payer, &token_acc])?;
send_ix_in_tx(&client, init_token_account, &payer, vec![&payer])?; send_ix_in_tx(&client, init_token_account, &payer, vec![&payer])?;
// Mint tokens // Mint tokens
let mint_ix = spl_token::instruction::mint_to(&spl_token::id(), &mint.pubkey(), &token_acc.pubkey(), &mint_authority.pubkey(), &[], 1000)?; let mint_ix = spl_token::instruction::mint_to(
&spl_token::id(),
&mint.pubkey(),
&token_acc.pubkey(),
&mint_authority.pubkey(),
&[],
1000,
)?;
send_ix_in_tx(&client, mint_ix, &payer, vec![&payer, &mint_authority])?; send_ix_in_tx(&client, mint_ix, &payer, vec![&payer, &mint_authority])?;
// Give allowance // Give allowance
let bridge_token_authority = token_bridge::accounts::AuthoritySigner::key(None, &token_program_id); let bridge_token_authority =
let allowance_ix = spl_token::instruction::approve(&spl_token::id(), &token_acc.pubkey(), &bridge_token_authority, &token_authority.pubkey(), &[], 1000)?; token_bridge::accounts::AuthoritySigner::key(None, &token_program_id);
send_ix_in_tx(&client, allowance_ix, &payer, vec![&payer, &token_authority])?; let allowance_ix = spl_token::instruction::approve(
&spl_token::id(),
&token_acc.pubkey(),
&bridge_token_authority,
&token_authority.pubkey(),
&[],
1000,
)?;
send_ix_in_tx(
&client,
allowance_ix,
&payer,
vec![&payer, &token_authority],
)?;
// Transfer to ETH // Transfer to ETH
let transfer_eth = token_bridge::instructions::transfer_native(token_program_id, program_id, payer.pubkey(), token_acc.pubkey(), mint.pubkey(), TransferNativeData { let transfer_eth = token_bridge::instructions::transfer_native(
nonce: 1, token_program_id,
amount: 500, program_id,
fee: 0, payer.pubkey(),
target_address: [2; 32], token_acc.pubkey(),
target_chain: 2, mint.pubkey(),
}).unwrap(); TransferNativeData {
nonce: 1,
amount: 500,
fee: 0,
target_address: [2; 32],
target_chain: 2,
},
)
.unwrap();
send_ix_in_tx(&client, transfer_eth, &payer, vec![&payer])?; send_ix_in_tx(&client, transfer_eth, &payer, vec![&payer])?;
let transfer_eth = token_bridge::instructions::transfer_native(token_program_id, program_id, payer.pubkey(), token_acc.pubkey(), mint.pubkey(), TransferNativeData { let transfer_eth = token_bridge::instructions::transfer_native(
nonce: 2, token_program_id,
amount: 500, program_id,
fee: 0, payer.pubkey(),
target_address: [2; 32], token_acc.pubkey(),
target_chain: 2, mint.pubkey(),
}).unwrap(); TransferNativeData {
nonce: 2,
amount: 500,
fee: 0,
target_address: [2; 32],
target_chain: 2,
},
)
.unwrap();
send_ix_in_tx(&client, transfer_eth, &payer, vec![&payer])?; send_ix_in_tx(&client, transfer_eth, &payer, vec![&payer])?;
Ok(()) Ok(())
} }
fn send_ix_in_tx(client: &RpcClient, ix: Instruction, payer: &Keypair, signers: Vec<&Keypair>) -> Result<(), ClientError> { fn send_ix_in_tx(
client: &RpcClient,
ix: Instruction,
payer: &Keypair,
signers: Vec<&Keypair>,
) -> Result<(), ClientError> {
let mut tx = Transaction::new_with_payer(&[ix], Some(&payer.pubkey())); let mut tx = Transaction::new_with_payer(&[ix], Some(&payer.pubkey()));
let (recent_blockhash, _) = client.get_recent_blockhash()?; let (recent_blockhash, _) = client.get_recent_blockhash()?;
@ -173,5 +229,8 @@ fn send_ix_in_tx(client: &RpcClient, ix: Instruction, payer: &Keypair, signers:
fn get_mint(client: &RpcClient, mint: &Pubkey) -> Result<Mint, ClientError> { fn get_mint(client: &RpcClient, mint: &Pubkey) -> Result<Mint, ClientError> {
let acc = client.get_account(mint)?; let acc = client.get_account(mint)?;
Mint::unpack(acc.data()).map_err(|e| ClientError { request: None, kind: ClientErrorKind::Custom(String::from("Could not deserialize mint")) }) Mint::unpack(acc.data()).map_err(|e| ClientError {
} request: None,
kind: ClientErrorKind::Custom(String::from("Could not deserialize mint")),
})
}

View File

@ -1,16 +1,10 @@
use crate::types::*; use crate::types::*;
use bridge::{ use bridge::{
api::ForeignAddress, api::ForeignAddress,
vaa::{ vaa::{DeserializePayload, PayloadMessage},
DeserializePayload,
PayloadMessage,
},
}; };
use solana_program::pubkey::Pubkey; use solana_program::pubkey::Pubkey;
use solitaire::{ use solitaire::{processors::seeded::Seeded, *};
processors::seeded::Seeded,
*,
};
pub type AuthoritySigner<'b> = Derive<Info<'b>, "authority_signer">; pub type AuthoritySigner<'b> = Derive<Info<'b>, "authority_signer">;
pub type CustodySigner<'b> = Derive<Info<'b>, "custody_signer">; pub type CustodySigner<'b> = Derive<Info<'b>, "custody_signer">;

View File

@ -1,52 +1,28 @@
use crate::{ use crate::{
accounts::{ accounts::{ConfigAccount, EmitterAccount},
ConfigAccount, messages::{PayloadAssetMeta, PayloadTransfer},
EmitterAccount,
},
messages::{
PayloadAssetMeta,
PayloadTransfer,
},
types::*, types::*,
}; };
use bridge::{ use bridge::{
api::{ api::{PostMessage, PostMessageData},
PostMessage,
PostMessageData,
},
vaa::SerializePayload, vaa::SerializePayload,
}; };
use primitive_types::U256; use primitive_types::U256;
use solana_program::{ use solana_program::{
account_info::AccountInfo, account_info::AccountInfo,
instruction::{ instruction::{AccountMeta, Instruction},
AccountMeta, program::{invoke, invoke_signed},
Instruction,
},
program::{
invoke,
invoke_signed,
},
program_error::ProgramError, program_error::ProgramError,
pubkey::Pubkey, pubkey::Pubkey,
sysvar::clock::Clock, sysvar::clock::Clock,
}; };
use solitaire::{ use solitaire::processors::seeded::invoke_seeded;
CreationLamports::Exempt, use solitaire::{CreationLamports::Exempt, *};
*,
};
use spl_token::{ use spl_token::{
error::TokenError::OwnerMismatch, error::TokenError::OwnerMismatch,
state::{ state::{Account, Mint},
Account,
Mint,
},
}; };
use std::ops::{ use std::ops::{Deref, DerefMut};
Deref,
DerefMut,
};
use solitaire::processors::seeded::invoke_seeded;
#[derive(FromAccounts)] #[derive(FromAccounts)]
pub struct AttestToken<'b> { pub struct AttestToken<'b> {
@ -111,6 +87,7 @@ pub fn attest_token(
let params = bridge::instruction::Instruction::PostMessage(PostMessageData { let params = bridge::instruction::Instruction::PostMessage(PostMessageData {
nonce: data.nonce, nonce: data.nonce,
payload: payload.try_to_vec()?, payload: payload.try_to_vec()?,
persist: true,
}); });
let ix = Instruction::new_with_bytes( let ix = Instruction::new_with_bytes(

View File

@ -1,14 +1,7 @@
use crate::{ use crate::{
accounts::{ accounts::{
ConfigAccount, ConfigAccount, CustodyAccount, CustodyAccountDerivationData, CustodySigner, Endpoint,
CustodyAccount, EndpointDerivationData, MintSigner, WrappedDerivationData, WrappedMint,
CustodyAccountDerivationData,
CustodySigner,
Endpoint,
EndpointDerivationData,
MintSigner,
WrappedDerivationData,
WrappedMint,
}, },
messages::PayloadTransfer, messages::PayloadTransfer,
types::*, types::*,
@ -16,27 +9,15 @@ use crate::{
}; };
use bridge::vaa::ClaimableVAA; use bridge::vaa::ClaimableVAA;
use solana_program::{ use solana_program::{
account_info::AccountInfo, account_info::AccountInfo, program::invoke_signed, program_error::ProgramError, pubkey::Pubkey,
program::invoke_signed,
program_error::ProgramError,
pubkey::Pubkey,
}; };
use solitaire::{ use solitaire::{
processors::seeded::{ processors::seeded::{invoke_seeded, Seeded},
invoke_seeded,
Seeded,
},
CreationLamports::Exempt, CreationLamports::Exempt,
*, *,
}; };
use spl_token::state::{ use spl_token::state::{Account, Mint};
Account, use std::ops::{Deref, DerefMut};
Mint,
};
use std::ops::{
Deref,
DerefMut,
};
#[derive(FromAccounts)] #[derive(FromAccounts)]
pub struct CompleteNative<'b> { pub struct CompleteNative<'b> {

View File

@ -1,39 +1,21 @@
use crate::{ use crate::{
accounts::{ accounts::{
ConfigAccount, ConfigAccount, Endpoint, EndpointDerivationData, MintSigner, WrappedDerivationData,
Endpoint, WrappedMint, WrappedTokenMeta,
EndpointDerivationData,
MintSigner,
WrappedDerivationData,
WrappedMint,
WrappedTokenMeta,
}, },
messages::PayloadAssetMeta, messages::PayloadAssetMeta,
types::*, types::*,
}; };
use bridge::vaa::ClaimableVAA; use bridge::vaa::ClaimableVAA;
use solana_program::{ use solana_program::{
account_info::AccountInfo, account_info::AccountInfo, program::invoke_signed, program_error::ProgramError, pubkey::Pubkey,
program::invoke_signed,
program_error::ProgramError,
pubkey::Pubkey,
};
use solitaire::{
processors::seeded::Seeded,
CreationLamports::Exempt,
*,
}; };
use solitaire::{processors::seeded::Seeded, CreationLamports::Exempt, *};
use spl_token::{ use spl_token::{
error::TokenError::OwnerMismatch, error::TokenError::OwnerMismatch,
state::{ state::{Account, Mint},
Account,
Mint,
},
};
use std::ops::{
Deref,
DerefMut,
}; };
use std::ops::{Deref, DerefMut};
#[derive(FromAccounts)] #[derive(FromAccounts)]
pub struct CreateWrapped<'b> { pub struct CreateWrapped<'b> {

View File

@ -1,20 +1,7 @@
use crate::{ use crate::{accounts::ConfigAccount, types::*};
accounts::ConfigAccount, use solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey};
types::*, use solitaire::{CreationLamports::Exempt, *};
}; use std::ops::{Deref, DerefMut};
use solana_program::{
account_info::AccountInfo,
program_error::ProgramError,
pubkey::Pubkey,
};
use solitaire::{
CreationLamports::Exempt,
*,
};
use std::ops::{
Deref,
DerefMut,
};
#[derive(FromAccounts)] #[derive(FromAccounts)]
pub struct Initialize<'b> { pub struct Initialize<'b> {
@ -22,8 +9,7 @@ pub struct Initialize<'b> {
pub config: ConfigAccount<'b, { AccountState::Uninitialized }>, pub config: ConfigAccount<'b, { AccountState::Uninitialized }>,
} }
impl<'b> InstructionContext<'b> for Initialize<'b> { impl<'b> InstructionContext<'b> for Initialize<'b> {}
}
pub fn initialize( pub fn initialize(
ctx: &ExecutionContext, ctx: &ExecutionContext,

View File

@ -1,31 +1,12 @@
use crate::{ use crate::{
accounts::{ accounts::{ConfigAccount, Endpoint, EndpointDerivationData},
ConfigAccount,
Endpoint,
EndpointDerivationData,
},
messages::PayloadGovernanceRegisterChain, messages::PayloadGovernanceRegisterChain,
types::*, types::*,
}; };
use bridge::vaa::{ use bridge::vaa::{ClaimableVAA, DeserializePayload, PayloadMessage};
ClaimableVAA, use solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey};
DeserializePayload, use solitaire::{processors::seeded::Seeded, CreationLamports::Exempt, *};
PayloadMessage, use std::ops::{Deref, DerefMut};
};
use solana_program::{
account_info::AccountInfo,
program_error::ProgramError,
pubkey::Pubkey,
};
use solitaire::{
processors::seeded::Seeded,
CreationLamports::Exempt,
*,
};
use std::ops::{
Deref,
DerefMut,
};
#[derive(FromAccounts)] #[derive(FromAccounts)]
pub struct RegisterChain<'b> { pub struct RegisterChain<'b> {

View File

@ -1,14 +1,7 @@
use crate::{ use crate::{
accounts::{ accounts::{
AuthoritySigner, AuthoritySigner, ConfigAccount, CustodyAccount, CustodyAccountDerivationData,
ConfigAccount, CustodySigner, EmitterAccount, MintSigner, WrappedDerivationData, WrappedMint,
CustodyAccount,
CustodyAccountDerivationData,
CustodySigner,
EmitterAccount,
MintSigner,
WrappedDerivationData,
WrappedMint,
WrappedTokenMeta, WrappedTokenMeta,
}, },
messages::PayloadTransfer, messages::PayloadTransfer,
@ -17,47 +10,29 @@ use crate::{
TokenBridgeError::WrongAccountOwner, TokenBridgeError::WrongAccountOwner,
}; };
use bridge::{ use bridge::{
api::{ api::{PostMessage, PostMessageData},
PostMessage,
PostMessageData,
},
vaa::SerializePayload, vaa::SerializePayload,
}; };
use primitive_types::U256; use primitive_types::U256;
use solana_program::{ use solana_program::{
account_info::AccountInfo, account_info::AccountInfo,
instruction::{ instruction::{AccountMeta, Instruction},
AccountMeta, program::{invoke, invoke_signed},
Instruction,
},
program::{
invoke,
invoke_signed,
},
program_error::ProgramError, program_error::ProgramError,
program_option::COption, program_option::COption,
pubkey::Pubkey, pubkey::Pubkey,
sysvar::clock::Clock, sysvar::clock::Clock,
}; };
use solitaire::{ use solitaire::{
processors::seeded::{ processors::seeded::{invoke_seeded, Seeded},
invoke_seeded,
Seeded,
},
CreationLamports::Exempt, CreationLamports::Exempt,
*, *,
}; };
use spl_token::{ use spl_token::{
error::TokenError::OwnerMismatch, error::TokenError::OwnerMismatch,
state::{ state::{Account, Mint},
Account,
Mint,
},
};
use std::ops::{
Deref,
DerefMut,
}; };
use std::ops::{Deref, DerefMut};
#[derive(FromAccounts)] #[derive(FromAccounts)]
pub struct TransferNative<'b> { pub struct TransferNative<'b> {
@ -176,6 +151,7 @@ pub fn transfer_native(
let params = bridge::instruction::Instruction::PostMessage(PostMessageData { let params = bridge::instruction::Instruction::PostMessage(PostMessageData {
nonce: data.nonce, nonce: data.nonce,
payload: payload.try_to_vec()?, payload: payload.try_to_vec()?,
persist: true,
}); });
let ix = Instruction::new_with_bytes( let ix = Instruction::new_with_bytes(
@ -299,6 +275,7 @@ pub fn transfer_wrapped(
let params = bridge::instruction::Instruction::PostMessage(PostMessageData { let params = bridge::instruction::Instruction::PostMessage(PostMessageData {
nonce: data.nonce, nonce: data.nonce,
payload: payload.try_to_vec()?, payload: payload.try_to_vec()?,
persist: true,
}); });
let ix = Instruction::new_with_bytes( let ix = Instruction::new_with_bytes(

View File

@ -1,69 +1,31 @@
use crate::{ use crate::{
accounts::{ accounts::{
AuthoritySigner, AuthoritySigner, ConfigAccount, CustodyAccount, CustodyAccountDerivationData,
ConfigAccount, CustodySigner, EmitterAccount, Endpoint, EndpointDerivationData, MintSigner,
CustodyAccount, WrappedDerivationData, WrappedMint, WrappedTokenMeta,
CustodyAccountDerivationData,
CustodySigner,
EmitterAccount,
Endpoint,
EndpointDerivationData,
MintSigner,
WrappedDerivationData,
WrappedMint,
WrappedTokenMeta,
}, },
api::{ api::{
complete_transfer::{ complete_transfer::{CompleteNativeData, CompleteWrappedData},
CompleteNativeData, AttestTokenData, CreateWrappedData, RegisterChainData, TransferNativeData,
CompleteWrappedData,
},
AttestTokenData,
CreateWrappedData,
RegisterChainData,
TransferNativeData,
TransferWrappedData, TransferWrappedData,
}, },
messages::{ messages::{PayloadAssetMeta, PayloadGovernanceRegisterChain, PayloadTransfer},
PayloadAssetMeta,
PayloadGovernanceRegisterChain,
PayloadTransfer,
},
}; };
use borsh::BorshSerialize; use borsh::BorshSerialize;
use bridge::vaa::SerializePayload;
use bridge::{ use bridge::{
accounts::{ accounts::{
Bridge, Bridge, Claim, ClaimDerivationData, FeeCollector, Message, MessageDerivationData, Sequence,
Claim,
ClaimDerivationData,
FeeCollector,
Message,
MessageDerivationData,
Sequence,
SequenceDerivationData, SequenceDerivationData,
}, },
api::ForeignAddress, api::ForeignAddress,
types::{ types::{BridgeConfig, PostedMessage},
BridgeConfig, vaa::{ClaimableVAA, PayloadMessage},
PostedMessage,
},
vaa::{
ClaimableVAA,
PayloadMessage,
},
}; };
use solana_program::instruction::Instruction;
use solitaire::{
processors::seeded::Seeded,
AccountState,
};
use solitaire_client::{
AccountMeta,
Keypair,
Pubkey,
};
use bridge::vaa::SerializePayload;
use primitive_types::U256; use primitive_types::U256;
use solana_program::instruction::Instruction;
use solitaire::{processors::seeded::Seeded, AccountState};
use solitaire_client::{AccountMeta, Keypair, Pubkey};
use spl_token::state::Mint; use spl_token::state::Mint;
pub fn initialize( pub fn initialize(
@ -511,6 +473,7 @@ pub fn attest(
// Program // Program
AccountMeta::new_readonly(bridge_id, false), AccountMeta::new_readonly(bridge_id, false),
], ],
data: crate::instruction::Instruction::AttestToken(AttestTokenData { nonce }).try_to_vec()?, data: crate::instruction::Instruction::AttestToken(AttestTokenData { nonce })
.try_to_vec()?,
}) })
} }

View File

@ -13,29 +13,11 @@ pub mod messages;
pub mod types; pub mod types;
use api::{ use api::{
attest_token, attest_token, complete_native, complete_wrapped, create_wrapped, initialize, register_chain,
complete_native, transfer_native, transfer_wrapped, AttestToken, AttestTokenData, CompleteNative,
complete_wrapped, CompleteNativeData, CompleteWrapped, CompleteWrappedData, CreateWrapped, CreateWrappedData,
create_wrapped, Initialize, RegisterChain, RegisterChainData, TransferNative, TransferNativeData,
initialize, TransferWrapped, TransferWrappedData,
register_chain,
transfer_native,
transfer_wrapped,
AttestToken,
AttestTokenData,
CompleteNative,
CompleteNativeData,
CompleteWrapped,
CompleteWrappedData,
CreateWrapped,
CreateWrappedData,
Initialize,
RegisterChain,
RegisterChainData,
TransferNative,
TransferNativeData,
TransferWrapped,
TransferWrappedData,
}; };
use solitaire::*; use solitaire::*;

View File

@ -1,36 +1,16 @@
use crate::{ use crate::{
types::{ types::{Address, ChainID},
Address,
ChainID,
},
TokenBridgeError, TokenBridgeError,
}; };
use borsh::{ use borsh::{BorshDeserialize, BorshSerialize};
BorshDeserialize, use bridge::vaa::{DeserializePayload, SerializePayload};
BorshSerialize, use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
};
use bridge::vaa::{
DeserializePayload,
SerializePayload,
};
use byteorder::{
BigEndian,
ReadBytesExt,
WriteBytesExt,
};
use primitive_types::U256; use primitive_types::U256;
use solana_program::{ use solana_program::{native_token::Sol, program_error::ProgramError};
native_token::Sol,
program_error::ProgramError,
};
use solitaire::SolitaireError; use solitaire::SolitaireError;
use std::{ use std::{
error::Error, error::Error,
io::{ io::{Cursor, Read, Write},
Cursor,
Read,
Write,
},
str::Utf8Error, str::Utf8Error,
string::FromUtf8Error, string::FromUtf8Error,
}; };

View File

@ -1,19 +1,10 @@
use borsh::{ use borsh::{BorshDeserialize, BorshSerialize};
BorshDeserialize,
BorshSerialize,
};
use solana_program::pubkey::Pubkey; use solana_program::pubkey::Pubkey;
use solitaire::{ use solitaire::{
pack_type, pack_type,
processors::seeded::{ processors::seeded::{AccountOwner, Owned},
AccountOwner,
Owned,
},
};
use spl_token::state::{
Account,
Mint,
}; };
use spl_token::state::{Account, Mint};
pub type Address = [u8; 32]; pub type Address = [u8; 32];
pub type ChainID = u16; pub type ChainID = u16;