From bbb8c67eac0f434466857732a457e882bf81d131 Mon Sep 17 00:00:00 2001 From: Apoorv Date: Fri, 19 Aug 2022 20:54:19 +0530 Subject: [PATCH] Election with auth and avail nodes only --- lib/archethic.ex | 14 +++---- .../bootstrap/transaction_handler.ex | 6 ++- .../contracts/interpreter/library.ex | 4 +- .../mining/pending_transaction_validation.ex | 2 +- .../replication/transaction_context.ex | 2 +- .../self_repair/sync/transaction_handler.ex | 9 +++-- lib/archethic/transaction_chain.ex | 4 +- test/archethic/account_test.exs | 2 +- test/archethic/beacon_chain_test.exs | 12 +++++- .../bootstrap/transaction_handler_test.exs | 7 +++- .../mining/distributed_workflow_test.exs | 40 +++++++++++++++---- .../sync/transaction_handler_test.exs | 22 ++++++---- test/archethic/self_repair/sync_test.exs | 24 ++++++----- 13 files changed, 102 insertions(+), 46 deletions(-) diff --git a/lib/archethic.ex b/lib/archethic.ex index 02070d245..c082d18d4 100644 --- a/lib/archethic.ex +++ b/lib/archethic.ex @@ -36,7 +36,7 @@ defmodule Archethic do | {:error, :transaction_invalid} | {:error, :network_issue} def search_transaction(address) when is_binary(address) do - storage_nodes = Election.chain_storage_nodes(address, P2P.available_nodes()) + storage_nodes = Election.chain_storage_nodes(address, P2P.authorized_and_available_nodes()) nodes = storage_nodes @@ -118,7 +118,7 @@ defmodule Archethic do {:ok, last_address} -> nodes = last_address - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) @@ -145,7 +145,7 @@ defmodule Archethic do @spec get_balance(binary) :: {:ok, Account.balance()} | {:error, :network_issue} def get_balance(address) when is_binary(address) do address - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) |> get_balance(address) @@ -171,7 +171,7 @@ defmodule Archethic do def get_transaction_inputs(address) when is_binary(address) do nodes = address - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) @@ -185,7 +185,7 @@ defmodule Archethic do def get_transaction_chain(address) when is_binary(address) do nodes = address - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) @@ -222,7 +222,7 @@ defmodule Archethic do def get_transaction_chain_by_paging_address(address, paging_address) when is_binary(address) do nodes = address - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) @@ -263,7 +263,7 @@ defmodule Archethic do def get_transaction_chain_length(address) when is_binary(address) do nodes = address - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) diff --git a/lib/archethic/bootstrap/transaction_handler.ex b/lib/archethic/bootstrap/transaction_handler.ex index 202499749..0f0f40f51 100644 --- a/lib/archethic/bootstrap/transaction_handler.ex +++ b/lib/archethic/bootstrap/transaction_handler.ex @@ -40,7 +40,11 @@ defmodule Archethic.Bootstrap.TransactionHandler do ) storage_nodes = - Election.chain_storage_nodes_with_type(tx.address, tx.type, P2P.available_nodes()) + Election.chain_storage_nodes_with_type( + tx.address, + tx.type, + P2P.authorized_and_available_nodes() + ) await_confirmation(tx.address, storage_nodes) diff --git a/lib/archethic/contracts/interpreter/library.ex b/lib/archethic/contracts/interpreter/library.ex index 571407e59..438acb1de 100644 --- a/lib/archethic/contracts/interpreter/library.ex +++ b/lib/archethic/contracts/interpreter/library.ex @@ -165,7 +165,7 @@ defmodule Archethic.Contracts.Interpreter.Library do @spec get_genesis_address(binary()) :: binary() def get_genesis_address(address) do - nodes = Election.chain_storage_nodes(address, P2P.available_nodes()) + nodes = Election.chain_storage_nodes(address, P2P.authorized_and_available_nodes()) {:ok, address} = download_first_address(nodes, address) address end @@ -175,7 +175,7 @@ defmodule Archethic.Contracts.Interpreter.Library do """ @spec get_genesis_public_key(binary()) :: binary() def get_genesis_public_key(address) do - nodes = Election.chain_storage_nodes(address, P2P.available_nodes()) + nodes = Election.chain_storage_nodes(address, P2P.authorized_and_available_nodes()) {:ok, key} = download_first_public_key(nodes, address) key end diff --git a/lib/archethic/mining/pending_transaction_validation.ex b/lib/archethic/mining/pending_transaction_validation.ex index e55156b7c..d1ef1068c 100644 --- a/lib/archethic/mining/pending_transaction_validation.ex +++ b/lib/archethic/mining/pending_transaction_validation.ex @@ -414,7 +414,7 @@ defmodule Archethic.Mining.PendingTransactionValidation do previous_address = Transaction.previous_address(tx) previous_address - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) |> get_first_public_key(previous_address) diff --git a/lib/archethic/replication/transaction_context.ex b/lib/archethic/replication/transaction_context.ex index e0160909c..c321f8c22 100644 --- a/lib/archethic/replication/transaction_context.ex +++ b/lib/archethic/replication/transaction_context.ex @@ -67,7 +67,7 @@ defmodule Archethic.Replication.TransactionContext do address # returns the storage nodes for the transaction chain based on the transaction address # from a list of available node - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) # Returns the nearest storages nodes from the local node as per the patch # when the input is a list of nodes |> P2P.nearest_nodes() diff --git a/lib/archethic/self_repair/sync/transaction_handler.ex b/lib/archethic/self_repair/sync/transaction_handler.ex index bae275c2f..01d0b7252 100644 --- a/lib/archethic/self_repair/sync/transaction_handler.ex +++ b/lib/archethic/self_repair/sync/transaction_handler.ex @@ -30,7 +30,9 @@ defmodule Archethic.SelfRepair.Sync.TransactionHandler do type: type, movements_addresses: mvt_addresses }) do - node_list = [P2P.get_node_info() | P2P.available_nodes()] |> P2P.distinct_nodes() + node_list = + [P2P.get_node_info() | P2P.authorized_and_available_nodes()] |> P2P.distinct_nodes() + chain_storage_nodes = Election.chain_storage_nodes_with_type(address, type, node_list) if Utils.key_in_node_list?(chain_storage_nodes, Crypto.first_node_public_key()) do @@ -62,7 +64,7 @@ defmodule Archethic.SelfRepair.Sync.TransactionHandler do storage_nodes = address - |> Election.chain_storage_nodes_with_type(type, P2P.available_nodes()) + |> Election.chain_storage_nodes_with_type(type, P2P.authorized_and_available_nodes()) |> Enum.reject(&(&1.first_public_key == Crypto.first_node_public_key())) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) @@ -96,7 +98,8 @@ defmodule Archethic.SelfRepair.Sync.TransactionHandler do type: type } ) do - node_list = [P2P.get_node_info() | P2P.available_nodes()] |> P2P.distinct_nodes() + node_list = + [P2P.get_node_info() | P2P.authorized_and_available_nodes()] |> P2P.distinct_nodes() cond do Election.chain_storage_node?(address, type, Crypto.first_node_public_key(), node_list) -> diff --git a/lib/archethic/transaction_chain.ex b/lib/archethic/transaction_chain.ex index c3003ec7f..a692a93e5 100644 --- a/lib/archethic/transaction_chain.ex +++ b/lib/archethic/transaction_chain.ex @@ -543,7 +543,7 @@ defmodule Archethic.TransactionChain do when is_binary(address) do nodes = address - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) @@ -862,7 +862,7 @@ defmodule Archethic.TransactionChain do def fetch_genesis_address_remotely(address) when is_binary(address) do nodes = address - |> Election.chain_storage_nodes(P2P.available_nodes()) + |> Election.chain_storage_nodes(P2P.authorized_and_available_nodes()) |> P2P.nearest_nodes() |> Enum.filter(&Node.locally_available?/1) diff --git a/test/archethic/account_test.exs b/test/archethic/account_test.exs index 9470f0349..d230fc8cd 100644 --- a/test/archethic/account_test.exs +++ b/test/archethic/account_test.exs @@ -19,7 +19,7 @@ defmodule Archethic.AccountTest do describe "get_balance/1" do setup do - expect(MockDB, :list_transactions_by_type, fn _, _ -> + stub(MockDB, :list_transactions_by_type, fn _, _ -> [ %Transaction{ address: "@RewardToken0", diff --git a/test/archethic/beacon_chain_test.exs b/test/archethic/beacon_chain_test.exs index 806d0e518..1e2301288 100644 --- a/test/archethic/beacon_chain_test.exs +++ b/test/archethic/beacon_chain_test.exs @@ -203,7 +203,11 @@ defmodule Archethic.BeaconChainTest do } storage_nodes = - Election.chain_storage_nodes_with_type(addr1, :transfer, P2P.available_nodes()) + Election.chain_storage_nodes_with_type( + addr1, + :transfer, + P2P.authorized_and_available_nodes() + ) beacon_summary = %Summary{ subset: "A", @@ -243,7 +247,11 @@ defmodule Archethic.BeaconChainTest do addr2 = <<0::8, 0::8, :crypto.strong_rand_bytes(32)::binary>> storage_nodes = - Election.chain_storage_nodes_with_type(addr1, :transfer, P2P.available_nodes()) + Election.chain_storage_nodes_with_type( + addr1, + :transfer, + P2P.authorized_and_available_nodes() + ) tx_summary = %TransactionSummary{ address: addr1, diff --git a/test/archethic/bootstrap/transaction_handler_test.exs b/test/archethic/bootstrap/transaction_handler_test.exs index cb7a1e33c..ced3c7f0d 100644 --- a/test/archethic/bootstrap/transaction_handler_test.exs +++ b/test/archethic/bootstrap/transaction_handler_test.exs @@ -39,11 +39,14 @@ defmodule Archethic.Bootstrap.TransactionHandlerTest do test "send_transaction/2 should send the transaction to a welcome node" do node = %Node{ ip: {80, 10, 101, 202}, - port: 4390, + port: 3005, http_port: 4000, first_public_key: "key1", last_public_key: "key1", - available?: true + available?: true, + authorized?: true, + authorization_date: DateTime.utc_now() |> DateTime.add(-10), + enrollment_date: DateTime.utc_now() } :ok = P2P.add_and_connect_node(node) diff --git a/test/archethic/mining/distributed_workflow_test.exs b/test/archethic/mining/distributed_workflow_test.exs index 3a25eb97f..011d6754c 100644 --- a/test/archethic/mining/distributed_workflow_test.exs +++ b/test/archethic/mining/distributed_workflow_test.exs @@ -105,7 +105,11 @@ defmodule Archethic.Mining.DistributedWorkflowTest do Election.validation_nodes( tx, sorting_seed, - Election.chain_storage_nodes_with_type(tx.address, tx.type, P2P.available_nodes()), + Election.chain_storage_nodes_with_type( + tx.address, + tx.type, + P2P.authorized_and_available_nodes() + ), P2P.authorized_nodes() ) @@ -182,7 +186,11 @@ defmodule Archethic.Mining.DistributedWorkflowTest do tx, sorting_seed, P2P.authorized_nodes(), - Election.chain_storage_nodes_with_type(tx.address, tx.type, P2P.available_nodes()) + Election.chain_storage_nodes_with_type( + tx.address, + tx.type, + P2P.authorized_and_available_nodes() + ) ) MockClient @@ -208,7 +216,9 @@ defmodule Archethic.Mining.DistributedWorkflowTest do last_public_key: "key1", reward_address: <<0::8, 0::8, :crypto.strong_rand_bytes(32)::binary>>, geo_patch: "AAA", - network_patch: "AAA" + network_patch: "AAA", + authorized?: true, + authorization_date: DateTime.utc_now() |> DateTime.add(-86_400) } {:ok, coordinator_pid} = @@ -278,7 +288,11 @@ defmodule Archethic.Mining.DistributedWorkflowTest do tx, sorting_seed, P2P.authorized_nodes(), - Election.chain_storage_nodes_with_type(tx.address, tx.type, P2P.available_nodes()) + Election.chain_storage_nodes_with_type( + tx.address, + tx.type, + P2P.authorized_and_available_nodes() + ) ) MockClient @@ -397,7 +411,11 @@ defmodule Archethic.Mining.DistributedWorkflowTest do tx, sorting_seed, P2P.authorized_nodes(), - Election.chain_storage_nodes_with_type(tx.address, tx.type, P2P.available_nodes()) + Election.chain_storage_nodes_with_type( + tx.address, + tx.type, + P2P.authorized_and_available_nodes() + ) ) MockClient @@ -520,7 +538,11 @@ defmodule Archethic.Mining.DistributedWorkflowTest do tx, sorting_seed, P2P.authorized_nodes(), - Election.chain_storage_nodes_with_type(tx.address, tx.type, P2P.available_nodes()) + Election.chain_storage_nodes_with_type( + tx.address, + tx.type, + P2P.authorized_and_available_nodes() + ) ) me = self() @@ -700,7 +722,11 @@ defmodule Archethic.Mining.DistributedWorkflowTest do tx, sorting_seed, P2P.authorized_nodes(), - Election.chain_storage_nodes_with_type(tx.address, tx.type, P2P.available_nodes()) + Election.chain_storage_nodes_with_type( + tx.address, + tx.type, + P2P.authorized_and_available_nodes() + ) ) me = self() diff --git a/test/archethic/self_repair/sync/transaction_handler_test.exs b/test/archethic/self_repair/sync/transaction_handler_test.exs index 8cb5a228e..de37d3924 100644 --- a/test/archethic/self_repair/sync/transaction_handler_test.exs +++ b/test/archethic/self_repair/sync/transaction_handler_test.exs @@ -37,14 +37,18 @@ defmodule Archethic.SelfRepair.Sync.TransactionHandlerTest do setup do start_supervised!({BeaconSlotTimer, interval: "0 * * * * * *"}) Enum.each(BeaconChain.list_subsets(), &BeaconSubset.start_link(subset: &1)) + pb_key1 = Crypto.derive_keypair("key11", 0) |> elem(0) + pb_key3 = Crypto.derive_keypair("key33", 0) |> elem(0) welcome_node = %Node{ - first_public_key: "key1", - last_public_key: "key1", + first_public_key: pb_key1, + last_public_key: pb_key1, available?: true, geo_patch: "BBB", network_patch: "BBB", - reward_address: :crypto.strong_rand_bytes(32), + authorized?: true, + reward_address: Crypto.derive_address(pb_key1), + authorization_date: DateTime.utc_now() |> DateTime.add(-10), enrollment_date: DateTime.utc_now() } @@ -64,13 +68,15 @@ defmodule Archethic.SelfRepair.Sync.TransactionHandlerTest do %Node{ ip: {127, 0, 0, 1}, port: 3000, - first_public_key: "key3", - last_public_key: "key3", - available?: true, + first_public_key: pb_key3, + last_public_key: pb_key3, geo_patch: "BBB", network_patch: "BBB", - reward_address: :crypto.strong_rand_bytes(32), - authorization_date: DateTime.utc_now() + reward_address: Crypto.derive_address(pb_key3), + available?: true, + authorized?: true, + authorization_date: DateTime.utc_now() |> DateTime.add(-10), + enrollment_date: DateTime.utc_now() } ] diff --git a/test/archethic/self_repair/sync_test.exs b/test/archethic/self_repair/sync_test.exs index ac4a088bf..32c804888 100644 --- a/test/archethic/self_repair/sync_test.exs +++ b/test/archethic/self_repair/sync_test.exs @@ -305,7 +305,6 @@ defmodule Archethic.SelfRepair.SyncTest do ] tx_address = transfer_tx.address - me = self() MockDB @@ -364,13 +363,18 @@ defmodule Archethic.SelfRepair.SyncTest do end defp create_p2p_context do + pb_key1 = Crypto.derive_keypair("key11", 0) |> elem(0) + pb_key3 = Crypto.derive_keypair("key33", 0) |> elem(0) + welcome_node = %Node{ - first_public_key: "key1", - last_public_key: "key1", + first_public_key: pb_key1, + last_public_key: pb_key1, available?: true, geo_patch: "BBB", network_patch: "BBB", - reward_address: <<0::8, 0::8, :crypto.strong_rand_bytes(32)::binary>>, + authorized?: true, + reward_address: Crypto.derive_address(pb_key1), + authorization_date: DateTime.utc_now() |> DateTime.add(-10), enrollment_date: DateTime.utc_now() } @@ -391,13 +395,15 @@ defmodule Archethic.SelfRepair.SyncTest do ip: {127, 0, 0, 1}, port: 3000, http_port: 4000, - first_public_key: "key3", - last_public_key: "key3", - available?: true, + first_public_key: pb_key3, + last_public_key: pb_key3, geo_patch: "BBB", network_patch: "BBB", - reward_address: <<0::8, 0::8, :crypto.strong_rand_bytes(32)::binary>>, - authorization_date: DateTime.utc_now() + reward_address: Crypto.derive_address(pb_key3), + available?: true, + authorized?: true, + authorization_date: DateTime.utc_now() |> DateTime.add(-10), + enrollment_date: DateTime.utc_now() } ]