Skip to content

Commit

Permalink
Add timestamp in node validation election
Browse files Browse the repository at this point in the history
  • Loading branch information
Wassim Mansouri authored and Neylix committed Nov 21, 2024
1 parent b570e22 commit e187ef7
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 135 deletions.
16 changes: 12 additions & 4 deletions lib/archethic.ex
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,21 @@ defmodule Archethic do
welcome_node_key = Keyword.get(opts, :welcome_node_key, Crypto.first_node_public_key())
contract_context = Keyword.get(opts, :contract_context, nil)
forward? = Keyword.get(opts, :forward?, false)
ref_timestamp = DateTime.utc_now()

cond do
P2P.authorized_and_available_node?() and shared_secret_synced?() ->
validation_nodes = Mining.get_validation_nodes(tx)
validation_nodes = Mining.get_validation_nodes(tx, ref_timestamp)

responses =
%{already_locked?: already_locked?} =
do_send_transaction(tx, validation_nodes, welcome_node_key, contract_context)
do_send_transaction(
tx,
validation_nodes,
welcome_node_key,
contract_context,
ref_timestamp
)

maybe_start_resync(responses)

Expand Down Expand Up @@ -121,7 +128,8 @@ defmodule Archethic do
tx = %Transaction{type: tx_type},
validation_nodes,
welcome_node_key,
contract_context
contract_context,
ref_timestamp
) do
message = %StartMining{
transaction: tx,
Expand All @@ -130,7 +138,7 @@ defmodule Archethic do
network_chains_view_hash: NetworkView.get_chains_hash(),
p2p_view_hash: NetworkView.get_p2p_hash(),
contract_context: contract_context,
ref_timestamp: DateTime.utc_now()
ref_timestamp: ref_timestamp
}

Task.Supervisor.async_stream_nolink(
Expand Down
7 changes: 5 additions & 2 deletions lib/archethic/election.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ defmodule Archethic.Election do
"""
@spec validation_nodes_election_seed_sorting(Transaction.t(), DateTime.t()) :: binary()
def validation_nodes_election_seed_sorting(tx = %Transaction{}, timestamp = %DateTime{}) do
tx_hash =
serialized_tx =
tx
|> Transaction.to_pending()
|> Transaction.serialize()

sorting_hash =
<<serialized_tx::bitstring, DateTime.to_unix(timestamp, :millisecond)::64>>
|> Crypto.hash()

Crypto.sign_with_daily_nonce_key(tx_hash, timestamp)
Crypto.sign_with_daily_nonce_key(sorting_hash, timestamp)
end

@doc """
Expand Down
17 changes: 10 additions & 7 deletions lib/archethic/mining.ex
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,13 @@ defmodule Archethic.Mining do
@doc """
Elect validation nodes for a transaction
"""
def get_validation_nodes(tx = %Transaction{address: tx_address, validation_stamp: nil}) do
current_date = DateTime.utc_now()
sorting_seed = Election.validation_nodes_election_seed_sorting(tx, current_date)
def get_validation_nodes(
tx = %Transaction{address: tx_address, validation_stamp: nil},
ref_timestamp
) do
sorting_seed = Election.validation_nodes_election_seed_sorting(tx, ref_timestamp)

node_list = P2P.authorized_and_available_nodes(current_date)
node_list = P2P.authorized_and_available_nodes(ref_timestamp)

storage_nodes = Election.chain_storage_nodes(tx_address, node_list)

Expand All @@ -100,10 +102,11 @@ defmodule Archethic.Mining do
@doc """
Determines if the election of validation nodes performed by the welcome node is valid
"""
@spec valid_election?(Transaction.t(), list(Crypto.key())) :: boolean()
def valid_election?(tx, validation_node_public_keys)
@spec valid_election?(Transaction.t(), list(Crypto.key()), ref_timestamp :: DateTime.t()) ::
boolean()
def valid_election?(tx, validation_node_public_keys, ref_timestamp)
when is_list(validation_node_public_keys) do
validation_nodes = get_validation_nodes(tx)
validation_nodes = get_validation_nodes(tx, ref_timestamp)
validation_node_public_keys == Enum.map(validation_nodes, & &1.last_public_key)
end

Expand Down
4 changes: 2 additions & 2 deletions lib/archethic/mining/distributed_workflow.ex
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,9 @@ defmodule Archethic.Mining.DistributedWorkflow do
:internal,
{:start_mining, tx, welcome_node, validation_nodes, contract_context},
:idle,
data = %{node_public_key: node_public_key}
data = %{ref_timestamp: ref_timestamp, node_public_key: node_public_key}
) do
validation_time = DateTime.utc_now() |> DateTime.truncate(:millisecond)
validation_time = ref_timestamp |> DateTime.truncate(:millisecond)

authorized_nodes = P2P.authorized_and_available_nodes(validation_time)

Expand Down
3 changes: 1 addition & 2 deletions lib/archethic/mining/validation_context.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1161,8 +1161,7 @@ defmodule Archethic.Mining.ValidationContext do
defp valid_timestamp(%ValidationStamp{timestamp: timestamp}, %__MODULE__{
validation_time: validation_time
}) do
diff = DateTime.diff(timestamp, validation_time)
diff <= 10 and diff > -10
DateTime.compare(timestamp, validation_time) == :eq
end

defp valid_stamp_signature(stamp = %ValidationStamp{}, %__MODULE__{
Expand Down
6 changes: 3 additions & 3 deletions lib/archethic/p2p/message/start_mining.ex
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ defmodule Archethic.P2P.Message.StartMining do
) do
with :ok <- check_ref_timestamp(ref_timestamp),
:ok <- check_synchronization(network_chains_view_hash, p2p_view_hash),
:ok <- check_valid_election(tx, validation_nodes),
:ok <- check_valid_election(tx, validation_nodes, ref_timestamp),
:ok <- check_current_node_is_elected(validation_nodes),
:ok <- check_not_already_mining(tx.address),
:ok <- Mining.request_chain_lock(tx) do
Expand Down Expand Up @@ -212,8 +212,8 @@ defmodule Archethic.P2P.Message.StartMining do
end
end

defp check_valid_election(tx, validation_nodes) do
if Mining.valid_election?(tx, validation_nodes) do
defp check_valid_election(tx, validation_nodes, ref_timestamp) do
if Mining.valid_election?(tx, validation_nodes, ref_timestamp) do
:ok
else
{:error, :invalid_validation_nodes_election}
Expand Down
Loading

0 comments on commit e187ef7

Please sign in to comment.