Skip to content

Commit

Permalink
Use a new transaction type
Browse files Browse the repository at this point in the history
  • Loading branch information
Neylix committed Jun 22, 2022
1 parent 4a4d659 commit ac799af
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 60 deletions.
2 changes: 1 addition & 1 deletion lib/archethic/bootstrap/network_init.ex
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ defmodule Archethic.Bootstrap.NetworkInit do
"""
}

tx = %Transaction{address: address} = Transaction.new_nft_reward(data)
tx = %Transaction{address: address} = Transaction.new(:mint_rewards, data)

tx
|> self_validation([
Expand Down
5 changes: 3 additions & 2 deletions lib/archethic/crypto.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1047,13 +1047,14 @@ defmodule Archethic.Crypto do
end
end

def load_transaction(%Transaction{type: :node_rewards, address: address}) do
def load_transaction(%Transaction{type: type, address: address})
when type in [:node_rewards, :mint_rewards] do
nb_transactions = TransactionChain.size(address)
SharedSecretsKeystore.set_network_pool_key_index(nb_transactions)

Logger.info("Network pool chain positioned at#{nb_transactions}",
transaction_address: Base.encode16(address),
transaction_type: :node_rewards
transaction_type: type
)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ defmodule Archethic.Crypto.SharedSecretsKeystore.SoftwareImpl do

Logger.info("Node shared secrets keys positioned at #{nb_node_shared_secrets_keys}")

nb_network_pool_keys = TransactionChain.count_transactions_by_type(:node_rewards)
nb_network_pool_keys =
TransactionChain.count_transactions_by_type(:node_rewards) +
TransactionChain.count_transactions_by_type(:mint_rewards)

Logger.info("Network pool keys positioned at #{nb_network_pool_keys}")

:ets.insert(@keystore_table, {:shared_secrets_index, nb_node_shared_secrets_keys})
Expand Down
9 changes: 1 addition & 8 deletions lib/archethic/mining/fee.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ defmodule Archethic.Mining.Fee do
alias Archethic.Election

alias Archethic.P2P
alias Archethic.Crypto

alias Archethic.TransactionChain
alias Archethic.TransactionChain.Transaction
alias Archethic.TransactionChain.TransactionData
alias Archethic.TransactionChain.TransactionData.Ledger
Expand All @@ -32,19 +30,14 @@ defmodule Archethic.Mining.Fee do
def calculate(
tx = %Transaction{
address: address,
type: type,
previous_public_key: previous_public_key
type: type
},
uco_price_in_usd
) do
cond do
address == Bootstrap.genesis_address() ->
0

TransactionChain.get_first_public_key(previous_public_key) ==
Crypto.network_pool_public_key(0) ->
0

true == Transaction.network_type?(type) ->
0

Expand Down
11 changes: 11 additions & 0 deletions lib/archethic/mining/pending_transaction_validation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@ defmodule Archethic.Mining.PendingTransactionValidation do
end
end

defp do_accept_transaction(%Transaction{
type: :mint_rewards,
data: %TransactionData{content: content}
}) do
if Regex.match?(~r/(?<=initial supply:).*\d/mi, content) do
:ok
else
{:error, "Invalid mint rewards content"}
end
end

defp do_accept_transaction(%Transaction{
type: :node,
data: %TransactionData{
Expand Down
3 changes: 2 additions & 1 deletion lib/archethic/shared_secrets/mem_tables_loader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ defmodule Archethic.SharedSecrets.MemTablesLoader do
)
end

def load_transaction(%Transaction{type: :node_rewards, address: address}) do
def load_transaction(%Transaction{type: type, address: address})
when type in [:node_rewards, :mint_rewards] do
NetworkLookup.set_network_pool_address(address)
end

Expand Down
1 change: 1 addition & 0 deletions lib/archethic/transaction_chain/mem_tables_loader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ defmodule Archethic.TransactionChain.MemTablesLoader do
:beacon,
:beacon_summary,
:node_rewards,
:mint_rewards,
:origin
]

Expand Down
52 changes: 16 additions & 36 deletions lib/archethic/transaction_chain/transaction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ defmodule Archethic.TransactionChain.Transaction do
:node
| :node_shared_secrets
| :node_rewards
| :mint_rewards
| :beacon
| :beacon_summary
| :oracle
Expand All @@ -84,6 +85,7 @@ defmodule Archethic.TransactionChain.Transaction do
:oracle,
:oracle_summary,
:node_rewards,
:mint_rewards,
:code_proposal,
:code_approval,
:keychain,
Expand Down Expand Up @@ -121,24 +123,6 @@ defmodule Archethic.TransactionChain.Transaction do
|> origin_sign_transaction()
end

@doc """
Create a new pending transaction using the Crypto keystore to find out
the seed and the transaction index for the nft reward minting
"""
@spec new_nft_reward(data :: TransactionData.t()) :: t()
def new_nft_reward(data = %TransactionData{}) do
{previous_public_key, next_public_key} = get_network_public_key()

%__MODULE__{
address: Crypto.derive_address(next_public_key),
type: :nft,
data: data,
previous_public_key: previous_public_key
}
|> previous_network_sign_transaction()
|> origin_sign_transaction()
end

@doc """
Create a new pending transaction
Expand Down Expand Up @@ -199,8 +183,11 @@ defmodule Archethic.TransactionChain.Transaction do
{previous_public_key, next_public_key}
end

