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

Commit

Permalink
Disallow duplicate payees
Browse files Browse the repository at this point in the history
  • Loading branch information
vihu committed Mar 2, 2020
1 parent 47fa1dd commit 4e22608
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 34 deletions.
44 changes: 29 additions & 15 deletions src/transactions/v2/blockchain_txn_payment_v2.erl
Expand Up @@ -179,21 +179,27 @@ do_is_valid_checks(Txn, Ledger, MaxPayments) ->
false ->
case lists:member(Payer, ?MODULE:payees(Txn)) of
false ->
TotAmount = ?MODULE:total_amount(Txn),
Fee = ?MODULE:fee(Txn),
case blockchain_ledger_v1:transaction_fee(Ledger) of
{error, _}=Error0 ->
Error0;
{ok, MinerFee} ->
case (TotAmount >= 0) andalso (Fee >= MinerFee) of
false ->
{error, invalid_transaction};
true ->
case blockchain_ledger_v1:check_dc_balance(Payer, Fee, Ledger) of
{error, _}=Error1 ->
Error1;
ok ->
blockchain_ledger_v1:check_balance(Payer, TotAmount, Ledger)
%% check that every payee is unique
case has_unique_payees(Payments) of
false ->
{error, duplicate_payees};
true ->
TotAmount = ?MODULE:total_amount(Txn),
Fee = ?MODULE:fee(Txn),
case blockchain_ledger_v1:transaction_fee(Ledger) of
{error, _}=Error0 ->
Error0;
{ok, MinerFee} ->
case (TotAmount >= 0) andalso (Fee >= MinerFee) of
false ->
{error, invalid_transaction};
true ->
case blockchain_ledger_v1:check_dc_balance(Payer, Fee, Ledger) of
{error, _}=Error1 ->
Error1;
ok ->
blockchain_ledger_v1:check_balance(Payer, TotAmount, Ledger)
end
end
end
end;
Expand All @@ -204,6 +210,14 @@ do_is_valid_checks(Txn, Ledger, MaxPayments) ->
end
end.

%% ------------------------------------------------------------------
%% Internal functions
%% ------------------------------------------------------------------

-spec has_unique_payees(Payments :: blockchain_payment_v2:payments()) -> boolean().
has_unique_payees(Payments) ->
Payees = [blockchain_payment_v2:payee(P) || P <- Payments],
length(lists:usort(Payees)) == length(Payees).

%% ------------------------------------------------------------------
%% EUNIT Tests
Expand Down
22 changes: 3 additions & 19 deletions test/blockchain_payment_v2_SUITE.erl
Expand Up @@ -137,10 +137,10 @@ single_payee_test(Config) ->
same_payees_test(Config) ->
BaseDir = ?config(base_dir, Config),
ConsensusMembers = ?config(consensus_members, Config),
Balance = ?config(balance, Config),
_Balance = ?config(balance, Config),
BaseDir = ?config(base_dir, Config),
Chain = ?config(chain, Config),
Swarm = ?config(swarm, Config),
_Swarm = ?config(swarm, Config),

%% Test a payment transaction, add a block and check balances
[_, {Payer, {_, PayerPrivKey, _}}|_] = ConsensusMembers,
Expand All @@ -156,23 +156,7 @@ same_payees_test(Config) ->
SignedTx = blockchain_txn_payment_v2:sign(Tx, SigFun),

ct:pal("~s", [blockchain_txn:print(SignedTx)]),

Block = test_utils:create_block(ConsensusMembers, [SignedTx]),
_ = blockchain_gossip_handler:add_block(Swarm, Block, Chain, self()),

?assertEqual({ok, blockchain_block:hash_block(Block)}, blockchain:head_hash(Chain)),
?assertEqual({ok, Block}, blockchain:head_block(Chain)),
?assertEqual({ok, 2}, blockchain:height(Chain)),

?assertEqual({ok, Block}, blockchain:get_block(2, Chain)),

Ledger = blockchain:ledger(Chain),

{ok, NewEntry0} = blockchain_ledger_v1:find_entry(Recipient, Ledger),
?assertEqual(Balance + 2*Amount, blockchain_ledger_entry_v1:balance(NewEntry0)),

{ok, NewEntry1} = blockchain_ledger_v1:find_entry(Payer, Ledger),
?assertEqual(Balance - 2*Amount, blockchain_ledger_entry_v1:balance(NewEntry1)),
?assertEqual({error, duplicate_payees}, blockchain_txn_payment_v2:is_valid(SignedTx, Chain)),
ok.

different_payees_test(Config) ->
Expand Down

0 comments on commit 4e22608

Please sign in to comment.