Skip to content
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

Events might be dropped because Solana truncates Logs #1613

Closed
tlambertz opened this issue Mar 14, 2022 · 3 comments
Closed

Events might be dropped because Solana truncates Logs #1613

tlambertz opened this issue Mar 14, 2022 · 3 comments
Labels
bug Something isn't working lang

Comments

@tlambertz
Copy link

Problem

Anchor currently supports custom events and the emit! macro. It is not documented that these events might not always be delivered. Root cause is Solana's log truncation if it gets longer than 10kB.

This will likely confuse devs coming from Ethereum, where Events are special and always kept.

A malicious user could force log-truncation by including a "spam-log" IX as the first IX in a TX. Any programs called later in the same TX have no way of detecting the log truncation, and all events will be silently dropped.

Details

Take a look at https://github.com/solana-labs/solana/blob/49443406fd729c5818ecf58ae773592804d35d89/program-runtime/src/log_collector.rs#L34

Solana's LogCollector, when the log is larger than limit, simply emits Log truncated.
The limit is initialized as const LOG_MESSAGES_BYTES_LIMIT: usize = 10 * 1000;.

As far as I am aware, there is no way to extract truncated logs from an unpatched validator, since they are not even saved during the rBPF execution.

In many cases, the event might be reconstructable from the IX by looking at input account keys, spl-balance changes and the block timestamp.

But there are especially awkward cases if the event contains any information read from an account at the time the event is emitted. Account contents are NOT available historically. It thus might be impossible to determine what an event would have looked like, without chain replay to the block to reconstruct the account data.

Suggested Solution(s)

You should document the fact that events might not be emitted. Especially that a user can force them to not be emitted might be relevant from a security perspective.

The only way I know of, to 100% guarantee custom event delivery, is to write the event into a unique, rent-exempt account, that never changes. That way, the log is always available via RPC. But that's annoying and expensive :D Maybe it could get cleaned-up by some protocol-authority once it is consumed.

Or, a really hacky solution for short events:
Allow deletion only when you include the event data in the instruction data. Instruction data is permanently available via RPC, so you can always reconstruct events by looking at the "consume events" transactions.

@paul-schaaf
Copy link
Contributor

thanks for the detailed issue!

we're thinking of asking for a new syscall that returns the remaining log budget and then we can allow the user to make the program crash if it's smaller than the event length

@paul-schaaf
Copy link
Contributor

solana-labs/solana#23653

@acheroncrypto
Copy link
Collaborator

Resolved by #2438

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working lang
Projects
None yet
Development

No branches or pull requests

3 participants