Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tx replication sometimes fails. #1650 #1651

Merged
merged 1 commit into from
Feb 3, 2025
Merged

Tx replication sometimes fails. #1650 #1651

merged 1 commit into from
Feb 3, 2025

Conversation

Chralu
Copy link
Contributor

@Chralu Chralu commented Jan 30, 2025

Description

When replicating transactions, checks if Tx is already present before writing it.

Check is performed in ChainWriter.write to ensure they are sequentials.

Fixes #1650

@Chralu Chralu requested a review from Neylix January 30, 2025 16:30
Copy link
Member

@Neylix Neylix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You ensured the transaction has been succesfully written before ingesting it only when writting the previous transactions of the chain. But in there is 2 others call of write_transaction that need the same check.
Also this PR could be merge into develop for the next release. It do not needs to be in 1.7.0

ChainWriter.append_transaction(genesis_address, tx)

# Delete IO transaction if it exists as it is now stored as a chain
delete_io_transaction(tx.address)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling this function after the append_transaction will ignore the return of the ChainWriter, so the function will never return {:error, :transaction_already_exists}
You could also updated the spec of the function

@@ -36,21 +36,25 @@ defmodule Archethic.DB.EmbeddedImpl.ChainWriter do
"""
@spec write_io_transaction(Transaction.t(), String.t()) :: :ok
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can update the spec of the function since it has a new return

@@ -154,23 +158,27 @@ defmodule Archethic.DB.EmbeddedImpl.ChainWriter do
end

defp write_transaction(genesis_address, tx, db_path) do
start = System.monotonic_time()
if ChainIndex.transaction_exists?(tx.address, db_path) do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:
This control could be done in the handle_call of append_tx. So function write_transaction only write and do not perform check.


opts = Keyword.delete(ingest_opts, :resolved_addresses)
if ingest?, do: ingest_transaction(tx, genesis_address, opts)
case TransactionChain.write_transaction(tx) do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:
Since we don't need a specific return from the lambda function (Stream.each always return :ok), you could simplify the function like

if TransactionChain.write_transaction(tx) == :ok do
    # There is some case where a transaction is not replicated while it should
    # because of some latency or network issue. So when we replicate a past chain
    # we also ingest the transaction if we are storage node of it

    ingest? =
      Transaction.network_type?(type) or
        Election.chain_storage_node?(address, first_node_key, download_nodes) or
        Election.chain_storage_node?(genesis_address, first_node_key, download_nodes)

    opts = Keyword.delete(ingest_opts, :resolved_addresses)
    if ingest?, do: ingest_transaction(tx, genesis_address, opts)
end

@@ -1128,7 +1128,7 @@ defmodule Archethic.TransactionChain do
Persist only one transaction
"""
@spec write_transaction(transaction :: Transaction.t(), storage_location :: DB.storage_type()) ::
:ok
:ok | {:error, :reason}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function will never return the atom :reason as error details. The right return spec sould be {:error, :transaction_already_exists}

@Chralu Chralu changed the base branch from 1.7.0 to develop February 3, 2025 15:21
@Neylix Neylix merged commit 21303b3 into develop Feb 3, 2025
1 check passed
@Neylix Neylix deleted the Chralu/issue1650 branch February 3, 2025 18:20
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.

Tx replication sometimes fails.
2 participants