defp get_transaction_public_keys(:node_rewards) do
get_network_public_key()
defp get_transaction_public_keys(type) when type in [:node_rewards, :mint_rewards] do
key_index = Crypto.number_of_network_pool_keys()
previous_public_key = Crypto.network_pool_public_key(key_index)
next_public_key = Crypto.network_pool_public_key(key_index + 1)
{previous_public_key, next_public_key}
end

defp get_transaction_public_keys(_) do
Expand All @@ -209,13 +196,6 @@ defmodule Archethic.TransactionChain.Transaction do
{previous_public_key, next_public_key}
end

defp get_network_public_key() do
key_index = Crypto.number_of_network_pool_keys()
previous_public_key = Crypto.network_pool_public_key(key_index)
next_public_key = Crypto.network_pool_public_key(key_index + 1)
{previous_public_key, next_public_key}
end

defp previous_sign_transaction(tx = %__MODULE__{type: :node_shared_secrets}) do
key_index = Crypto.number_of_node_shared_secrets_keys()

Expand All @@ -228,28 +208,25 @@ defmodule Archethic.TransactionChain.Transaction do
%{tx | previous_signature: previous_signature}
end

defp previous_sign_transaction(tx = %__MODULE__{type: :node_rewards}) do
previous_network_sign_transaction(tx)
end
defp previous_sign_transaction(tx = %__MODULE__{type: type})
when type in [:node_rewards, :mint_rewards] do
key_index = Crypto.number_of_network_pool_keys()

defp previous_sign_transaction(tx = %__MODULE__{}) do
previous_signature =
tx
|> extract_for_previous_signature()
|> serialize()
|> Crypto.sign_with_previous_node_key()
|> Crypto.sign_with_network_pool_key(key_index)

%{tx | previous_signature: previous_signature}
end

defp previous_network_sign_transaction(tx = %__MODULE__{}) do
key_index = Crypto.number_of_network_pool_keys()

defp previous_sign_transaction(tx = %__MODULE__{}) do
previous_signature =
tx
|> extract_for_previous_signature()
|> serialize()
|> Crypto.sign_with_network_pool_key(key_index)
|> Crypto.sign_with_previous_node_key()

%{tx | previous_signature: previous_signature}
end
Expand Down Expand Up @@ -334,6 +311,7 @@ defmodule Archethic.TransactionChain.Transaction do
def serialize_type(:code_proposal), do: 7
def serialize_type(:code_approval), do: 8
def serialize_type(:node_rewards), do: 9
def serialize_type(:mint_rewards), do: 10

# User transaction's type
def serialize_type(:keychain), do: 255
Expand All @@ -357,6 +335,7 @@ defmodule Archethic.TransactionChain.Transaction do
def parse_type(7), do: :code_proposal
def parse_type(8), do: :code_approval
def parse_type(9), do: :node_rewards
def parse_type(10), do: :mint_rewards

# User transaction's type
def parse_type(255), do: :keychain
Expand All @@ -377,6 +356,7 @@ defmodule Archethic.TransactionChain.Transaction do
def network_type?(:oracle), do: true
def network_type?(:oracle_summary), do: true
def network_type?(:node_rewards), do: true
def network_type?(:mint_rewards), do: true
def network_type?(_), do: false

@doc """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,27 @@ defmodule Archethic.TransactionChain.Transaction.ValidationStamp.LedgerOperation
}
end

def from_transaction(ops = %__MODULE__{}, %Transaction{
address: address,
type: :mint_rewards,
data: %TransactionData{content: content}
}) do
[[match | _]] = Regex.scan(~r/(?<=initial supply:).*\d/mi, content)

{initial_supply, _} =
match
|> String.trim()
|> String.replace(" ", "")
|> Integer.parse()

%{
ops
| unspent_outputs: [
%UnspentOutput{from: address, amount: initial_supply * @unit_uco, type: {:NFT, address}}
]
}
end

def from_transaction(ops = %__MODULE__{}, %Transaction{}), do: ops

@doc """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,11 @@ defmodule Archethic.TransactionChain.Transaction.ValidationStamp.LedgerOperation

@spec from_map(map()) :: __MODULE__.t()
def from_map(unspent_output = %{}) do
res = %__MODULE__{
%__MODULE__{
from: Map.get(unspent_output, :from),
amount: Map.get(unspent_output, :amount)
amount: Map.get(unspent_output, :amount),
type: Map.get(unspent_output, :type)
}

case Map.get(unspent_output, :type) do
"NFT" ->
%{res | type: {:NFT, Map.get(unspent_output, :nft_address)}}

_ ->
%{res | type: :UCO}
end
end

@spec to_map(t()) :: map()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ defmodule Archethic.Crypto.SharedSecrets.SoftwareImplTest do
|> stub(:count_transactions_by_type, fn
:node_rewards -> 1
:node_shared_secrets -> 1
:mint_rewards -> 1
end)
|> expect(:list_addresses_by_type, fn :node_shared_secrets ->
[:crypto.strong_rand_bytes(32)]
Expand All @@ -52,7 +53,7 @@ defmodule Archethic.Crypto.SharedSecrets.SoftwareImplTest do
unix_timestamp = DateTime.to_unix(timestamp)

assert [{_, 1}] = :ets.lookup(:archethic_shared_secrets_keystore, :shared_secrets_index)
assert [{_, 1}] = :ets.lookup(:archethic_shared_secrets_keystore, :network_pool_index)
assert [{_, 2}] = :ets.lookup(:archethic_shared_secrets_keystore, :network_pool_index)

assert [{^unix_timestamp, ^daily_nonce_keypair}] =
:ets.tab2list(:archethic_shared_secrets_daily_keys)
Expand Down

0 comments on commit ac799af

Please sign in to comment.