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

Introduce var to change how xor filter update txn fees are calculated #1303

Merged
merged 10 commits into from
Apr 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/blockchain_vars.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,9 @@
%% - 1 :: accept first dispute, drop all DC from opener, no rewards
-define(sc_dispute_strategy_version, sc_dispute_strategy_version).

%% Txn Routing Xor Filter Fee calculation var HIP-XXX
macpie marked this conversation as resolved.
Show resolved Hide resolved
-define(txn_routing_update_xor_fees_version, txn_routing_update_xor_fees_version).

%% ------------------------------------------------------------------
%% snapshot vars

Expand Down
122 changes: 120 additions & 2 deletions src/transactions/v1/blockchain_txn_routing_v1.erl
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,56 @@ calculate_fee(Txn, Chain) ->
-spec calculate_fee(txn_routing(), blockchain_ledger_v1:ledger(), pos_integer(), pos_integer(), boolean()) -> non_neg_integer().
calculate_fee(_Txn, _Ledger, _DCPayloadSize, _TxnFeeMultiplier, false) ->
?LEGACY_TXN_FEE;
calculate_fee(Txn, Ledger, DCPayloadSize, TxnFeeMultiplier, true) ->
?calculate_fee(Txn#blockchain_txn_routing_v1_pb{fee=0, staking_fee = 0, signature = <<0:512>>}, Ledger, DCPayloadSize, TxnFeeMultiplier).
calculate_fee(Txn0, Ledger, DCPayloadSize, TxnFeeMultiplier, true) ->
FeeVersion =
case blockchain:config(?txn_routing_update_xor_fees_version, Ledger) of
{ok, V} -> V;
_ -> 0
end,
Txn1 = Txn0#blockchain_txn_routing_v1_pb{
fee=0,
staking_fee = 0,
signature = <<0:512>>
},
case FeeVersion of
1 ->
Action = ?MODULE:action(Txn1),
case Action of
{update_xor, Index, Filter} ->
%% Find out current size at index, get new size, calculate diff
OUI = Txn0#blockchain_txn_routing_v1_pb.oui,
OldFilter =
case blockchain_ledger_v1:find_routing(OUI, Ledger) of
{ok, Routing} ->
Filters = blockchain_ledger_routing_v1:filters(Routing),
%% We do +1 here because Index is "0 indexed"
%% and lists:nth/2 does not support 0
lists:nth(Index+1, Filters);
_Error ->
macpie marked this conversation as resolved.
Show resolved Hide resolved
lager:error("we failed to get routing info for OUI=~p : ~p", [OUI, _Error]),
<<>>
end,
SizeDiff = erlang:byte_size(Filter) - erlang:byte_size(OldFilter),
%% If diff =< 0, meaning that old filter is bigger than new one we set new filter to be empty
%% If diff > 0, we calculate fees based on a random binary of same size
case SizeDiff =< 0 of
true ->
Txn2 = Txn1#blockchain_txn_routing_v1_pb{
update={update_xor, #update_xor_pb{index=Index, filter= <<>>}}
},
?calculate_fee(Txn2, Ledger, DCPayloadSize, TxnFeeMultiplier);
false ->
Txn2 = Txn1#blockchain_txn_routing_v1_pb{
update={update_xor, #update_xor_pb{index=Index, filter= <<0:(8*SizeDiff)>>}}
},
?calculate_fee(Txn2, Ledger, DCPayloadSize, TxnFeeMultiplier)
end;
_ ->
?calculate_fee(Txn1, Ledger, DCPayloadSize, TxnFeeMultiplier)
end;
_ ->
?calculate_fee(Txn1, Ledger, DCPayloadSize, TxnFeeMultiplier )
end.

%%--------------------------------------------------------------------
%% @doc
Expand Down Expand Up @@ -584,4 +632,74 @@ to_json_test() ->
?assert(lists:all(fun(K) -> maps:is_key(K, Json) end,
[type, hash, oui, owner, fee, action, nonce])).


calculate_fee_test_() ->
{timeout, 30000,
fun() ->
OUI = 1,
Owner = crypto:strong_rand_bytes(32),
Routing =
blockchain_ledger_routing_v1:new(
OUI,
Owner,
[],
crypto:strong_rand_bytes(100),
<<>>,
1
),
meck:new(blockchain_ledger_v1, [passthrough]),
meck:expect(blockchain_ledger_v1, find_routing, fun(_, _) ->
{ok, Routing}
end),

meck:new(blockchain, [passthrough]),
%% Set txn_routing_update_xor_fees_version to 0
meck:expect(blockchain, config, fun(_, _) ->
{ok, 0}
end),

Index = 0,
Xor = crypto:strong_rand_bytes(200),
Nonce = 1,
Txn = blockchain_txn_routing_v1:update_xor(OUI, Owner, Index, Xor, Nonce),

%% Testing legacy path
?assertEqual(?LEGACY_TXN_FEE, calculate_fee(Txn, ledger, 1, 1, false)),

%% Testing old version (pay for full xor size)
?assertEqual(313, calculate_fee(Txn, ledger, 1, 1, true)),

%% Set txn_routing_update_xor_fees_version to 1
meck:expect(blockchain, config, fun(_, _) ->
{ok, 1}
end),

%% Testing with version 1 (pay for diff of xor size)
?assertEqual(211, calculate_fee(Txn, ledger, 1, 1, true)),

Xor1 = crypto:strong_rand_bytes(50),
Txn1 = blockchain_txn_routing_v1:update_xor(OUI, Owner, Index, Xor1, Nonce),

%% Testing with smaller xor
?assertEqual(108, calculate_fee(Txn1, ledger, 1, 1, true)),

Xor2 = crypto:strong_rand_bytes(102),
Txn2 = blockchain_txn_routing_v1:update_xor(OUI, Owner, Index, Xor2, Nonce),

%% Testing with small update to show price diff with previous version
%% 112 compare to > 300
?assertEqual(112, calculate_fee(Txn2, ledger, 1, 1, true)),
macpie marked this conversation as resolved.
Show resolved Hide resolved

Xor3 = crypto:strong_rand_bytes(102),
Txn3 = blockchain_txn_routing_v1:update_xor(OUI, Owner, Index, Xor3, Nonce),

%% Xor3 is same size as Xor2, no change in fee.
?assertEqual(112, calculate_fee(Txn3, ledger, 1, 1, true)),

meck:unload(blockchain_ledger_v1),
meck:unload(blockchain),
ok
end
}.

-endif.
9 changes: 9 additions & 0 deletions src/transactions/v1/blockchain_txn_vars_v1.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,15 @@ validate_var(?sc_only_count_open_active, Value) ->
validate_var(?sc_dispute_strategy_version, Value) ->
validate_int(Value, "sc_dispute_strategy_version", 0, 1, false);

%% Txn Routing Xor Filter Fee calculation var HIP-XXX
validate_var(?txn_routing_update_xor_fees_version, Value) ->
case Value of
N when is_integer(N), N == 1 ->
ok;
_ ->
throw({error, {invalid_txn_routing_update_xor_fees_version, Value}})
end;

%% txn snapshot vars
validate_var(?snapshot_version, Value) ->
case Value of
Expand Down