solana: Update last_lamports after transfer_fees

This commit is contained in:
Csongor Kiss 2022-06-27 13:29:32 +01:00 committed by Csongor Kiss
parent 1deb5683e2
commit be38cf5d7e
3 changed files with 87 additions and 6 deletions

View File

@ -224,7 +224,7 @@ pub struct TransferFees<'b> {
pub payer: Mut<Signer<Info<'b>>>,
/// Bridge config
pub bridge: Bridge<'b, { AccountState::Initialized }>,
pub bridge: Mut<Bridge<'b, { AccountState::Initialized }>>,
/// Governance VAA
pub vaa: ClaimableVAA<'b, GovernancePayloadTransferFees>,
@ -255,15 +255,17 @@ pub fn transfer_fees(
verify_governance(&accs.vaa)?;
accs.vaa.verify(ctx.program_id)?;
if accs
let new_balance = accs
.fee_collector
.lamports()
.saturating_sub(accs.vaa.amount.as_u64())
< accs.rent.minimum_balance(accs.fee_collector.data_len())
{
.saturating_sub(accs.vaa.amount.as_u64());
if new_balance < accs.rent.minimum_balance(accs.fee_collector.data_len()) {
return Err(InvalidGovernanceWithdrawal.into());
}
accs.bridge.last_lamports = new_balance;
accs.vaa.claim(ctx, accs.payer.key)?;
// Transfer fees

View File

@ -405,7 +405,7 @@ pub fn transfer_fees(
accounts: vec![
AccountMeta::new(payer, true),
AccountMeta::new_readonly(bridge, false),
AccountMeta::new(bridge, false),
AccountMeta::new_readonly(message, false),
AccountMeta::new(claim, false),
AccountMeta::new(fee_collector, false),

View File

@ -462,6 +462,85 @@ async fn test_bridge_messages_unreliable_do_not_override_reliable() {
.is_err());
}
#[tokio::test]
async fn bridge_works_after_transfer_fees() {
// This test aims to ensure that the bridge remains operational after the
// fees have been transferred out.
// NOTE: the bridge is initialised to take a minimum of 500 in fees.
let (ref mut context, ref mut client, ref payer, ref program) = initialize().await;
let fee_collector = FeeCollector::key(None, program);
let initial_balance = common::get_account_balance(client, fee_collector).await;
// First, post a message that transfer out 500 lamports.
// Since posting the message itself costs 500 lamports, this should result
// in the fee collector's account being reset to the initial amount (which
// is the rent exemption amount)
{
let emitter = Keypair::from_bytes(&GOVERNANCE_KEY).unwrap();
let sequence = context.seq.next(emitter.pubkey().to_bytes());
let nonce = rand::thread_rng().gen();
let message = GovernancePayloadTransferFees {
amount: 500u128.into(),
to: payer.pubkey().to_bytes(),
}
.try_to_vec()
.unwrap();
let message_key = common::post_message(
client,
program,
payer,
&emitter,
None,
nonce,
message.clone(),
500,
)
.await
.unwrap();
common::transfer_fees(
client,
program,
payer,
message_key,
emitter.pubkey(),
payer.pubkey(),
sequence,
)
.await
.unwrap();
common::sync(client, payer).await;
}
// Ensure that the account has the same amount of money as we started with
let account_balance = common::get_account_balance(client, fee_collector).await;
assert_eq!(account_balance, initial_balance);
// Next, make sure that we can still post a message.
{
let emitter = Keypair::new();
let nonce = rand::thread_rng().gen();
let message: [u8; 32] = rand::thread_rng().gen();
common::post_message(
client,
program,
payer,
&emitter,
None,
nonce,
message.to_vec(),
500,
)
.await
.unwrap();
}
}
// Make sure that solitaire can claim accounts that already hold lamports so the protocol can't be
// DoSd by someone funding derived accounts making CreateAccount fail.
#[tokio::test]