diff --git a/lib/archethic/transaction_chain.ex b/lib/archethic/transaction_chain.ex index 3c25aace6..0986ad3d4 100644 --- a/lib/archethic/transaction_chain.ex +++ b/lib/archethic/transaction_chain.ex @@ -845,12 +845,37 @@ defmodule Archethic.TransactionChain do end end + repair_fun = fn + nil, _results_by_node -> + :ok + + %GenesisAddress{address: ^address}, _results_by_node -> + :ok + + %GenesisAddress{address: genesis_address}, results_by_node -> + results_by_node + |> Enum.reduce([], fn + {node_public_key, %GenesisAddress{address: ^address}}, acc -> + [node_public_key | acc] + + _, acc -> + acc + end) + |> P2P.get_nodes_info() + |> P2P.broadcast_message(%ShardRepair{ + genesis_address: genesis_address, + storage_address: address, + io_addresses: [] + }) + end + case P2P.quorum_read( nodes, %GetGenesisAddress{address: address}, conflict_resolver: conflict_resolver, timeout: timeout, - acceptance_resolver: acceptance_resolver + acceptance_resolver: acceptance_resolver, + repair_fun: repair_fun ) do {:ok, %GenesisAddress{address: genesis_address}} -> {:ok, genesis_address} diff --git a/test/archethic/transaction_chain_test.exs b/test/archethic/transaction_chain_test.exs index 8b7aaa6d7..e6b4b77f0 100644 --- a/test/archethic/transaction_chain_test.exs +++ b/test/archethic/transaction_chain_test.exs @@ -1220,6 +1220,29 @@ defmodule Archethic.TransactionChainTest do assert {:ok, "addr1"} = TransactionChain.fetch_genesis_address("addr2", nodes) end + + test "should send a repair msg to nodes that missed the tx", %{nodes: nodes = [node | _]} do + address = random_address() + genesis = random_address() + me = self() + + MockClient + |> stub(:send_message, fn + ^node, %GetGenesisAddress{}, _ -> + {:ok, %GenesisAddress{address: genesis, timestamp: ~U[2023-01-01 00:00:00Z]}} + + _, %GetGenesisAddress{}, _ -> + {:ok, %GenesisAddress{address: address, timestamp: DateTime.utc_now()}} + + _, %ShardRepair{genesis_address: ^genesis, storage_address: ^address}, _ -> + send(me, :shardrepair) + {:ok, %Ok{}} + end) + + assert {:ok, ^genesis} = TransactionChain.fetch_genesis_address(address, nodes) + assert_receive :shardrepair, 100 + assert_receive :shardrepair, 100 + end end describe "resolve_paging_state/3" do