Skip to content

Commit

Permalink
Add geopatch to node transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
Wassim Mansouri committed Nov 25, 2024
1 parent e187ef7 commit 923859f
Show file tree
Hide file tree
Showing 19 changed files with 538 additions and 174 deletions.
45 changes: 35 additions & 10 deletions lib/archethic/bootstrap.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ defmodule Archethic.Bootstrap do

alias Archethic.Crypto

alias Archethic.P2P.GeoPatch

alias Archethic.Networking

alias Archethic.P2P
Expand Down Expand Up @@ -175,6 +177,7 @@ defmodule Archethic.Bootstrap do
configured_reward_address
) do
Logger.info("Bootstrapping starting")
geo_patch = GeoPatch.from_ip(ip)

cond do
Sync.should_initialize_network?(closest_bootstrapping_nodes) ->
Expand All @@ -187,7 +190,8 @@ defmodule Archethic.Bootstrap do
port,
http_port,
transport,
configured_reward_address
configured_reward_address,
geo_patch
)

Sync.initialize_network(tx)
Expand All @@ -203,7 +207,8 @@ defmodule Archethic.Bootstrap do
http_port,
transport,
closest_bootstrapping_nodes,
configured_reward_address
configured_reward_address,
geo_patch
)

true ->
Expand All @@ -215,15 +220,17 @@ defmodule Archethic.Bootstrap do
)

{:ok, _ip, _p2p_port, _http_port, _transport, last_reward_address, _origin_public_key,
_key_certificate, _mining_public_key} = Node.decode_transaction_content(content)
_key_certificate, _mining_public_key,
_geo_patch} = Node.decode_transaction_content(content)

update_node(
ip,
port,
http_port,
transport,
closest_bootstrapping_nodes,
last_reward_address
last_reward_address,
geo_patch
)
end
end
Expand Down Expand Up @@ -265,7 +272,8 @@ defmodule Archethic.Bootstrap do
http_port,
transport,
closest_bootstrapping_nodes,
configured_reward_address
configured_reward_address,
geo_patch
) do
# In case node had lose it's DB, we ask the network if the node chain already exists
{:ok, length} =
Expand All @@ -286,15 +294,23 @@ defmodule Archethic.Bootstrap do
TransactionChain.fetch_transaction(last_address, closest_bootstrapping_nodes)

{:ok, _ip, _p2p_port, _http_port, _transport, last_reward_address, _origin_public_key,
_key_certificate, _mining_public_key} = Node.decode_transaction_content(content)
_key_certificate, _mining_public_key,
_geo_patch} = Node.decode_transaction_content(content)

last_reward_address
else
configured_reward_address
end

tx =
TransactionHandler.create_node_transaction(ip, port, http_port, transport, reward_address)
TransactionHandler.create_node_transaction(
ip,
port,
http_port,
transport,
reward_address,
geo_patch
)

{:ok, validated_tx} = TransactionHandler.send_transaction(tx, closest_bootstrapping_nodes)

Expand All @@ -307,18 +323,27 @@ defmodule Archethic.Bootstrap do
)
end

defp update_node(_ip, _port, _http_port, _transport, [], _reward_address) do
defp update_node(_ip, _port, _http_port, _transport, [], _reward_address, _geo_patch) do
Logger.warning("Not enough nodes in the network. No node update")
end

defp update_node(ip, port, http_port, transport, closest_bootstrapping_nodes, reward_address) do
defp update_node(
ip,
port,
http_port,
transport,
closest_bootstrapping_nodes,
reward_address,
geo_patch
) do
tx =
TransactionHandler.create_node_transaction(
ip,
port,
http_port,
transport,
reward_address
reward_address,
geo_patch
)

{:ok, validated_tx} = TransactionHandler.send_transaction(tx, closest_bootstrapping_nodes)
Expand Down
35 changes: 22 additions & 13 deletions lib/archethic/bootstrap/transaction_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,21 @@ defmodule Archethic.Bootstrap.TransactionHandler do
p2p_port :: :inet.port_number(),
http_port :: :inet.port_number(),
transport :: P2P.supported_transport(),
reward_address :: Crypto.versioned_hash()
reward_address :: Crypto.versioned_hash(),
geo_patch :: binary()
) ::
Transaction.t()
def create_node_transaction(ip = {_, _, _, _}, port, http_port, transport, reward_address)
def create_node_transaction(
ip = {_, _, _, _},
port,
http_port,
transport,
reward_address,
geo_patch
)
when is_number(port) and port >= 0 and is_binary(reward_address) do
origin_public_key = Crypto.origin_node_public_key()
origin_public_key_certificate = Crypto.get_key_certificate(origin_public_key)
origin_public_certificate = Crypto.get_key_certificate(origin_public_key)
mining_public_key = Crypto.mining_node_public_key()

