Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Add set_account to solana-program-test #21415

Merged
merged 1 commit into from
Nov 24, 2021

Conversation

ruuda
Copy link
Contributor

@ruuda ruuda commented Nov 24, 2021

Problem

It is extremely tedious, and sometimes impossible, to recreate certain states of the bank using solana_program_test. When it is tedious to write tests for common Solana attack vectors, that results in those tests not being written at all.

Summary of Changes

Add a “god mode” to ProgramTestContext: a method set_account that allows you to arbitrarily change accounts. This allows us to jump to states of the bank that would otherwise be tedious or impossible to reach.

Details

For writing tests, it is often desirable to create a certain situation that would be tedious, or even impossible to create by sending individual transactions.

For example, a common attack vector on Solana is to create a copy of some existing account that stores configuration data, but manipulate the data stored there, and then to call a program and pass in the manipulated account, instead of the real account.

If one wants to test this, one option is to write a program that you can call to write arbitrary data into a new account account (and possibly change its owner), then include that program in the test context, and send a transaction to call it. This is extremely tedious, and developers are not going to bother doing it. I myself would rather fork solana-program-test to add this set_account method, than to write that program. Having a “god mode” method to just write an account, lowers the barrier to writing comprehensive tests.

A second reason for introducing this method, is defense in depth. There may be states of the bank that are not reachable yet by only sending transactions, but that you might want to test against either way. For example, right now, the balance of a stake account cannot decrease without going through the stake program. But what if Solana were to introduce slashing in the future, and you want to ensure your program is robust against decreases in stake account balance? Right now there is no way to test this, but by introducing this “god mode” to write accounts, the situation becomes testable.

For writing tests, it is often desirable to create a certain situation
that would be tedious, or even impossible to create by sending
individual transactions.

For example, a common attack vector on Solana is to create a copy of
some existing account that stores configuration data, but manipulate the
data stored there, and then to call a program and pass in the
manipulated account, instead of the real account.

If one wants to test this, one option is to write a program that you can
call to write arbitrary data into a new account account (and possibly
change its owner), then include that program in the test context, and
send a transaction to call it. This is extremely tedious, and developers
are not going to bother doing it. I myself would rather fork
solana-program-test to add this `set_account` method, than to write that
program. Having a “god mode” method to just write an account, lowers the
barrier to writing comprehensive tests.

A second reason for introducing this method, is defense in depth. There
may be states of the bank that are not reachable *yet* by only sending
transactions, but that you might want to test against either way. For
example, right now, the balance of a stake account cannot decrease
without going through the stake program. But what if Solana were to
introduce slashing in the future, and you want to ensure your program is
robust against decreases in stake account balance? Right now there is no
way to test this, but by introducing this “god mode” to write accounts,
the situation becomes testable.
@mergify mergify bot added the community Community contribution label Nov 24, 2021
@mergify mergify bot requested a review from a team November 24, 2021 13:53
Copy link
Contributor

@jstarry jstarry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very useful, thanks! Now we just need something like this for solana-test-validator!

@jstarry jstarry added automerge Merge this Pull Request automatically once CI passes v1.8 labels Nov 24, 2021
@mergify mergify bot requested a review from a team November 24, 2021 14:24
@mergify mergify bot removed the automerge Merge this Pull Request automatically once CI passes label Nov 24, 2021
@mergify
Copy link
Contributor

mergify bot commented Nov 24, 2021

automerge label removed due to a CI failure

@jstarry jstarry merged commit e7fa412 into solana-labs:master Nov 24, 2021
mergify bot pushed a commit that referenced this pull request Nov 24, 2021
For writing tests, it is often desirable to create a certain situation
that would be tedious, or even impossible to create by sending
individual transactions.

For example, a common attack vector on Solana is to create a copy of
some existing account that stores configuration data, but manipulate the
data stored there, and then to call a program and pass in the
manipulated account, instead of the real account.

If one wants to test this, one option is to write a program that you can
call to write arbitrary data into a new account account (and possibly
change its owner), then include that program in the test context, and
send a transaction to call it. This is extremely tedious, and developers
are not going to bother doing it. I myself would rather fork
solana-program-test to add this `set_account` method, than to write that
program. Having a “god mode” method to just write an account, lowers the
barrier to writing comprehensive tests.

A second reason for introducing this method, is defense in depth. There
may be states of the bank that are not reachable *yet* by only sending
transactions, but that you might want to test against either way. For
example, right now, the balance of a stake account cannot decrease
without going through the stake program. But what if Solana were to
introduce slashing in the future, and you want to ensure your program is
robust against decreases in stake account balance? Right now there is no
way to test this, but by introducing this “god mode” to write accounts,
the situation becomes testable.

(cherry picked from commit e7fa412)
mvines pushed a commit that referenced this pull request Nov 29, 2021
For writing tests, it is often desirable to create a certain situation
that would be tedious, or even impossible to create by sending
individual transactions.

For example, a common attack vector on Solana is to create a copy of
some existing account that stores configuration data, but manipulate the
data stored there, and then to call a program and pass in the
manipulated account, instead of the real account.

If one wants to test this, one option is to write a program that you can
call to write arbitrary data into a new account account (and possibly
change its owner), then include that program in the test context, and
send a transaction to call it. This is extremely tedious, and developers
are not going to bother doing it. I myself would rather fork
solana-program-test to add this `set_account` method, than to write that
program. Having a “god mode” method to just write an account, lowers the
barrier to writing comprehensive tests.

A second reason for introducing this method, is defense in depth. There
may be states of the bank that are not reachable *yet* by only sending
transactions, but that you might want to test against either way. For
example, right now, the balance of a stake account cannot decrease
without going through the stake program. But what if Solana were to
introduce slashing in the future, and you want to ensure your program is
robust against decreases in stake account balance? Right now there is no
way to test this, but by introducing this “god mode” to write accounts,
the situation becomes testable.

(cherry picked from commit e7fa412)
t-nelson added a commit to t-nelson/solana that referenced this pull request Dec 13, 2021
tao-stones pushed a commit that referenced this pull request Dec 13, 2021
CriesofCarrots pushed a commit to CriesofCarrots/solana that referenced this pull request Dec 16, 2021
CriesofCarrots pushed a commit that referenced this pull request Dec 17, 2021
@ruuda ruuda deleted the program-test-set-account branch July 15, 2022 13:33
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
community Community contribution
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants