parent
e630e51939
commit
6673b1cee1
@ -0,0 +1,76 @@ |
||||
defmodule Explorer.Chain.Import.Runner.ZkevmBatchTxns do |
||||
@moduledoc """ |
||||
Bulk imports `t:Explorer.Chain.ZkevmBatchTxn.t/0`. |
||||
""" |
||||
|
||||
require Ecto.Query |
||||
|
||||
alias Ecto.{Changeset, Multi, Repo} |
||||
alias Explorer.Chain.{Import, ZkevmBatchTxn} |
||||
alias Explorer.Prometheus.Instrumenter |
||||
|
||||
@behaviour Import.Runner |
||||
|
||||
# milliseconds |
||||
@timeout 60_000 |
||||
|
||||
@type imported :: [ZkevmBatchTxn.t()] |
||||
|
||||
@impl Import.Runner |
||||
def ecto_schema_module, do: ZkevmBatchTxn |
||||
|
||||
@impl Import.Runner |
||||
def option_key, do: :zkevm_batch_txns |
||||
|
||||
@impl Import.Runner |
||||
def imported_table_row do |
||||
%{ |
||||
value_type: "[#{ecto_schema_module()}.t()]", |
||||
value_description: "List of `t:#{ecto_schema_module()}.t/0`s" |
||||
} |
||||
end |
||||
|
||||
@impl Import.Runner |
||||
def run(multi, changes_list, %{timestamps: timestamps} = options) do |
||||
insert_options = |
||||
options |
||||
|> Map.get(option_key(), %{}) |
||||
|> Map.take(~w(on_conflict timeout)a) |
||||
|> Map.put_new(:timeout, @timeout) |
||||
|> Map.put(:timestamps, timestamps) |
||||
|
||||
Multi.run(multi, :insert_zkevm_batch_txns, fn repo, _ -> |
||||
Instrumenter.block_import_stage_runner( |
||||
fn -> insert(repo, changes_list, insert_options) end, |
||||
:block_referencing, |
||||
:zkevm_batch_txns, |
||||
:zkevm_batch_txns |
||||
) |
||||
end) |
||||
end |
||||
|
||||
@impl Import.Runner |
||||
def timeout, do: @timeout |
||||
|
||||
@spec insert(Repo.t(), [map()], %{required(:timeout) => timeout(), required(:timestamps) => Import.timestamps()}) :: |
||||
{:ok, [ZkevmBatchTxn.t()]} |
||||
| {:error, [Changeset.t()]} |
||||
def insert(repo, changes_list, %{timeout: timeout, timestamps: timestamps} = _options) when is_list(changes_list) do |
||||
# Enforce ZkevmBatchTxn ShareLocks order (see docs: sharelock.md) |
||||
ordered_changes_list = Enum.sort_by(changes_list, & &1.hash) |
||||
|
||||
{:ok, inserted} = |
||||
Import.insert_changes_list( |
||||
repo, |
||||
ordered_changes_list, |
||||
for: ZkevmBatchTxn, |
||||
returning: true, |
||||
timeout: timeout, |
||||
timestamps: timestamps, |
||||
conflict_target: :hash, |
||||
on_conflict: :nothing |
||||
) |
||||
|
||||
{:ok, inserted} |
||||
end |
||||
end |
@ -0,0 +1,32 @@ |
||||
defmodule Explorer.Chain.ZkevmBatchTxn do |
||||
@moduledoc "Models a list of transactions related to a batch for zkEVM." |
||||
|
||||
use Explorer.Schema |
||||
|
||||
alias Explorer.Chain.{Hash, Transaction, ZkevmTxnBatch} |
||||
|
||||
@required_attrs ~w(batch_number hash)a |
||||
|
||||
@type t :: %__MODULE__{ |
||||
batch_number: non_neg_integer(), |
||||
batch: %Ecto.Association.NotLoaded{} | ZkevmTxnBatch.t() | nil, |
||||
hash: Hash.t(), |
||||
l2_transaction: %Ecto.Association.NotLoaded{} | Transaction.t() | nil |
||||
} |
||||
|
||||
@primary_key false |
||||
schema "zkevm_batch_l2_transactions" do |
||||
belongs_to(:batch, ZkevmTxnBatch, foreign_key: :batch_number, references: :number, type: :integer) |
||||
belongs_to(:l2_transaction, Transaction, foreign_key: :hash, references: :hash, type: Hash.Full) |
||||
|
||||
timestamps() |
||||
end |
||||
|
||||
def changeset(%__MODULE__{} = transactions, attrs \\ %{}) do |
||||
transactions |
||||
|> cast(attrs, @required_attrs) |
||||
|> validate_required(@required_attrs) |
||||
|> foreign_key_constraint(:batch_number) |
||||
|> unique_constraint(:hash) |
||||
end |
||||
end |
Loading…
Reference in new issue