Skip to content

Commit

Permalink
Add transaction's content verification
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmanzanera committed Dec 2, 2022
1 parent 2b52177 commit 92f4670
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
75 changes: 75 additions & 0 deletions lib/archethic/mining/pending_transaction_validation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ defmodule Archethic.Mining.PendingTransactionValidation do
TransactionData,
TransactionData.Ledger,
TransactionData.Ownership,
TransactionData.UCOLedger,
TransactionData.TokenLedger,
TransactionSummary
}
Expand Down Expand Up @@ -243,6 +244,47 @@ defmodule Archethic.Mining.PendingTransactionValidation do
end
end

defp do_accept_transaction(
%Transaction{
type: :transfer,
data: %TransactionData{
ledger: %Ledger{
uco: %UCOLedger{transfers: uco_transfers},
token: %TokenLedger{transfers: token_transfers}
},
recipients: recipients
}
},
_
) do
if length(uco_transfers) > 0 or length(token_transfers) > 0 or length(recipients) > 0 do
:ok
else
{:error,
"Transfer's transaction requires some recipients for ledger or smart contract calls"}
end
end

defp do_accept_transaction(
%Transaction{
type: :hosting,
data: %TransactionData{content: content}
},
_
) do
with {:ok, json} <- Jason.decode(content),
:ok <- check_aeweb_format(json) do
:ok
else
:error ->
{:error, "Invalid AEWeb transaction"}

{:error, reason} ->
Logger.debug("Invalid AEWeb format #{inspect(reason)}")
{:error, "Invalid AEWeb transaction"}
end
end

defp do_accept_transaction(
tx = %Transaction{
type: :node_rewards,
Expand Down Expand Up @@ -762,4 +804,37 @@ defmodule Archethic.Mining.PendingTransactionValidation do
{:error, :invalid_ip}
end
end

defp check_aeweb_format(json) do
ref_schema =
:archethic
|> Application.app_dir("priv/json-schemas/aeweb_ref.json")
|> File.read!()
|> Jason.decode!()
|> ExJsonSchema.Schema.resolve()

file_schema =
:archethic
|> Application.app_dir("priv/json-schemas/aeweb_file.json")
|> File.read!()
|> Jason.decode!()
|> ExJsonSchema.Schema.resolve()

case ExJsonSchema.Validator.validate(ref_schema, json) do
:ok ->
:ok

{:error, [{"Required properties aewebVersion, metadata were not present.", _}]} ->
case ExJsonSchema.Validator.validate(file_schema, json) do
:ok ->
:ok

{:error, error_file} ->
{:error, error_file}
end

{:error, error_ref} ->
{:error, error_ref}
end
end
end
45 changes: 45 additions & 0 deletions test/archethic/mining/pending_transaction_validation_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ defmodule Archethic.Mining.PendingTransactionValidationTest do

alias Archethic.TransactionChain.Transaction
alias Archethic.TransactionChain.TransactionData
alias Archethic.TransactionChain.TransactionData.Ledger
alias Archethic.TransactionChain.TransactionData.UCOLedger
alias Archethic.TransactionChain.TransactionData.UCOLedger.Transfer
alias Archethic.TransactionChain.TransactionData.Ownership

alias Archethic.SharedSecrets
Expand Down Expand Up @@ -490,6 +493,13 @@ defmodule Archethic.Mining.PendingTransactionValidationTest do
Transaction.new(
:transfer,
%TransactionData{
ledger: %Ledger{
uco: %UCOLedger{
transfers: [
%Transfer{to: :crypto.strong_rand_bytes(32), amount: 100_000}
]
}
},
code: """
condition inherit: [
content: "hello"
Expand Down Expand Up @@ -724,5 +734,40 @@ defmodule Archethic.Mining.PendingTransactionValidationTest do
assert {:error, "Invalid node rewards trigger time"} =
PendingTransactionValidation.validate(tx, ~U[2022-01-01 00:00:03Z])
end

test "should return :ok when we deploy a aeweb ref transaction" do
tx =
Transaction.new(:hosting, %TransactionData{
content:
Jason.encode!(%{
"aewebVersion" => 1,
"metadata" => %{
"index.html" => %{
"encoding" => "gzip",
"addresses" => [
Crypto.derive_keypair("seed", 0)
|> elem(0)
|> Crypto.derive_address()
|> Base.encode16()
]
}
}
})
})

assert :ok = PendingTransactionValidation.validate(tx, DateTime.utc_now())
end

test "should return :ok when we deploy a aeweb file transaction" do
tx =
Transaction.new(:hosting, %TransactionData{
content:
Jason.encode!(%{
"index.html" => Base.url_encode64(:crypto.strong_rand_bytes(1000))
})
})

assert :ok = PendingTransactionValidation.validate(tx, DateTime.utc_now())
end
end
end

0 comments on commit 92f4670

Please sign in to comment.