fix: batch transactions view recovered and support of proofs through ZkSync Hyperchain (#10234)

* unified tx_hash field with Arbitrum batch transaction

* Supported yet another contract function to submit batches proofs

* fixed formatting issue
pull/10240/head
Alexander Kolotov 6 months ago committed by GitHub
parent aaed915990
commit c31f937680
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      apps/explorer/lib/explorer/chain/import/runner/zksync/batch_transactions.ex
  2. 2
      apps/explorer/lib/explorer/chain/transaction.ex
  3. 38
      apps/explorer/lib/explorer/chain/zksync/batch_transaction.ex
  4. 7
      apps/explorer/priv/zk_sync/migrations/20240611091814_rename_field_in_batch_transactions.exs
  5. 2
      apps/indexer/lib/indexer/fetcher/zksync/discovery/batches_data.ex
  6. 123
      apps/indexer/lib/indexer/fetcher/zksync/status_tracking/proven.ex

@ -60,7 +60,7 @@ defmodule Explorer.Chain.Import.Runner.ZkSync.BatchTransactions do
| {:error, [Changeset.t()]}
def insert(repo, changes_list, %{timeout: timeout, timestamps: timestamps} = _options) when is_list(changes_list) do
# Enforce ZkSync.BatchTransaction ShareLocks order (see docs: sharelock.md)
ordered_changes_list = Enum.sort_by(changes_list, & &1.hash)
ordered_changes_list = Enum.sort_by(changes_list, & &1.tx_hash)
{:ok, inserted} =
Import.insert_changes_list(
@ -70,7 +70,7 @@ defmodule Explorer.Chain.Import.Runner.ZkSync.BatchTransactions do
returning: true,
timeout: timeout,
timestamps: timestamps,
conflict_target: :hash,
conflict_target: :tx_hash,
on_conflict: :nothing
)

@ -110,7 +110,7 @@ defmodule Explorer.Chain.Transaction.Schema do
elem(
quote do
has_one(:zksync_batch_transaction, ZkSyncBatchTransaction,
foreign_key: :hash,
foreign_key: :tx_hash,
references: :hash
)

@ -1,24 +1,38 @@
defmodule Explorer.Chain.ZkSync.BatchTransaction do
@moduledoc "Models a list of transactions related to a batch for ZkSync."
@moduledoc """
Models a list of transactions related to a batch for ZkSync.
Changes in the schema should be reflected in the bulk import module:
- Explorer.Chain.Import.Runner.ZkSync.BatchTransactions
Migrations:
- Explorer.Repo.ZkSync.Migrations.CreateZkSyncTables
- Explorer.Repo.ZkSync.Migrations.RenameFieldInBatchTransactions
"""
use Explorer.Schema
alias Explorer.Chain.{Hash, Transaction}
alias Explorer.Chain.ZkSync.TransactionBatch
@required_attrs ~w(batch_number hash)a
@type t :: %__MODULE__{
batch_number: non_neg_integer(),
batch: %Ecto.Association.NotLoaded{} | TransactionBatch.t() | nil,
hash: Hash.t(),
l2_transaction: %Ecto.Association.NotLoaded{} | Transaction.t() | nil
}
@required_attrs ~w(batch_number tx_hash)a
@typedoc """
* `tx_hash` - The hash of the rollup transaction.
* `l2_transaction` - An instance of `Explorer.Chain.Transaction` referenced by `tx_hash`.
* `batch_number` - The number of the ZkSync batch.
* `batch` - An instance of `Explorer.Chain.ZkSync.TransactionBatch` referenced by `batch_number`.
"""
@primary_key false
schema "zksync_batch_l2_transactions" do
typed_schema "zksync_batch_l2_transactions" do
belongs_to(:batch, TransactionBatch, foreign_key: :batch_number, references: :number, type: :integer)
belongs_to(:l2_transaction, Transaction, foreign_key: :hash, primary_key: true, references: :hash, type: Hash.Full)
belongs_to(:l2_transaction, Transaction,
foreign_key: :tx_hash,
primary_key: true,
references: :hash,
type: Hash.Full
)
timestamps()
end
@ -32,6 +46,6 @@ defmodule Explorer.Chain.ZkSync.BatchTransaction do
|> cast(attrs, @required_attrs)
|> validate_required(@required_attrs)
|> foreign_key_constraint(:batch_number)
|> unique_constraint(:hash)
|> unique_constraint(:tx_hash)
end
end

@ -0,0 +1,7 @@
defmodule Explorer.Repo.ZkSync.Migrations.RenameFieldInBatchTransactions do
use Ecto.Migration
def change do
rename(table(:zksync_batch_l2_transactions), :hash, to: :tx_hash)
end
end

@ -400,7 +400,7 @@ defmodule Indexer.Fetcher.ZkSync.Discovery.BatchesData do
[
%{
batch_number: block.batch_number,
hash: l2_tx_hash
tx_hash: l2_tx_hash
}
| l2_txs
]

@ -12,7 +12,7 @@ defmodule Indexer.Fetcher.ZkSync.StatusTracking.Proven do
associate_and_import_or_prepare_for_recovery: 4
]
import Indexer.Fetcher.ZkSync.Utils.Logging, only: [log_info: 1]
import Indexer.Fetcher.ZkSync.Utils.Logging, only: [log_error: 1, log_info: 1]
@doc """
Checks if the oldest unproven batch in the database has the associated L1 proving transaction
@ -68,8 +68,6 @@ defmodule Indexer.Fetcher.ZkSync.StatusTracking.Proven do
end
defp get_proven_batches_from_calldata(calldata) do
"0x7f61885c" <> encoded_params = calldata
# /// @param batchNumber Rollup batch number
# /// @param batchHash Hash of L2 batch
# /// @param indexRepeatedStorageChanges The serial number of the shortcut index that's used as a unique identifier for storage keys that were used twice or more
@ -93,41 +91,90 @@ defmodule Indexer.Fetcher.ZkSync.StatusTracking.Proven do
# uint256[] recursiveAggregationInput;
# uint256[] serializedProof;
# }
# proveBatches(StoredBatchInfo calldata _prevBatch, StoredBatchInfo[] calldata _committedBatches, ProofInput calldata _proof)
# IO.inspect(FunctionSelector.decode("proveBatches((uint64,bytes32,uint64,uint256,bytes32,bytes32,uint256,bytes32),(uint64,bytes32,uint64,uint256,bytes32,bytes32,uint256,bytes32)[],(uint256[],uint256[]))"))
[_prev_batch, proven_batches, _proof] =
TypeDecoder.decode(
Base.decode16!(encoded_params, case: :lower),
%FunctionSelector{
function: "proveBatches",
types: [
tuple: [
uint: 64,
bytes: 32,
uint: 64,
uint: 256,
bytes: 32,
bytes: 32,
uint: 256,
bytes: 32
],
array:
{:tuple,
[
uint: 64,
bytes: 32,
uint: 64,
uint: 256,
bytes: 32,
bytes: 32,
uint: 256,
bytes: 32
]},
tuple: [array: {:uint, 256}, array: {:uint, 256}]
]
}
)
proven_batches =
case calldata do
"0x7f61885c" <> encoded_params ->
# proveBatches(StoredBatchInfo calldata _prevBatch, StoredBatchInfo[] calldata _committedBatches, ProofInput calldata _proof)
# IO.inspect(FunctionSelector.decode("proveBatches((uint64,bytes32,uint64,uint256,bytes32,bytes32,uint256,bytes32),(uint64,bytes32,uint64,uint256,bytes32,bytes32,uint256,bytes32)[],(uint256[],uint256[]))"))
[_prev_batch, proven_batches, _proof] =
TypeDecoder.decode(
Base.decode16!(encoded_params, case: :lower),
%FunctionSelector{
function: "proveBatches",
types: [
tuple: [
uint: 64,
bytes: 32,
uint: 64,
uint: 256,
bytes: 32,
bytes: 32,
uint: 256,
bytes: 32
],
array:
{:tuple,
[
uint: 64,
bytes: 32,
uint: 64,
uint: 256,
bytes: 32,
bytes: 32,
uint: 256,
bytes: 32
]},
tuple: [array: {:uint, 256}, array: {:uint, 256}]
]
}
)
proven_batches
"0xc37533bb" <> encoded_params ->
# proveBatchesSharedBridge(uint256 _chainId, StoredBatchInfo calldata _prevBatch, StoredBatchInfo[] calldata _committedBatches, ProofInput calldata _proof)
# IO.inspect(FunctionSelector.decode("proveBatchesSharedBridge(uint256,(uint64,bytes32,uint64,uint256,bytes32,bytes32,uint256,bytes32),(uint64,bytes32,uint64,uint256,bytes32,bytes32,uint256,bytes32)[],(uint256[],uint256[]))"))
[_chainid, _prev_batch, proven_batches, _proof] =
TypeDecoder.decode(
Base.decode16!(encoded_params, case: :lower),
%FunctionSelector{
function: "proveBatchesSharedBridge",
types: [
{:uint, 256},
tuple: [
uint: 64,
bytes: 32,
uint: 64,
uint: 256,
bytes: 32,
bytes: 32,
uint: 256,
bytes: 32
],
array:
{:tuple,
[
uint: 64,
bytes: 32,
uint: 64,
uint: 256,
bytes: 32,
bytes: 32,
uint: 256,
bytes: 32
]},
tuple: [array: {:uint, 256}, array: {:uint, 256}]
]
}
)
proven_batches
_ ->
log_error("Unknown calldata format: #{calldata}")
[]
end
log_info("Discovered #{length(proven_batches)} proven batches in the prove tx")

Loading…
Cancel
Save