-
Notifications
You must be signed in to change notification settings - Fork 0
setup reclaim order #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kaze-cow
wants to merge
27
commits into
main
Choose a base branch
from
kaze/sc-150-close-order-account
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
9ce4ad9
setup reclaim order
kaze-cow 555239a
fix lints and errors
kaze-cow 013557a
simplify reclaim order test even more
kaze-cow b892ae7
Merge branch 'main' into kaze/sc-150-close-order-account
kaze-cow 9199880
stub timestamp function only runs when explicit feature is enabled
kaze-cow 83e3556
Merge branch 'kaze/sc-150-close-order-account' of https://github.com/…
kaze-cow ce3280c
Merge branch 'main' into kaze/sc-150-close-order-account
kaze-cow 68a3bea
Update interface/src/instruction/reclaim_order.rs
kaze-cow 8919f68
Update programs/settlement/src/reclaim_order.rs
kaze-cow 76e8434
Update programs/settlement/src/reclaim_order.rs
kaze-cow af95669
Update programs/settlement/tests/reclaim_order.rs
kaze-cow 3d25f1f
remove settlement-test-clock and related unit test, will move to inte…
kaze-cow 908681b
fix test error
kaze-cow c6627d7
fix lint failures
kaze-cow 8a4a989
use signed_tx helper
kaze-cow 9ed99a6
remove unnecessary test
kaze-cow ffdefe4
add a helper function to load an order account with canonical safety …
kaze-cow a7afebd
use suggested code from pinnochio to construct an account with fake data
kaze-cow 4c045d4
just fmt
kaze-cow fee918a
Merge branch 'main' into kaze/sc-150-close-order-account
kaze-cow e0c8467
Update interface/src/instruction/mod.rs
kaze-cow ba0fd79
Update interface/src/instruction/reclaim_order.rs
kaze-cow bfb85ae
Update programs/settlement/src/reclaim_order.rs
kaze-cow 09b2d87
Update programs/settlement/tests/reclaim_order.rs
kaze-cow ed4b7e1
Update interface/src/data/order.rs
kaze-cow a2d2d99
Merge branch 'main' into kaze/sc-150-close-order-account
kaze-cow a227027
fix lints and remove AFTER_EXPIRY
kaze-cow File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,192 @@ | ||
| //! `ReclaimOrder` instruction builder. | ||
| //! | ||
| //! Closes an expired order PDA and returns its rent lamports to the | ||
| //! `created_by` account recorded in the order body. The instruction may only be | ||
| //! executed after the order's `valid_to` timestamp has elapsed. | ||
| //! | ||
| //! Wire format: `[discriminator=5]`, 1 byte. | ||
| //! Required accounts: | ||
| //! `[order_pda (W), reclaim_recipient (W)]`. | ||
|
|
||
| use solana_account_view::AccountView; | ||
| use solana_instruction::{AccountMeta, Instruction}; | ||
| use solana_program_error::ProgramError; | ||
| use solana_pubkey::Pubkey; | ||
|
|
||
| use super::InstructionInputParsing; | ||
| use crate::SettlementInstruction; | ||
|
|
||
| /// Builder for a `ReclaimOrder` instruction. | ||
| /// | ||
| /// `order_pda` is the canonical order PDA to close. `reclaim_recipient` must | ||
| /// be the account recorded as `created_by` in the order PDA; it receives the | ||
| /// recovered rent lamports. The instruction enforces no signature requirement: | ||
| /// anyone may reclaim an expired order on behalf of its reclaim_recipient. | ||
| pub struct ReclaimOrder { | ||
| pub program_id: Pubkey, | ||
| pub order_pda: Pubkey, | ||
| pub reclaim_recipient: Pubkey, | ||
| } | ||
|
|
||
| impl ReclaimOrder { | ||
| pub fn instruction(self) -> Instruction { | ||
| Instruction { | ||
| program_id: self.program_id, | ||
| accounts: vec![ | ||
| AccountMeta::new(self.order_pda, false), | ||
| AccountMeta::new(self.reclaim_recipient, false), | ||
| ], | ||
| data: vec![SettlementInstruction::ReclaimOrder.discriminator()], | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Parsed inputs of a `ReclaimOrder` instruction. | ||
| pub struct ReclaimOrderInput<'a> { | ||
| pub order_pda: &'a mut AccountView, | ||
| pub reclaim_recipient: &'a mut AccountView, | ||
| } | ||
|
|
||
| impl<'a> InstructionInputParsing<'a> for ReclaimOrderInput<'a> { | ||
| const DISCRIMINATOR: SettlementInstruction = SettlementInstruction::ReclaimOrder; | ||
|
|
||
| fn parse_body( | ||
| instruction_data: &'a [u8], | ||
| accounts: &'a mut [AccountView], | ||
| ) -> Result<Self, ProgramError> { | ||
| // No instruction body: only the discriminator, already stripped. | ||
| if !instruction_data.is_empty() { | ||
| return Err(ProgramError::InvalidInstructionData); | ||
| } | ||
| let [order_pda, reclaim_recipient, ..] = accounts else { | ||
| return Err(ProgramError::NotEnoughAccountKeys); | ||
| }; | ||
| Ok(Self { | ||
| order_pda, | ||
| reclaim_recipient, | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| /// Test scaffolding for `ReclaimOrder` parsing, shared by this crate's tests | ||
| /// and the settlement program's via the `test-fixtures` feature. | ||
| #[cfg(any(test, feature = "test-fixtures"))] | ||
| pub mod fixtures { | ||
| use solana_address::Address; | ||
|
|
||
| use super::ReclaimOrder; | ||
|
|
||
| /// Number of accounts `ReclaimOrder` expects: order PDA and reclaim | ||
| /// recipient. | ||
| pub const NUM_ACCOUNTS: usize = 2; | ||
|
|
||
| /// `ReclaimOrder` instruction data with placeholder addresses. | ||
| pub fn default_reclaim_data() -> Vec<u8> { | ||
|
fedgiac marked this conversation as resolved.
|
||
| let zero = Address::new_from_array([0; 32]); | ||
| ReclaimOrder { | ||
| program_id: zero, | ||
| order_pda: zero, | ||
| reclaim_recipient: zero, | ||
| } | ||
| .instruction() | ||
| .data | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::fixtures::{default_reclaim_data, NUM_ACCOUNTS}; | ||
| use super::*; | ||
| use crate::instruction::fixtures::{fake_account, fake_sequential_accounts}; | ||
| use solana_address::Address; | ||
|
|
||
| #[test] | ||
| fn reclaim_order_input_parses_valid_input() { | ||
| let program_id = Address::new_from_array([1; 32]); | ||
| let order_pda = Address::new_from_array([2; 32]); | ||
| let reclaim_recipient = Address::new_from_array([3; 32]); | ||
|
|
||
| let data = ReclaimOrder { | ||
| program_id, | ||
| order_pda, | ||
| reclaim_recipient, | ||
| } | ||
| .instruction() | ||
| .data; | ||
| let mut accounts = [fake_account(order_pda), fake_account(reclaim_recipient)]; | ||
|
|
||
| let ReclaimOrderInput { | ||
| order_pda: derived_order_pda, | ||
| reclaim_recipient: derived_reclaim_recipient, | ||
| } = ReclaimOrderInput::parse(&data, &mut accounts).expect("parse should succeed"); | ||
|
|
||
| assert_eq!(*derived_order_pda.address(), order_pda); | ||
| assert_eq!(*derived_reclaim_recipient.address(), reclaim_recipient); | ||
| } | ||
|
|
||
| #[test] | ||
| fn reclaim_order_input_rejects_nonempty_body() { | ||
|
kaze-cow marked this conversation as resolved.
Outdated
|
||
| let mut data = default_reclaim_data(); | ||
| data.push(0); | ||
| let mut accounts = fake_sequential_accounts::<NUM_ACCOUNTS>(); | ||
| assert_eq!( | ||
| ReclaimOrderInput::parse(&data, &mut accounts).err(), | ||
| Some(ProgramError::InvalidInstructionData), | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn reclaim_order_input_rejects_missing_accounts() { | ||
|
kaze-cow marked this conversation as resolved.
|
||
| let data = default_reclaim_data(); | ||
| let mut accounts: Vec<AccountView> = fake_sequential_accounts::<NUM_ACCOUNTS>().into(); | ||
| accounts.pop(); | ||
| assert_eq!( | ||
| ReclaimOrderInput::parse(&data, &mut accounts).err(), | ||
| Some(ProgramError::NotEnoughAccountKeys), | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn instruction_data_has_expected_layout() { | ||
| let program_id = Address::new_from_array([1; 32]); | ||
| let order_pda = Address::new_from_array([2; 32]); | ||
| let reclaim_recipient = Address::new_from_array([3; 32]); | ||
|
|
||
| let ix = ReclaimOrder { | ||
| program_id, | ||
| order_pda, | ||
| reclaim_recipient, | ||
| } | ||
| .instruction(); | ||
|
|
||
| assert_eq!(ix.data.len(), 1); | ||
| assert_eq!( | ||
| ix.data[0], | ||
| SettlementInstruction::ReclaimOrder.discriminator() | ||
| ); | ||
|
kaze-cow marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| #[test] | ||
| fn instruction_data_has_expected_accounts() { | ||
| let program_id = Address::new_from_array([1; 32]); | ||
| let order_pda = Address::new_from_array([2; 32]); | ||
| let reclaim_recipient = Address::new_from_array([3; 32]); | ||
|
|
||
| let ix = ReclaimOrder { | ||
| program_id, | ||
| order_pda, | ||
| reclaim_recipient, | ||
| } | ||
| .instruction(); | ||
|
|
||
| assert_eq!(ix.accounts.len(), 2); | ||
| // order_pda: writable, not signer (the PDA being closed) | ||
| assert_eq!(ix.accounts[0].pubkey, order_pda); | ||
| assert!(ix.accounts[0].is_writable); | ||
| assert!(!ix.accounts[0].is_signer); | ||
| // reclaim_recipient: writable, not signer (receives the recovered rent) | ||
| assert_eq!(ix.accounts[1].pubkey, reclaim_recipient); | ||
| assert!(ix.accounts[1].is_writable); | ||
| assert!(!ix.accounts[1].is_signer); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.