-
Notifications
You must be signed in to change notification settings - Fork 7
CLI helper: Wrap #38
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
CLI helper: Wrap #38
Conversation
clients/cli/src/create_mint.rs
Outdated
#[serde_as(as = "DisplayFromStr")] | ||
pub wrapped_mint_address: Pubkey, | ||
#[serde_as(as = "DisplayFromStr")] | ||
pub wrapped_mint_authority: Pubkey, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found myself needing the wrapped mint authority from the previous step (CreateMint) for the wrap command. In fact, will have another PR to expose CLI utilities for getting access to stuff like this at any time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need this in production, or only tests? Because it looks to me like you're deriving it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was mistaken here. There is not a need to pass the wrapped mint authority to the wrap command. Will delete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great, just a few questions from my side, really.
clients/cli/src/create_mint.rs
Outdated
#[serde_as(as = "DisplayFromStr")] | ||
pub wrapped_mint_address: Pubkey, | ||
#[serde_as(as = "DisplayFromStr")] | ||
pub wrapped_mint_authority: Pubkey, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need this in production, or only tests? Because it looks to me like you're deriving it.
clients/cli/tests/helpers.rs
Outdated
}; | ||
let mut data = vec![0u8; spl_token::state::Mint::LEN]; | ||
state.pack_into_slice(&mut data); | ||
pub async fn create_unwrapped_mint( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For what it's worth, I prefer the startup account fixtures approach you had here originally. I saw the back-and-forth over here, so I'll leave it up to you to choose which you prefer, and it seems you have.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a reason for that preference?
We've had false positives in the past due to improper setup in tests, so I lean towards the more complicated setup to be sure we're actually testing a real-world situation.
We can certainly stick with fixtures for unit tests, but for a CLI, an end-to-end test is more useful to test the whole flow, but maybe I'm missing some context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a reason for that preference?
I have formed a bias toward fixtures for a number of reasons, but it spawned from unit testing the RPC API for @solana/kit
and has been hardened through writing program unit tests with Mollusk. It was also the motivation for building the latter.
The crux of the fixtures/mocks approach is the belief that your unit tests should be testing a single unit in isolation. If you're trying to test function C and its setup depends on functions A and B, now your tests for C are all coupled to functions A and B.
What if, all this time, CreateMint
was doing something slightly erroneous, and we were getting all false positives in Wrap
and Unwrap
? It might sound ridiculous, but it happens.
Fixtures/mocks also let you set up a wide array of edge cases, which might be complex to set up through transactions (perhaps they would require a custom program, for example).
I also think if we're going to write unit tests that use separate test-validator instances, the faster they spin up and then back down, the better. That means less "send and confirm".
We can certainly stick with fixtures for unit tests, but for a CLI, an end-to-end test is more useful to test the whole flow, but maybe I'm missing some context.
I suppose I would just set up the per-command unit tests in isolation and then have one or more aptly-labeled end-to-end tests for the whole flow. I wouldn't make every CLI test an end-to-end test.
We've had false positives in the past due to improper setup in tests, so I lean towards the more complicated setup to be sure we're actually testing a real-world situation.
Without knowing the context of these false positives I don't want to make any assumptions, but I generally think this is an acceptable risk compared to coupling too many things within each test.
Anyway, that's just my two cents! If you both disagree with me, you can do what you think is best! If we're only testing for success within the CLI tests, and nothing else, maybe it doesn't matter anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my experience, there's a much higher chance of false positives with unit-testing than end-to-end testing because you can setup any set of inputs. As one example, remember all of the firedancer conformance fixtures that were checking impossible situations?
On the flip side, I'll definitely admit that highly-coupled tests are a lot more work to maintain. But I still stick by these words: Write tests. Not too many. Mostly integration
For now, since we don't have integration tests otherwise, I lean towards doing them here in the CLI. But we can let Gabe be the tie-breaker 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely can see the two sides to this. One benefit I've seen with these CLI tests making the actual calls is that it's shown me the real-life process the end-user will need to go through in order to make use of it. This inspired #40 because I ran into a user flow I wasn't fully supporting.
One thing to note is in the main program code with mollusk, the processor methods were tested in isolation with pre-made accounts passed in, which feels like it worked well given the variety of cases those tests covered. Given that, I think this program probably could use the "integration coverage" by continuing along the path of this PR. Will go that route for these CLI tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great overall! Mostly small things
clients/cli/tests/helpers.rs
Outdated
}; | ||
let mut data = vec![0u8; spl_token::state::Mint::LEN]; | ||
state.pack_into_slice(&mut data); | ||
pub async fn create_unwrapped_mint( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a reason for that preference?
We've had false positives in the past due to improper setup in tests, so I lean towards the more complicated setup to be sure we're actually testing a real-world situation.
We can certainly stick with fixtures for unit tests, but for a CLI, an end-to-end test is more useful to test the whole flow, but maybe I'm missing some context.
/// The address of the escrow account that will hold the unwrapped tokens | ||
#[clap(value_parser = parse_pubkey)] | ||
pub escrow_account: Pubkey, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't need to be done here, but we could eventually have a helper to create an escrow account, probably the wrapped mint authority's ATA for the unwrapped token mint would be good.
That way, we could make this optional too and default to that ATA
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to know. Helpful for a later PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few last nits, then this can go in from my side
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ship it!
The second CLI helper (after #33) for the
Wrap
instruction. Note, it only supports single signer at the moment.Walkthrough for testing locally:
token-wrap
command