From 3c428304f4b9bfc49fdbfac99b55af1d422acdf6 Mon Sep 17 00:00:00 2001 From: Hamza Belhaj Date: Thu, 24 Nov 2022 20:27:15 +0100 Subject: [PATCH 1/3] Valid the authorized nodes in the node shared secret --- .../mining/pending_transaction_validation.ex | 15 ++++++++------- .../pending_transaction_validation_test.exs | 7 ++++++- .../shared_secrets/node_renewal_test.exs | 2 -- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/archethic/mining/pending_transaction_validation.ex b/lib/archethic/mining/pending_transaction_validation.ex index 32ed3f39f..fe17ec833 100644 --- a/lib/archethic/mining/pending_transaction_validation.ex +++ b/lib/archethic/mining/pending_transaction_validation.ex @@ -394,8 +394,6 @@ defmodule Archethic.Mining.PendingTransactionValidation do validation_time ) when is_binary(secret) and byte_size(secret) > 0 and map_size(authorized_keys) > 0 do - nodes = P2P.authorized_nodes() ++ NodeRenewal.candidates() - last_scheduling_date = SharedSecrets.get_last_scheduling_date(validation_time) genesis_address = @@ -405,12 +403,15 @@ defmodule Archethic.Mining.PendingTransactionValidation do {last_address, _} = DB.get_last_chain_address(genesis_address) with {^last_address, _} <- DB.get_last_chain_address(genesis_address, last_scheduling_date), - {:ok, _, _} <- - NodeRenewal.decode_transaction_content(content), + {:ok, _, _} <- NodeRenewal.decode_transaction_content(content), true <- - Enum.all?( - Map.keys(authorized_keys), - &Utils.key_in_node_list?(nodes, &1) + authorized_keys + |> Map.keys() + |> Enum.sort() + |> then( + &(NodeRenewal.next_authorized_node_public_keys() + |> Enum.sort() + |> Kernel.==(&1)) ) do :ok else diff --git a/test/archethic/mining/pending_transaction_validation_test.exs b/test/archethic/mining/pending_transaction_validation_test.exs index 002b543e4..e79cdf23a 100644 --- a/test/archethic/mining/pending_transaction_validation_test.exs +++ b/test/archethic/mining/pending_transaction_validation_test.exs @@ -186,6 +186,9 @@ defmodule Archethic.Mining.PendingTransactionValidationTest do available?: true }) + MockDB + |> expect(:get_latest_tps, fn -> 1000.0 end) + tx = Transaction.new( :node_shared_secrets, @@ -205,7 +208,9 @@ defmodule Archethic.Mining.PendingTransactionValidationTest do secret: :crypto.strong_rand_bytes(32), authorized_keys: %{ "node_key1" => "", - "node_key2" => "" + "node_key2" => "", + # we started and connected this node in setup + Crypto.last_node_public_key() => "" } } ] diff --git a/test/archethic/shared_secrets/node_renewal_test.exs b/test/archethic/shared_secrets/node_renewal_test.exs index e9b9ddbe5..acdfa9adc 100644 --- a/test/archethic/shared_secrets/node_renewal_test.exs +++ b/test/archethic/shared_secrets/node_renewal_test.exs @@ -13,8 +13,6 @@ defmodule Archethic.SharedSecrets.NodeRenewalTest do alias Archethic.TransactionChain.TransactionData alias Archethic.TransactionChain.TransactionData.Ownership - alias Archethic.SharedSecrets.NodeRenewal - import Mox test "new_node_shared_secrets_transaction/4 should create a new node shared secrets transaction" do From 607e38a83dcef4ea0a76c908a91928e9bf2d1b25 Mon Sep 17 00:00:00 2001 From: tenmoves Date: Tue, 29 Nov 2022 18:01:56 +0100 Subject: [PATCH 2/3] refactoring --- .../mining/pending_transaction_validation.ex | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/archethic/mining/pending_transaction_validation.ex b/lib/archethic/mining/pending_transaction_validation.ex index fe17ec833..7485aa892 100644 --- a/lib/archethic/mining/pending_transaction_validation.ex +++ b/lib/archethic/mining/pending_transaction_validation.ex @@ -402,17 +402,18 @@ defmodule Archethic.Mining.PendingTransactionValidation do {last_address, _} = DB.get_last_chain_address(genesis_address) + sorted_authorized_keys = + authorized_keys + |> Map.keys() + |> Enum.sort() + + sorted_node_renewal_authorized_keys = + NodeRenewal.next_authorized_node_public_keys() + |> Enum.sort() + with {^last_address, _} <- DB.get_last_chain_address(genesis_address, last_scheduling_date), {:ok, _, _} <- NodeRenewal.decode_transaction_content(content), - true <- - authorized_keys - |> Map.keys() - |> Enum.sort() - |> then( - &(NodeRenewal.next_authorized_node_public_keys() - |> Enum.sort() - |> Kernel.==(&1)) - ) do + true <- sorted_authorized_keys == sorted_node_renewal_authorized_keys do :ok else :error -> From 3cd6d1e3d605c19430d4e75a1614313df1262a2f Mon Sep 17 00:00:00 2001 From: tenmoves Date: Wed, 30 Nov 2022 11:55:02 +0100 Subject: [PATCH 3/3] added test --- .../pending_transaction_validation_test.exs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/archethic/mining/pending_transaction_validation_test.exs b/test/archethic/mining/pending_transaction_validation_test.exs index e79cdf23a..9fffd1208 100644 --- a/test/archethic/mining/pending_transaction_validation_test.exs +++ b/test/archethic/mining/pending_transaction_validation_test.exs @@ -223,6 +223,53 @@ defmodule Archethic.Mining.PendingTransactionValidationTest do :persistent_term.put(:node_shared_secrets_gen_addr, nil) end + test "should return error when authorized nodes are not the same as the candidates" do + P2P.add_and_connect_node(%Node{ + ip: {127, 0, 0, 1}, + port: 3000, + http_port: 4000, + first_public_key: "node_key1", + last_public_key: "node_key1", + available?: true + }) + + MockDB + |> expect(:get_latest_tps, fn -> 1000.0 end) + + tx = + Transaction.new( + :node_shared_secrets, + %TransactionData{ + content: + <<0, 0, 219, 82, 144, 35, 140, 59, 161, 231, 225, 145, 111, 203, 173, 197, 200, 150, + 213, 145, 87, 209, 98, 25, 28, 148, 198, 77, 174, 48, 16, 117, 253, 15, 0, 0, 105, + 113, 238, 128, 201, 90, 172, 230, 46, 99, 215, 130, 104, 26, 196, 222, 157, 89, + 101, 74, 248, 245, 118, 36, 194, 213, 108, 141, 175, 248, 6, 120>>, + code: """ + condition inherit: [ + type: node_shared_secrets + ] + """, + ownerships: [ + %Ownership{ + secret: :crypto.strong_rand_bytes(32), + authorized_keys: %{ + # we started and connected this node in setup + Crypto.last_node_public_key() => "" + } + } + ] + } + ) + + :persistent_term.put(:node_shared_secrets_gen_addr, Transaction.previous_address(tx)) + + assert {:error, "Invalid node shared secrets transaction authorized nodes"} = + PendingTransactionValidation.validate(tx) + + :persistent_term.put(:node_shared_secrets_gen_addr, nil) + end + test "should return :ok when a origin transaction is made" do P2P.add_and_connect_node(%Node{ ip: {127, 0, 0, 1},