Skip to content

Commit

Permalink
N.2.6.8.old (#424)
Browse files Browse the repository at this point in the history
Release 2.6.8
Release Number 63

This release introduces a patch that adds to the transition period before the
activation of Arweave 2.6’s trustless price oracle, in order to give miners
additional time to on-board packed data to the network. The release delays
the onset of the transition window by 4 months, and extends the interpolation
between of old and new pricing systems to 18 months, from 12.

This release introduces a hard fork that activates at height 1,189,560,
approximately 2023-05-30 16:00 UTC. You will need to make sure you have
upgraded your miner before this time to connect to the network.
  • Loading branch information
JamesPiechota committed May 27, 2023
1 parent 4f5d69a commit 7d89b53
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 37 deletions.
2 changes: 1 addition & 1 deletion apps/arweave/include/ar.hrl
Expand Up @@ -29,7 +29,7 @@
-define(CLIENT_VERSION, 5).

%% The current build number -- incremented for every release.
-define(RELEASE_NUMBER, 62).
-define(RELEASE_NUMBER, 63).

-define(DEFAULT_REQUEST_HEADERS,
[
Expand Down
28 changes: 28 additions & 0 deletions apps/arweave/include/ar_pricing.hrl
@@ -1,5 +1,8 @@
%% @doc Pricing macros.

%% The number of bytes in a gibibyte.
-define(GiB, (1024 * 1024 * 1024)).

%% For a new account, we charge the fee equal to the price of uploading
%% this number of bytes. The fee is about 0.1$ at the time.
-define(NEW_ACCOUNT_FEE_DATA_SIZE_EQUIVALENT, 20_000_000).
Expand Down Expand Up @@ -82,6 +85,29 @@ end).
-endif.
-endif.

-ifdef(DEBUG).
-define(PRICE_2_6_8_TRANSITION_START, 2).
-else.
-ifdef(FORKS_RESET).
-define(PRICE_2_6_8_TRANSITION_START, 0).
-else.
-define(PRICE_2_6_8_TRANSITION_START, (30 * 24 * 30 * 4)). % ~4 months;
-endif.
-endif.

-ifdef(DEBUG).
-define(PRICE_2_6_8_TRANSITION_BLOCKS, 2).
-else.
-ifdef(FORKS_RESET).
-define(PRICE_2_6_8_TRANSITION_BLOCKS, 0).
-else.
-ifndef(PRICE_2_6_8_TRANSITION_BLOCKS).
-define(PRICE_2_6_8_TRANSITION_BLOCKS, (30 * 24 * 30 * 18)). % ~18 months.
-endif.
-endif.
-endif.


%% The number of recent blocks contributing data points to the continuous estimation
%% of the average price of storing a gibibyte for a minute. Also, the reward history
%% is used to tracking the reserved mining rewards.
Expand Down Expand Up @@ -243,6 +269,8 @@ end).
%% Used until the transition to the new fee calculation method is complete.
-define(USD_PER_GBY_2019, {925, 1000000}). % 0.000925

-define(STATIC_2_6_8_FEE_WINSTON, 858_000_000_000).

%% The largest possible multiplier for a one-step increase of the USD to AR Rate.
-define(USD_TO_AR_MAX_ADJUSTMENT_UP_MULTIPLIER, {1005, 1000}).

Expand Down
10 changes: 9 additions & 1 deletion apps/arweave/src/ar_fork.erl
Expand Up @@ -5,7 +5,7 @@
-module(ar_fork).

-export([height_1_6/0, height_1_7/0, height_1_8/0, height_1_9/0, height_2_0/0, height_2_2/0,
height_2_3/0, height_2_4/0, height_2_5/0, height_2_6/0]).
height_2_3/0, height_2_4/0, height_2_5/0, height_2_6/0, height_2_6_8/0]).

-include_lib("arweave/include/ar.hrl").
-include_lib("arweave/include/ar_consensus.hrl").
Expand Down Expand Up @@ -94,3 +94,11 @@ height_2_6() ->
1132210. % Targeting 2023-03-06 14:00 UTC
-endif.
-endif.

-ifdef(FORKS_RESET).
height_2_6_8() ->
0.
-else.
height_2_6_8() ->
1189560. % Targeting 2023-05-30 16:00 UTC
-endif.
11 changes: 4 additions & 7 deletions apps/arweave/src/ar_pricing.erl
Expand Up @@ -18,9 +18,6 @@

-include_lib("eunit/include/eunit.hrl").

%% The number of bytes in a gibibyte.
-define(GiB, 1024 * 1024 * 1024).

