-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Prevent creation of rent-paying accounts with non-empty data #21142
Prevent creation of rent-paying accounts with non-empty data #21142
Conversation
bf2f3f3
to
d7cdfdd
Compare
d7cdfdd
to
6030078
Compare
6030078
to
e56efdd
Compare
if account.lamports() == 0 { | ||
Self::Uninitialized | ||
} else if native_loader::check_id(account.owner()) || sysvar::is_sysvar_id(account.owner()) | ||
{ | ||
Self::NativeOrSysvar | ||
} else if account.data().is_empty() { | ||
Self::EmptyData | ||
} else if !rent.is_exempt(account.lamports(), account.data().len()) { | ||
Self::RentPaying | ||
} else { | ||
Self::RentExempt | ||
} |
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.
Technically, we could make do without the enum, and boil this logic down to a bool
: is RentPaying or not. I rather like how explicit and clear the variants make the logic and exceptions, but open to other opinions.
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.
The enum is helpful to me! I always appreciate the added type safety as well.
accounts[i].0, | ||
accounts[i].1.borrow().lamports() | ||
); | ||
*process_result = Err(TransactionError::InvalidRentPayingAccount) |
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.
I don't think we want to return a TransactionError
after processing a transaction. That means it's free to process potentially expensive transactions since fees aren't deducted for tx errors.
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.
Yeah, I was pondering adding this TransactionError as a special case in filter_program_errors_and_collect_fee()
. But perhaps a better approach would be to pass the rent information into the message processor and evaluate on a per-instruction basis with the other pre/post processing checks. Thoughts?
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.
I think it's fine to use non-rent-exempt accounts between instructions for passing data around. Would your change prevent that?
I think that putting the rent changes inside |
As for accounts without data, could the network have a hard cap on the number of such accounts (or the I think of it as a safety check that would not affect account creation normally, but would come into play if the cluster gets flooded with creation of tiny data len 0 accounts that are not rent-exempt. Tentatively, a cap of 100M of such non-rent-exempt accounts is probably desirable. If you'd like me to PR this in, I'd be happy to do so. |
I don't really like that method for this. To me, this check should be reflected in TransactionExecutionResults, not some separate new thing. |
Could you share your reasoning? I still think that |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
Problem
A single epoch's worth of rent for an account with data is too little relative to the costs of storing that data.
Summary of Changes
Compare rent-exemption status pre- and post-processing; fail if any end up RentPaying that didn't start that way.