How Solana validators catch duplicated transactions without nonce?

Hello, I have several questions about transaction & validators. If anyone knows of any of these questions, I’d appreciate an answer.

  1. From my current understanding, it needs maximum 32 blocktime so that we can know whether our transactions successfully included in blockchain or not. This is because Solana’s current maximum rollback depth is 32. This requires approximately 24s(with blocktime 800ms). But this time frame is too long. How much time is needed on average that I can convince my transaction is included in blockchain with confidence 100%, 90% or 80%?

  2. In Ethereum, duplicated transactions be effectively dropped via each account’s “nonce”. But solana does not have it. How solana catch duplicate transactions and drop them except only one? I read Soalna docs and ‘recent block hash’ manage this, but I think this is too weak condition to do it.

  3. How validator order incomming transactions? Just by incomming order? Then how we trust that they do so? I think the answer is that we don’t know whether actually they order them in incomming order or not, and ordering is validators privilege to do so. This is because we cannot distinguish failure from malicious validator between failure from network dropping. Is this correct?

  4. In ethereum, as I know, there is an MEV. In detail, miners can see transactions metadata which tells what functions in contract will be executed. So they see metadata, and get profit from them by front-running attack or sandwitch them. Is this possible in Solana also? In short, Is it possible for validators to see transactions metadata?

I’m unsure the details of Solana’s validator protocol or rollbacks, etc. You might find more knowledgeable people on Discord for that topic.

But, I do believe that transactions on Solana are finalized, aka. 100% permanent and included on the chain, in less than 5 minutes ( maybe less than 1 minute ).

You can see this on explorers such as Solscan. Right when you submit a transaction, if you try to view it in Solscan, it will actually show as pending, and it will show how many verifications the transaction has gotten before finally showing that it got MAX confirmations and is final.

That said, I could be wrong about this, because I’m not sure how rollbacks work.

Why would the recent block hash solution not be sufficient do you think? I think that is supposed to be all that’s necessary to prevent the issue.

I’d love to hear what situation you think that might not work in, if you can think of anything. This sounds like a fun puzzle. :slight_smile:

I’m almost 100% positive it’s not incomming order. There’s no way to verify incomming order.

I’m not how this is done in Solana exactly, but the concept might be somewhat similar to what is described in Tendermint Concensus. Whether or not Solana uses the same algorithm, the concept is probably similar, which is that there is a process by which all the validators go through in order to deliberate and eventually agree on the order that transactions are executed in.

This process, in Tendermint at least, can tolerate up to any amount less than 1/3 of the nodes being totally malicious while still being able to continue and come to agreement on the order of the transactions. And I believe that malicious nodes will actually stick out and be noticeable by the other nodes in that process.

I think so, but I’m not positive. You’d have to ask someone else, probably on Discord. I think I’ve heard that these kinds of things are somewhat possible in Solana, but they might be thinking about strategies to reduce the threat in the future. I can’t remember for sure, though.


Why would the recent block hash solution not be sufficient do you think? I think that is supposed to be all that’s necessary to prevent the issue.

For example in Ethereum, if a user send a transaction X with nonce N, after then he cannot send the transaction X with nonce N regardless of when he send a transaction, But in Solana, if I send a transaction X, and send X again after sufficiently long time, there is no way to discard this transaction X because recentBlock hash were changed.

Above example it bit overbearing, but because of such cases, I think recent blockhash is not enough to replace nonce

Ah, but you aren’t allowed to send a transaction if the recent blockhash is older than about two minutes!

So, during that two-minute period, as far as I understand, you aren’t allowed to send the transaction twice, because Solana assumes it’s a duplicate because the recent block-hash is the same as another transaction submitted very recently and the transaction data is identical.

And after that two minute period, you aren’t allowed to send the same transaction twice because the recent blockhash isn’t recent enough, and so the transaction is discarded.

I think it’s all safe!

I’m not super positive that’s all right, so don’t take my word for it, but I think it makes sense.

1 Like

Oh, I’m not sure I understood you correctly initially.

Just to be clear, the transaction signature includes the recent blockhash. And a transaction ID is actually the primary signer’s signature for that transaction.

That mean’s that you can’t re-send the same transaction, without changing the recent blockhash of the transaction and re-signing the transaction, which will result in a different signature, and a different transaction ID.

So, that actually means that it’s impossible to send the same transaction twice, just because that transaction ID already exists.

1 Like

If two transactions have equal recentblockhash and context of transaction, then two transactions will be regarded as same. I agree with this. But if recentblock hash is different, then two transactions will be regarded as different.

The reason why I consider such case is because in Solana web3 json RPC method, in sendTransaction method, recentBlockhash is “OPTIONAL” parameter. So I thought naive developers could confront such case if they did not set recentBlockhash properly + when they send transactions quickly. Maybe I have to see how recentblockhash will be set if I didn’t set it.

But if recentblockhash is properly set every time I send transaction, then as you said, it could be impossible to duplicate same transaction.

I think this question is a bit ambiguous because the definition of ‘duplicated transaction’ is different between ethereum and solana. Anyway, I now agree with that recentblockhash is enough to prevent duplicated transactions!

Ah, I see why that would raise concern.

The recent blockhash is 100% required at the data level to send a transaction. See the docs here. So that will solve even the naive developer problem.

If we look at the code for web3.js we see that composing a transaction will fail if it doesn’t have a recent blockchash:

Because the blockhash is a part of the Message which is what gets signed by the user, if a developer were to somehow try to submit the same transaction multiple times with a different recent blockhash, the user would actually have to sign the transaction multiple times, which would probably be apparent to the user that they are actually performing the operation again.

It looks like the recent blockhash is optional because it will automatically go and get one when you sign the transaction. So it would be harder for a programmer to mistakenly have the user sign the transaction multiple times the developer just intended to retry because of a failed send or something of that sort.

Anyway, looks safe, but this was fun to look into!

1 Like