%%%===================================================================
%%% Types.
%%%===================================================================
Expand All @@ -39,10 +36,10 @@
%% @doc Return true if the given height is a height where the transition to the
%% new pricing algorithm is complete.
is_v2_pricing_height(Height) ->
Fork_2_6 = ar_fork:height_2_6(),
Height >= Fork_2_6 % First check just this because it may be infinity.
andalso Height >= Fork_2_6 + (?PRICE_2_6_TRANSITION_START)
+ (?PRICE_2_6_TRANSITION_BLOCKS).
Fork_2_6_8 = ar_fork:height_2_6_8(),
Height >= Fork_2_6_8 % First check just this because it may be infinity.
andalso Height >= Fork_2_6_8 + (?PRICE_2_6_8_TRANSITION_START)
+ (?PRICE_2_6_8_TRANSITION_BLOCKS).

%% @doc Return the price per gibibyte minute estimated from the given history of
%% network hash rates and block rewards. The total reward used in calculations
Expand Down
174 changes: 151 additions & 23 deletions apps/arweave/src/ar_tx.erl
Expand Up @@ -559,32 +559,64 @@ get_tx_fee(Args) ->
{DataSize, Rate, PricePerGiBMinute, KryderPlusRateMultiplier, Addr, Timestamp, Accounts,
Height} = Args,
Fork_2_6 = ar_fork:height_2_6(),
Args2 = {DataSize, Rate, Height, Accounts, Addr, Timestamp},
case Height >= Fork_2_6 of
false ->
get_tx_fee_pre_fork_2_6(Args2);
true ->
Args3 = {DataSize, PricePerGiBMinute, KryderPlusRateMultiplier, Addr, Accounts,
Fork_2_6_8 = ar_fork:height_2_6_8(),
PreFork26Args = {DataSize, Rate, Height, Accounts, Addr, Timestamp},
V2PricingArgs = {DataSize, PricePerGiBMinute, KryderPlusRateMultiplier, Addr, Accounts,
Height},
case ar_pricing:is_v2_pricing_height(Height) of
true ->
get_tx_fee2(Args3);
false ->
TransitionStart = Fork_2_6 + ?PRICE_2_6_TRANSITION_START,
TransitionEnd = TransitionStart + ?PRICE_2_6_TRANSITION_BLOCKS,
case Height >= TransitionStart of
true ->
Fee1 = get_tx_fee_pre_fork_2_6(Args2),
Fee2 = get_tx_fee2(Args3),
Interval1 = Height - TransitionStart + 1,
Interval2 = TransitionEnd - (Height + 1),
(Fee1 * Interval2 + Fee2 * Interval1) div (Interval1 + Interval2);
false ->
get_tx_fee_pre_fork_2_6(Args2)
end
end

V2PricingHeight = Fork_2_6_8 + (?PRICE_2_6_8_TRANSITION_START)
+ (?PRICE_2_6_8_TRANSITION_BLOCKS),

TransitionStart_2_6 = Fork_2_6 + ?PRICE_2_6_TRANSITION_START,
TransitionEnd_2_6 = TransitionStart_2_6 + ?PRICE_2_6_TRANSITION_BLOCKS,
TransitionStart_2_6_8 = Fork_2_6_8 + ?PRICE_2_6_8_TRANSITION_START,
TransitionEnd_2_6_8 = TransitionStart_2_6_8 + ?PRICE_2_6_8_TRANSITION_BLOCKS,

case Height of
H when H >= V2PricingHeight ->
%% New pricing is fully live
get_tx_fee2(V2PricingArgs);
H when H >= TransitionStart_2_6_8 ->
%% 2.6.8 transition period. Interpolate between a static fee-based pricing and
%% new pricing throughout the 2.6.8 transition period
get_transition_tx_fee(
get_static_2_6_8_tx_fee(DataSize, Addr, Accounts), %% StartFee
get_tx_fee2(V2PricingArgs), %% EndFee
TransitionStart_2_6_8,
TransitionEnd_2_6_8,
Height);
H when H >= Fork_2_6_8 ->
%% Pre-2.6.8 transition period. Use a static fee-based pricing + new account fee.
get_static_2_6_8_tx_fee(DataSize, Addr, Accounts);
H when H >= TransitionStart_2_6 ->
%% 2.6 transition period. Interpolate between pre-2.6 pricing and new pricing
%% throughout the 2.6 transition period
get_transition_tx_fee(
get_tx_fee_pre_fork_2_6(PreFork26Args), %% StartFee
get_tx_fee2(V2PricingArgs), %% EndFee
TransitionStart_2_6,
TransitionEnd_2_6,
Height);
_ ->
get_tx_fee_pre_fork_2_6(PreFork26Args)
end.

get_static_2_6_8_tx_fee(DataSize, Addr, Accounts) ->
UploadFee = (?STATIC_2_6_8_FEE_WINSTON div ?GiB) * (DataSize + ?TX_SIZE_BASE),
case Addr == <<>> orelse maps:is_key(Addr, Accounts) of
true ->
UploadFee;
false ->
NewAccountFee = (?STATIC_2_6_8_FEE_WINSTON div ?GiB) *
?NEW_ACCOUNT_FEE_DATA_SIZE_EQUIVALENT,
UploadFee + NewAccountFee
end.

get_transition_tx_fee(StartFee, EndFee, StartHeight, EndHeight, Height) ->
Interval1 = Height - StartHeight + 1,
Interval2 = EndHeight - (Height + 1),
(StartFee * Interval2 + EndFee * Interval1) div (Interval1 + Interval2).

get_tx_fee2(Args) ->
{DataSize, PricePerGiBMinute, KryderPlusRateMultiplier, Addr, Accounts, Height} = Args,
Args2 = {DataSize + ?TX_SIZE_BASE, PricePerGiBMinute, KryderPlusRateMultiplier, Height},
Expand Down Expand Up @@ -907,3 +939,99 @@ get_weave_size_increase_test() ->
get_weave_size_increase(#tx{ data_size = 1 }, ar_fork:height_2_5() - 1)),
?assertEqual(262144,
get_weave_size_increase(#tx{ data_size = 256 * 1024 }, ar_fork:height_2_5() - 1)).

%% @doc Primarily test the different branches in the ar_tx:get_tx_fee logic. Several
%% of the pricing constants have test specific values which means the fees asserted here
%% will not match true mainnet fees.
get_tx_fee_test() ->
meck:new(ar_fork, [passthrough]),
meck:expect(ar_fork, height_2_6, fun() -> 1132210 end),
meck:expect(ar_fork, height_2_6_8, fun() -> 1189560 end),

Addr = crypto:strong_rand_bytes(32),

%% After the 2.6 transition starts
Height3 = ar_fork:height_2_6() + ?PRICE_2_6_TRANSITION_START,
test_get_tx_fee(1, Height3, <<>>, 2748223),
test_get_tx_fee(2, Height3, <<>>, 2749079),
test_get_tx_fee(2 * ?GiB, Height3, <<>>, 1837986144189),
%% +new account fee
test_get_tx_fee(1, Height3, Addr, 21460170515),
test_get_tx_fee(2, Height3, Addr, 21460171371),
test_get_tx_fee(2 * ?GiB, Height3, Addr, 1859443566481),

%% After the 2.6 transition starts, with interpolation.
Height4 = ar_fork:height_2_6() + ?PRICE_2_6_TRANSITION_START + 1,
test_get_tx_fee(1, Height4, <<>>, 5284478),
test_get_tx_fee(2, Height4, <<>>, 5286124),
test_get_tx_fee(2 * ?GiB, Height4, <<>>, 3534209808925),
%% +new account fee
test_get_tx_fee(1, Height4, Addr, 32920129062),
test_get_tx_fee(2, Height4, Addr, 32920130708),
test_get_tx_fee(2 * ?GiB, Height4, Addr, 3567124653509),

%% After the 2.6.8 hard fork
Height5 = ar_fork:height_2_6_8(),
test_get_tx_fee(1, Height5, <<>>, 2565589),
test_get_tx_fee(2, Height5, <<>>, 2566388),
test_get_tx_fee(2 * ?GiB, Height5, <<>>, 1715841999542),
%% +new account fee
test_get_tx_fee(1, Height5, Addr, 15982565589),
test_get_tx_fee(2, Height5, Addr, 15982566388),
test_get_tx_fee(2 * ?GiB, Height5, Addr, 1731821999542),

%% After the 2.6.8 hard fork. Second sample to confirm static pricing.
Height6 = ar_fork:height_2_6_8() + 1,
test_get_tx_fee(1, Height6, <<>>, 2565589),
test_get_tx_fee(2, Height6, <<>>, 2566388),
test_get_tx_fee(2 * ?GiB, Height6, <<>>, 1715841999542),
%% +new account fee
test_get_tx_fee(1, Height6, Addr, 15982565589),
test_get_tx_fee(2, Height6, Addr, 15982566388),
test_get_tx_fee(2 * ?GiB, Height6, Addr, 1731821999542),

%% After the 2.6.8 transition starts
Height7 = ar_fork:height_2_6_8() + ?PRICE_2_6_8_TRANSITION_START,
test_get_tx_fee(1, Height7, <<>>, 3925033),
test_get_tx_fee(2, Height7, <<>>, 3926256),
test_get_tx_fee(2 * ?GiB, Height7, <<>>, 2625025904233),
%% +new account fee
test_get_tx_fee(1, Height7, Addr, 24451347325),
test_get_tx_fee(2, Height7, Addr, 24451348548),
test_get_tx_fee(2 * ?GiB, Height7, Addr, 2649473326525),

%% After the 2.6 transition starts, with interpolation
Height8 = ar_fork:height_2_6_8() + ?PRICE_2_6_8_TRANSITION_START + 1,
test_get_tx_fee(1, Height8, <<>>, 5284478),
test_get_tx_fee(2, Height8, <<>>, 5286124),
test_get_tx_fee(2 * ?GiB, Height8, <<>>, 3534209808925),
%% +new account fee
test_get_tx_fee(1, Height8, Addr, 32920129062),
test_get_tx_fee(2, Height8, Addr, 32920130708),
test_get_tx_fee(2 * ?GiB, Height8, Addr, 3567124653509),

%% V2Pricing
Height9 = ar_fork:height_2_6_8() + ?PRICE_2_6_8_TRANSITION_START + ?PRICE_2_6_8_TRANSITION_BLOCKS,
test_get_tx_fee(1, Height9, <<>>, 5284478),
test_get_tx_fee(2, Height9, <<>>, 5286124),
test_get_tx_fee(2 * ?GiB, Height9, <<>>, 3534209808925),
%% +new account fee
test_get_tx_fee(1, Height9, Addr, 32920129062),
test_get_tx_fee(2, Height9, Addr, 32920130708),
test_get_tx_fee(2 * ?GiB, Height9, Addr, 3567124653509),

meck:unload(ar_fork).


test_get_tx_fee(DataSize, Height, Addr, ExpectedFee) ->
Rate = {1, 10},
PricePerGiBMinute = 8025,
KryderPlusRateMultiplier = 1,
Timestamp = os:system_time(seconds),
Accounts = #{},

?assertEqual(ExpectedFee,
ar_tx:get_tx_fee({DataSize, Rate, PricePerGiBMinute,
KryderPlusRateMultiplier, Addr, Timestamp, Accounts, Height})).


2 changes: 1 addition & 1 deletion apps/arweave/src/arweave.app.src
@@ -1,6 +1,6 @@
{application, arweave, [
{description, "Arweave"},
{vsn, "2.6.7.1"},
{vsn, "2.6.8"},
{mod, {ar, []}},
{applications, [
kernel,
Expand Down
11 changes: 8 additions & 3 deletions apps/arweave/test/ar_pricing_tests.erl
Expand Up @@ -19,6 +19,7 @@
read_block_when_stored/1]).

-define(HUGE_WEAVE_SIZE, 1000000000000000).
-define(DISTANT_FUTURE_BLOCK_HEIGHT, 262800000). %% 1,000 years from genesis

auto_redenomination_and_endowment_debt_test_() ->
{timeout, 120, fun test_auto_redenomination_and_endowment_debt/0}.
Expand Down Expand Up @@ -348,7 +349,8 @@ assert_new_account_fee() ->

updates_pool_and_assigns_rewards_correctly_before_burden_test_() ->
test_with_mocked_functions(
[{ar_fork, height_2_6, fun() -> infinity end}],
[{ar_fork, height_2_6, fun() -> ?DISTANT_FUTURE_BLOCK_HEIGHT end},
{ar_fork, height_2_6_8, fun() -> ?DISTANT_FUTURE_BLOCK_HEIGHT end}],
fun updates_pool_and_assigns_rewards_correctly_before_burden/0
).

Expand All @@ -362,13 +364,16 @@ updates_pool_and_assigns_rewards_correctly_after_burden_test_() ->
{ar_pricing, get_miner_reward_and_endowment_pool,
fun ar_pricing_tests:get_miner_reward_and_endowment_pool/1},
{ar_inflation, calculate, fun(_Height) -> 1 end},
{ar_fork, height_2_6, fun() -> infinity end}
{ar_fork, height_2_6, fun() -> ?DISTANT_FUTURE_BLOCK_HEIGHT end},
{ar_fork, height_2_6_8, fun() -> ?DISTANT_FUTURE_BLOCK_HEIGHT end}
],
fun updates_pool_and_assigns_rewards_correctly_after_burden/0
).

unclaimed_rewards_go_to_endowment_pool_test_() ->
ar_test_node:test_with_mocked_functions([{ar_fork, height_2_6, fun() -> infinity end}],
ar_test_node:test_with_mocked_functions([
{ar_fork, height_2_6, fun() -> ?DISTANT_FUTURE_BLOCK_HEIGHT end},
{ar_fork, height_2_6_8, fun() -> ?DISTANT_FUTURE_BLOCK_HEIGHT end}],
fun test_unclaimed_rewards_go_to_endowment_pool/0).

get_miner_reward_and_endowment_pool(Args) ->
Expand Down
2 changes: 1 addition & 1 deletion rebar.config
Expand Up @@ -26,7 +26,7 @@
]}.

{relx, [
{release, {arweave, "2.6.7.1"}, [
{release, {arweave, "2.6.8"}, [
{arweave, load},
ar_sqlite3,
b64fast,
Expand Down

0 comments on commit 7d89b53

Please sign in to comment.