Skip to content
This repository has been archived by the owner on Nov 21, 2024. It is now read-only.

Commit

Permalink
test mint verification
Browse files Browse the repository at this point in the history
  • Loading branch information
NehharShah committed Oct 22, 2024
1 parent 7c18f20 commit 8660bb4
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lib/cashubrew/core/mint_verification.ex
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ end

defmodule Cashubrew.Mint.Verification.Outputs do
@moduledoc """
Logic to verify protocol "outputs" (blinded messages)
Logic to verify protocol "outputs" (blinded messages)
"""

# Will perform all the check required upon some user provided 'output'
Expand Down Expand Up @@ -144,7 +144,7 @@ end

defmodule Cashubrew.Mint.Verification.InputsAndOutputs do
@moduledoc """
Logic to verify protocol "inputs" and "outputs" together
Logic to verify protocol "inputs" and "outputs" together
"""

def verify!(repo, inputs, outputs) do
Expand Down
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ defmodule Cashubrew.MixProject do
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 1.0"},
{:bitcoinex, "~> 0.1.7"},
{:dotenv, "~> 3.0.0"}
{:dotenv, "~> 3.0.0"},
{:meck, "~> 0.9"}
]
end

Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"httpoison": {:hex, :httpoison, "1.8.2", "9eb9c63ae289296a544842ef816a85d881d4a31f518a0fec089aaa744beae290", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "2bb350d26972e30c96e2ca74a1aaf8293d61d0742ff17f01e0279fef11599921"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
"mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"},
Expand Down
157 changes: 157 additions & 0 deletions test/test_mint_verification.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
defmodule Cashubrew.Mint.VerificationTest do
use ExUnit.Case, async: true
alias Cashubrew.Mint.Verification.Amount
alias Cashubrew.Mint.Verification.Inputs
alias Cashubrew.Mint.Verification.Outputs
alias Cashubrew.Mint.Verification.InputsAndOutputs
alias Cashubrew.Nuts.Nut02
alias Cashubrew.Nuts.Nut00.BDHKE

defmodule MockRepo do
def get!(_schema, _id), do: %{active: true, unit: "USD"}
def exists?(_schema, _id), do: false
end

defmodule MockMint do
def get_keyset(_repo, _id), do: %{unit: "USD", input_fee_ppk: 1}
def get_key_for_amount(_repo, _id, _amount), do: "mock_key"
end

describe "Amount.verify!/1" do
test "raises error for negative amount" do
assert_raise RuntimeError, "BlindMessageAmountShouldBePositive", fn ->
Amount.verify!(-1)
end
end

test "raises error for amount exceeding max order" do
max_order = Nut02.Keyset.max_order()
assert_raise RuntimeError, "BlindMessageAmountNotExceed2^MaxOrder", fn ->
Amount.verify!(2 ** (max_order + 1))
end
end

test "passes for valid amount" do
assert Amount.verify!(100) == nil
end
end

describe "Inputs.verify!/2" do
setup do
inputs = [
%{id: "1", amount: 100, secret: "secret1", C: "C1"},
%{id: "2", amount: 200, secret: "secret2", C: "C2"}
]
{:ok, inputs: inputs}
end

test "raises error for empty list", %{inputs: _inputs} do
assert_raise RuntimeError, "EmptyListOfProof", fn ->
Inputs.verify!(MockRepo, [])
end
end

test "raises error for duplicate secrets", %{inputs: inputs} do
duplicate_inputs = inputs ++ [%{id: "3", amount: 300, secret: "secret1", C: "C3"}]
assert_raise RuntimeError, "DuplicateProofInList", fn ->
Inputs.verify!(MockRepo, duplicate_inputs)
end
end

test "passes for valid inputs", %{inputs: inputs} do
:meck.new(BDHKE, [:passthrough])
:meck.expect(BDHKE, :verify?, fn _, _, _ -> true end)

result = Inputs.verify!(MockRepo, inputs)
assert is_tuple(result)
assert tuple_size(result) == 3

:meck.unload(BDHKE)
end
end

describe "Outputs.verify!/2" do
setup do
outputs = [
%{id: "1", amount: 100, B_: "B1"},
%{id: "1", amount: 200, B_: "B2"}
]
{:ok, outputs: outputs}
end

test "raises error for empty list", %{outputs: _outputs} do
assert_raise RuntimeError, "Empty", fn ->
Outputs.verify!(MockRepo, [])
end
end

test "raises error for different keyset ids", %{outputs: outputs} do
invalid_outputs = outputs ++ [%{id: "2", amount: 300, B_: "B3"}]
assert_raise RuntimeError, "DifferentKeysetIds", fn ->
Outputs.verify!(MockRepo, invalid_outputs)
end
end

test "passes for valid outputs", %{outputs: outputs} do
result = Outputs.verify!(MockRepo, outputs)
assert is_tuple(result)
assert tuple_size(result) == 2
end
end

describe "InputsAndOutputs.verify!/3" do
setup do
inputs = [
%{id: "1", amount: 100, secret: "secret1", C: "C1"},
%{id: "1", amount: 200, secret: "secret2", C: "C2"}
]
outputs = [
%{id: "1", amount: 290, B_: "B1"}
]
{:ok, inputs: inputs, outputs: outputs}
end

test "raises error for different input and output units", %{inputs: inputs, outputs: outputs} do
:meck.new(Inputs, [:passthrough])
:meck.expect(Inputs, :verify!, fn _, _ -> {10, 300, "USD"} end)

:meck.new(Outputs, [:passthrough])
:meck.expect(Outputs, :verify!, fn _, _ -> {%{unit: "EUR"}, 290} end)

assert_raise RuntimeError, "DifferentInputAndOutputUnit", fn ->
InputsAndOutputs.verify!(MockRepo, inputs, outputs)
end

:meck.unload(Inputs)
:meck.unload(Outputs)
end

test "raises error for invalid amount and fee", %{inputs: inputs, outputs: outputs} do
:meck.new(Inputs, [:passthrough])
:meck.expect(Inputs, :verify!, fn _, _ -> {10, 300, "USD"} end)

:meck.new(Outputs, [:passthrough])
:meck.expect(Outputs, :verify!, fn _, _ -> {%{unit: "USD"}, 280} end)

assert_raise RuntimeError, "InvalidAmountAndFee", fn ->
InputsAndOutputs.verify!(MockRepo, inputs, outputs)
end

:meck.unload(Inputs)
:meck.unload(Outputs)
end

test "passes for valid inputs and outputs", %{inputs: inputs, outputs: outputs} do
:meck.new(Inputs, [:passthrough])
:meck.expect(Inputs, :verify!, fn _, _ -> {10, 300, "USD"} end)

:meck.new(Outputs, [:passthrough])
:meck.expect(Outputs, :verify!, fn _, _ -> {%{unit: "USD"}, 290} end)

assert InputsAndOutputs.verify!(MockRepo, inputs, outputs) == nil

:meck.unload(Inputs)
:meck.unload(Outputs)
end
end
end

0 comments on commit 8660bb4

Please sign in to comment.