Is the transaction hash unique in ICP?

Hello Everyone,
I was under the impression that transaction hash are unique. Also I understand its a hash, so there might be collisions. But the probability of those collisions should be very low ( correct me if I am wrong here ).

I saw one of the hash which is same for three transactions.

Another example:

Why are we seeing this collision very often or am I missing something here?

PS: Can someone also point to the algorithm which calculates this hash from github ?

1 Like

Uniqueness of transaction hash is guaranteed for the transactions that have the created_at field set.
For these transactions the ledger ensures dedication. If created_at is not set then there may be duplicates

  1. Can you please elaborate more on “For these transactions the ledger ensures dedication”.
  2. Who is responsible for setting created_at.
  3. How does one refer to a particular transaction? Shouldn’t there be a unique attribute to a transaction? I understand for now one block has one transaction, in this case block_number can be considered unique.
    Is there a possibility in the future that one block can process multiple transactions ?
1 Like
  1. That was a typo :(. I meant the ledger ensures deduplication: there will never be two identical transactions that have created_at set.
  2. It’s the initiator of the transaction that should set it. There is no good reason not to set it - but unfortunately for historical reasons the created_at field is optional.
  3. The guarantee that we will always have is that within the same block (even if there were more transactions) all transactions will have unique hashes. So the pair (block_id, tx_hash) should be a unique identifier. However, it is safe to say that in the ICP ledger will never have more than one transaction per block, so the block identifier would also be a unique identifier.

Shouldn’t this be fixed?

Wasn’t aware that transaction hashes cannot be trusted as unique identifiers.

Transaction indexes are incremental unique identifiers (also mentioned as blocks above), the hashes are unique for the transaction data, this makes it e.g. possible to find a transaction when you know it’s details but not the index (create hash based on details and lookup hash).

When you make a transaction, the index is returned as reference.

As far as I’m aware, every index contains a single transaction in the current ledger implementation.

The transaction hash is the unique representation of the transaction data (with or without created_at). It is not the unique identifier for the transaction within the ledger transaction history. This is not known until the transaction has been sent to the ledger and added to the history, it’s position within the history is then returned as index.