defmodule Elixium.Error do alias Elixium.Error @moduledoc """ Converts error tuples to human-readable strings. """ @doc """ Converts a tuple in the form {:error, any} to a string. """ @spec to_string({:error, any}) :: String.t() def to_string({:error, err}), do: str(err) def to_string(err), do: "Error #{inspect(err)} isn't a valid error tuple" defp str({:invalid_index, prev, index}), do: "Invalid index #{:binary.decode_unsigned(index)}, expected > #{:binary.decode_unsigned(prev)}" defp str({:wrong_hash, reason}), do: "Invalid hash: #{hash_err(reason)}" defp str(:no_coinbase), do: "No coinbase found in a block" defp str(:invalid_inputs), do: "Invalid transaction inputs" defp str(:block_too_large), do: "Block too large -- Exceeds byte limit" defp str({:not_coinbase, txtype}), do: "The first transaction is not a coinbase, but a #{txtype}" defp str({:invalid_coinbase, fees, reward, amount}), do: "The coinbase is invalid, since the fees (#{fees}) + reward (#{reward}) ≠ coinbase amount (#{ amount })" defp str({:invalid_difficulty, difficulty, diff}), do: "Invalid block difficulty #{difficulty}. expected #{diff}" defp str({:invalid_tx_id, expected, received}), do: "Invalid transaction id. Calculated #{expected} but got #{received}" defp str(:failed_pool_check), do: "Input in transaction was not found in UTXO pool" defp str(:sig_set_mismatch), do: "Transaction is missing signature(s)" defp str(:invalid_tx_sig), do: "One or more signatures in transaction are invalid" defp str(:utxo_amount_not_decimal), do: "One or more inputs/outputs in the transaction have an amount that is not of type Decimal" defp str({:outputs_exceed_inputs, output_total, input_total}), do: "Outputs exceed inputs. Outputs: #{output_total}, Inputs: #{input_total}" defp str({:invalid_transaction, errors}), do: Enum.each(errors, &Error.to_string/1) defp str(err), do: "Unrecognized error: #{err}" defp hash_err({:doesnt_match_last, prev, hash}), do: "Doesn't match last hash. expected #{prev}, got #{hash}" defp hash_err({:too_high, hash, difficulty}), do: "Hash #{hash} is too high for a difficulty of #{difficulty}" defp hash_err({:doesnt_match_provided, computed, hash}), do: "Provided hash #{hash} doesn't equal #{computed}" end