From 15909ce437212f06070c1d7d72a133be183c77ba Mon Sep 17 00:00:00 2001 From: Neylix Date: Mon, 13 Jan 2025 16:39:35 +0100 Subject: [PATCH] Refactor Contracts functions --- lib/archethic/contracts.ex | 14 +++++++++++++ lib/archethic/contracts/wasm/contract.ex | 20 ++++++++----------- .../mining/pending_transaction_validation.ex | 9 +-------- lib/archethic/mining/proof_of_work.ex | 6 ++---- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/lib/archethic/contracts.ex b/lib/archethic/contracts.ex index 8e0616971..326530f0f 100644 --- a/lib/archethic/contracts.ex +++ b/lib/archethic/contracts.ex @@ -788,6 +788,20 @@ defmodule Archethic.Contracts do end end + @doc """ + Returns a contract instance from a transaction + """ + @spec validate_and_parse_transaction(transaction :: Transaction.t()) :: + {:ok, InterpretedContract.t() | WasmContract.t()} | {:error, String.t()} + def validate_and_parse_transaction(tx = %Transaction{version: version}) when version < 4, + do: InterpretedContract.from_transaction(tx) + + def validate_and_parse_transaction(%Transaction{data: %TransactionData{contract: nil}}), + do: {:error, "No contract to parse"} + + def validate_and_parse_transaction(%Transaction{data: %TransactionData{contract: contract}}), + do: WasmContract.validate_and_parse(contract) + defp get_condition_constants( :inherit, %InterpretedContract{ diff --git a/lib/archethic/contracts/wasm/contract.ex b/lib/archethic/contracts/wasm/contract.ex index 901d1878e..3683f58ef 100644 --- a/lib/archethic/contracts/wasm/contract.ex +++ b/lib/archethic/contracts/wasm/contract.ex @@ -52,18 +52,6 @@ defmodule Archethic.Contracts.WasmContract do end end - @doc """ - Parse smart contract json block and return a contract struct - """ - @spec parse(Contract.t()) :: t() - def parse(%Contract{manifest: manifest, bytecode: bytecode}) do - uncompressed_bytes = :zlib.unzip(bytecode) - spec = WasmSpec.from_manifest(manifest) - - {:ok, module} = WasmModule.parse(uncompressed_bytes, spec) - %__MODULE__{module: module} - end - @doc """ Validate WASM contract """ @@ -91,6 +79,14 @@ defmodule Archethic.Contracts.WasmContract do {:ok, %__MODULE__{parse(contract) | state: get_state_from_tx(tx), transaction: tx}} end + defp parse(%Contract{manifest: manifest, bytecode: bytecode}) do + uncompressed_bytes = :zlib.unzip(bytecode) + spec = WasmSpec.from_manifest(manifest) + + {:ok, module} = WasmModule.parse(uncompressed_bytes, spec) + %__MODULE__{module: module} + end + defp get_state_from_tx(%Transaction{ validation_stamp: %ValidationStamp{ ledger_operations: %LedgerOperations{unspent_outputs: utxos} diff --git a/lib/archethic/mining/pending_transaction_validation.ex b/lib/archethic/mining/pending_transaction_validation.ex index 61c11c809..ed047461d 100644 --- a/lib/archethic/mining/pending_transaction_validation.ex +++ b/lib/archethic/mining/pending_transaction_validation.ex @@ -179,19 +179,12 @@ defmodule Archethic.Mining.PendingTransactionValidation do end defp parse_contract(tx) do - case validate_and_parse_transaction(tx) do + case Contracts.validate_and_parse_transaction(tx) do {:ok, contract} -> {:ok, contract} {:error, reason} -> {:error, "Smart contract invalid #{inspect(reason)}"} end end - defp validate_and_parse_transaction(tx = %Transaction{data: %TransactionData{code: code}}) - when code != "", - do: Contracts.Interpreter.Contract.from_transaction(tx) - - defp validate_and_parse_transaction(%Transaction{data: %TransactionData{contract: contract}}), - do: Contracts.WasmContract.validate_and_parse(contract) - defp validate_contract_ownership(contract, ownerships) do if Contracts.contains_trigger?(contract), do: ensure_ownership_in_contract(ownerships), diff --git a/lib/archethic/mining/proof_of_work.ex b/lib/archethic/mining/proof_of_work.ex index 84a4587d3..58d12907f 100644 --- a/lib/archethic/mining/proof_of_work.ex +++ b/lib/archethic/mining/proof_of_work.ex @@ -112,9 +112,9 @@ defmodule Archethic.Mining.ProofOfWork do Smart contract code can defined which family to use (like security level) """ + # TODO: support WasmContract inherit conditions @spec list_origin_public_keys_candidates(Transaction.t()) :: list(Crypto.key()) - def list_origin_public_keys_candidates(tx = %Transaction{data: %TransactionData{code: code}}) - when code != "" do + def list_origin_public_keys_candidates(tx = %Transaction{version: version}) when version < 4 do case Contracts.from_transaction(tx) do {:ok, %InterpretedContract{ @@ -127,8 +127,6 @@ defmodule Archethic.Mining.ProofOfWork do when family != :all -> SharedSecrets.list_origin_public_keys(family) - # TODO: support WasmContract inherit conditions - _ -> do_list_origin_public_keys_candidates(tx) end