Transaction.new(:node, %TransactionData{
Expand All @@ -94,16 +102,17 @@ defmodule Archethic.Bootstrap.TransactionHandler do
]
""",
content:
Node.encode_transaction_content(
ip,
port,
http_port,
transport,
reward_address,
origin_public_key,
origin_public_key_certificate,
mining_public_key
)
Node.encode_transaction_content(%{
ip: ip,
port: port,
http_port: http_port,
transport: transport,
reward_address: reward_address,
origin_public_key: origin_public_key,
key_certificate: origin_public_certificate,
mining_public_key: mining_public_key,
geo_patch: geo_patch
})
})
end
end
15 changes: 13 additions & 2 deletions lib/archethic/mining/pending_transaction_validation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ defmodule Archethic.Mining.PendingTransactionValidation do
alias Archethic.OracleChain

alias Archethic.P2P
alias Archethic.P2P.GeoPatch
alias Archethic.P2P.Message.FirstPublicKey
alias Archethic.P2P.Message.GetFirstPublicKey
alias Archethic.P2P.Node
Expand Down Expand Up @@ -317,7 +318,8 @@ defmodule Archethic.Mining.PendingTransactionValidation do
},
_
) do
with {:ok, ip, port, _http_port, _, _, origin_public_key, key_certificate, mining_public_key} <-
with {:ok, ip, port, _http_port, _, _, origin_public_key, key_certificate, mining_public_key,
geo_patch} <-
Node.decode_transaction_content(content),
{:auth_origin, true} <-
{:auth_origin,
Expand All @@ -338,7 +340,9 @@ defmodule Archethic.Mining.PendingTransactionValidation do
{:mining_public_key, true} <-
{:mining_public_key,
Crypto.valid_public_key?(mining_public_key) and
Crypto.get_public_key_curve(mining_public_key) == :bls} do
Crypto.get_public_key_curve(mining_public_key) == :bls},
{:geo_patch, true} <-
{:geo_patch, valid_geopatch?(ip, geo_patch)} do
:ok
else
:error ->
Expand All @@ -362,6 +366,9 @@ defmodule Archethic.Mining.PendingTransactionValidation do

{:mining_public_key, false} ->
{:error, "Invalid mining public key"}

{:geo_patch, false} ->
{:error, "Invalid geo patch from IP"}
end
end

Expand Down Expand Up @@ -966,6 +973,10 @@ defmodule Archethic.Mining.PendingTransactionValidation do
end
end

defp valid_geopatch?(ip, calculated_geopatch) do
calculated_geopatch == GeoPatch.from_ip(ip)
end

defp get_allowed_node_key_origins do
:archethic
|> Application.get_env(__MODULE__, [])
Expand Down
3 changes: 2 additions & 1 deletion lib/archethic/mining/proof_of_work.ex
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ defmodule Archethic.Mining.ProofOfWork do
}
}) do
{:ok, _ip, _p2p_port, _http_port, _transport, _reward_address, origin_public_key,
_origin_certificate, _mining_public_key} = Node.decode_transaction_content(content)
_origin_certificate, _mining_public_key,
_geo_patch} = Node.decode_transaction_content(content)

[origin_public_key]
end
Expand Down
23 changes: 13 additions & 10 deletions lib/archethic/networking/scheduler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule Archethic.Networking.Scheduler do
alias Archethic.Networking.PortForwarding

alias Archethic.P2P
alias(Archethic.P2P.GeoPatch)
alias Archethic.P2P.Listener, as: P2PListener
alias Archethic.P2P.Node

Expand Down Expand Up @@ -103,21 +104,23 @@ defmodule Archethic.Networking.Scheduler do
origin_public_key = Crypto.origin_node_public_key()
mining_public_key = Crypto.mining_node_public_key()
key_certificate = Crypto.get_key_certificate(origin_public_key)
new_geo_patch = GeoPatch.from_ip(ip)

tx =
Transaction.new(:node, %TransactionData{
code: code,
content:
Node.encode_transaction_content(
ip,
p2p_port,
web_port,
transport,
reward_address,
origin_public_key,
key_certificate,
mining_public_key
)
Node.encode_transaction_content(%{
ip: ip,
port: p2p_port,
http_port: web_port,
transport: transport,
reward_address: reward_address,
origin_public_key: origin_public_key,
orogin_key_certificate: key_certificate,
mining_public_key: mining_public_key,
geo_patch: new_geo_patch
})
})

Archethic.send_new_transaction(tx, forward?: true)
Expand Down
8 changes: 5 additions & 3 deletions lib/archethic/p2p/mem_table_loader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ defmodule Archethic.P2P.MemTableLoader do
first_public_key = TransactionChain.get_first_public_key(previous_public_key)

{:ok, ip, port, http_port, transport, reward_address, origin_public_key, _certificate,
mining_public_key} = Node.decode_transaction_content(content)
mining_public_key, geo_patch} = Node.decode_transaction_content(content)

geo_patch = if geo_patch == nil, do: GeoPatch.from_ip(ip), else: geo_patch

if first_node_change?(first_public_key, previous_public_key) do
node = %Node{
Expand All @@ -114,7 +116,7 @@ defmodule Archethic.P2P.MemTableLoader do
http_port: http_port,
first_public_key: first_public_key,
last_public_key: previous_public_key,
geo_patch: GeoPatch.from_ip(ip),
geo_patch: geo_patch,
transport: transport,
last_address: address,
reward_address: reward_address,
Expand All @@ -135,7 +137,7 @@ defmodule Archethic.P2P.MemTableLoader do
port: port,
http_port: http_port,
last_public_key: previous_public_key,
geo_patch: GeoPatch.from_ip(ip),
geo_patch: geo_patch,
transport: transport,
last_address: address,
reward_address: reward_address,
Expand Down
Loading

0 comments on commit 923859f

Please sign in to comment.