Skip to content

Conversation

@kariy
Copy link
Member

@kariy kariy commented Sep 24, 2025

Current blocker:

  • adding the new class without breaking backward compatibility caused by different genesis state root

@kariy kariy added this to the 1.8.0 milestone Sep 25, 2025
kariy and others added 4 commits September 30, 2025 11:00
## 'Legacy' Transaction V3

When V3 transaction was first introduced in RPC [v0.6.0], the `resource_bounds` field consists of only two fields; `l1_gas` and `l2_gas`. These values are included in the hash computation for the V3 transaction. But RPC [v0.8.0], a new field is added to the mapping,
`l1_data_gas`. The addition of the new field means there are now two variations of the V3 transaction - with or without `l1_data_gas`. Depending on the presence of the field, the transaction hash is computed differently.

Transaction V3 w/o `l1_data_gas` (legacy) hash:

```
h(
  "prefix",
  version,
  sender_address,
  h(tip, l1_gas_bounds, l2_gas_bounds),
  h(paymaster_data),
  chain_id,
  nonce,
  data_availability_modes,
  h(account_deployment_data),
  h(calldata)
)
```

Transaction V3 w/ `l1_data_gas` hash:

```
h(
  "prefix",
  version,
  sender_address,
  h(tip, l1_gas_bounds, l2_gas_bounds, l1_data_gas_bounds),
  h(paymaster_data),
  chain_id,
  nonce,
  data_availability_modes,
  h(account_deployment_data),
  h(calldata)
)
```

V3 transaction without the `l1_data_gas` is referred to as 'legacy' V3.

## Previous Refactors

When pull request [#141] was made, I didn't take into account the possibility that a transaction with 'legacy' resource bounds would have a nonzero `l2_gas`. Hence why in that pull request, the `ResourceBoundsMapping::L1Gas` wraps a `ResourceBounds` struct - intended only for the `l1_gas` field.

Currently, when computing the hash for transaction that uses the legacy resource bounds mapping, Katana naively assumes that the `l2_gas` bounds is 0. While this is true for most part, because some Starknet client libraries (eg `starknet-rs`) hardcoded the `l2_gas` to 0, but this doesn't fully negate the possibility that a transaction could be submitted with non-zero `l2_gas`.

Even though the `l2_gas` wasn't actually used for execution, it is still used to compute the hash for the transaction. Preserving all the bounds is important if we want to make sure the hashes of transactions stored in the Katana database are reproducible!

Honestly, if we only consider the transaction version that Katana supports now - 0.14.0 compatible transaction where all 3 bounds must be present - then this change really doesn't do anything at all. Transactions using legacy resource bounds will be outright rejected by the RPC server, and we don't have to worry about ensuring their hashes reproducibility. This change only matters once we have Katana running as a full node, syncing from Starknet mainnet/sepolia where transactions with only `l1_gas` and `l2_gas` resource bounds exist. As such, it is important that all details of a transaction is preserved correctly.

## Database Compatibility

This change isn't compatible with the current database format. As such a database version bump is required!

[v0.6.0]:
https://github.com/starkware-libs/starknet-specs/blob/49665932a97f8fdef7ac5869755d2858c5e3a687/api/starknet_api_openrpc.json#L3714
[v0.8.0]:
https://github.com/starkware-libs/starknet-specs/blob/b4f81445c79b2a8b2b09ff5bb2b7eddca78a32de/api/starknet_api_openrpc.json#L3494-L3514
[#141]: #141

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants