Skip to content

Commit

Permalink
Merge pull request #2731 from aeternity/PT-lima-bidding
Browse files Browse the repository at this point in the history
Pt lima bidding
  • Loading branch information
ThomasArts committed Sep 3, 2019
2 parents 4c0eb69 + c2829a1 commit 6880ce5
Show file tree
Hide file tree
Showing 15 changed files with 639 additions and 89 deletions.
3 changes: 3 additions & 0 deletions apps/aechannel/test/aesc_txs_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -426,12 +426,15 @@ init_per_group(fork_awareness, Config) ->
init_per_group(VM, Config) when VM == aevm; VM == fate ->
aect_test_utils:init_per_group(VM, Config);
init_per_group(_Group, Config) ->
%% Disable name auction for these groups
application:set_env(aecore, name_claim_bid_timeout, 0),
Config.

end_per_group(fork_awareness, _Config) ->
meck:unload(aec_hard_forks),
ok;
end_per_group(_Group, _Config) ->
application:unset_env(aecore, name_claim_bid_timeout),
ok.

init_per_testcase(_, Config) ->
Expand Down
11 changes: 11 additions & 0 deletions apps/aecontract/test/aecontract_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,12 @@ init_per_testcase(fate_environment, Config) ->
aeb_fate_data:make_hash(<<N:256>>)
end),
init_per_testcase_common(fate_environment, Config);
init_per_testcase(TC, Config) when TC == sophia_aens_resolve;
TC == sophia_signatures_aens;
TC == sophia_aens_transactions ->
%% Disable name auction
meck:expect(aec_governance, name_claim_bid_timeout, fun(_, _) -> 0 end),
init_per_testcase_common(TC, Config);
init_per_testcase(TC, Config) ->
init_per_testcase_common(TC, Config).

Expand Down Expand Up @@ -539,6 +545,11 @@ init_per_testcase_common(TC, Config) ->
end_per_testcase(fate_environment, _Config) ->
meck:unload(aefa_chain_api),
ok;
end_per_testcase(TC, Cfg) when TC == sophia_aens_resolve;
TC == sophia_signatures_aens;
TC == sophia_aens_transactions ->
meck:unload(aec_governance),
ok;
end_per_testcase(_TC,_Config) ->
ok.

Expand Down
34 changes: 31 additions & 3 deletions apps/aecore/src/aec_governance.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
name_preclaim_expiration/0,
name_claim_locked_fee/0,
name_claim_fee/2,
name_claim_bid_timeout/2,
name_claim_bid_increment/0,
name_claim_max_expiration/0,
name_protection_period/0,
name_claim_preclaim_delta/0,
Expand Down Expand Up @@ -63,6 +65,7 @@
-define(BENEFICIARY_REWARD_DELAY, 180). %% in key blocks / generations
-define(MICRO_BLOCK_CYCLE, 3000). %% in msecs
-define(MULTIPLIER_14, 100000000000000).
-define(MULTIPLIER_DAY, 480).

-define(ACCEPTED_FUTURE_BLOCK_TIME_SHIFT, (?EXPECTED_BLOCK_MINE_RATE_MINUTES * 3 * 60 * 1000)). %% 9 min

Expand Down Expand Up @@ -251,14 +254,39 @@ name_claim_preclaim_delta() ->
%% not only length of the bytes
-spec name_claim_fee(binary(), non_neg_integer()) -> non_neg_integer().
name_claim_fee(Name, Protocol) when Protocol >= ?LIMA_PROTOCOL_VSN ->
name_claim_size_fee(name_claim_size(Name));
name_claim_fee(_Name, _Protocol) ->
0.

%% local helper function
name_claim_size(Name) ->
%% Name fee is computed over ascii version
{ok, AsciiName} = aens_utils:to_ascii(Name),
{ok, Domain} = aens_utils:name_domain(AsciiName),
%% No payment for registrars, Name should have been validated before
name_claim_size_fee(size(AsciiName) - size(Domain) - 1);
name_claim_fee(_Name, _Protocol) ->
size(AsciiName) - size(Domain) - 1.

%% Give possibility to have the actual name under consensus,
%% possible to define different bid times for different names.
%% No auction for names of 32 characters or longer
-spec name_claim_bid_timeout(binary(), non_neg_integer()) -> non_neg_integer().
name_claim_bid_timeout(Name, Protocol) when Protocol >= ?LIMA_PROTOCOL_VSN ->
NameSize = name_claim_size(Name),
BidTimeout =
if NameSize > 31 -> 0;
NameSize > 8 -> 1 * ?MULTIPLIER_DAY; %% 480 blocks
NameSize > 4 -> 31 * ?MULTIPLIER_DAY; %% 14880 blocks
true -> 62 * ?MULTIPLIER_DAY %% 29760 blocks
end,
%% allow overwrite by configuration for test
aeu_env:user_config_or_env([<<"mining">>, <<"name_claim_bid_timeout">>],
aecore, name_claim_bid_timeout, BidTimeout);
name_claim_bid_timeout(_Name, _Protocol) ->
0.

name_claim_bid_increment() ->
5. %% 5%

name_claim_size_fee(Size) when Size >= 31 -> 3 * ?MULTIPLIER_14;
name_claim_size_fee(30) -> 5 * ?MULTIPLIER_14;
name_claim_size_fee(29) -> 8 * ?MULTIPLIER_14;
Expand Down Expand Up @@ -298,7 +326,7 @@ name_registrars(_Protocol) ->
[<<"test">>].

non_test_registrars() ->
[<<"aet">>].
possible_name_registrars() -- [<<"test">>].

%% union of all name_registrars above disregarding the height
possible_name_registrars() ->
Expand Down
2 changes: 1 addition & 1 deletion apps/aecore/src/aec_trees.erl
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ gc_cache(Trees, TreesToGC) ->
perform_pre_transformations(Trees, Height) ->
Trees0 = aect_call_state_tree:prune(Height, Trees),
Trees1 = aeo_state_tree:prune(Height, Trees0),
Trees2 = set_ns(Trees1, aens_state_tree:prune(Height, ns(Trees1))),
Trees2 = aens_state_tree:prune(Height, Trees1),
case Height =:= aec_block_genesis:height() of
true -> Trees2; % genesis block
false ->
Expand Down
5 changes: 1 addition & 4 deletions apps/aefate/src/aefa_chain_api.erl
Original file line number Diff line number Diff line change
Expand Up @@ -637,10 +637,7 @@ aens_preclaim(Pubkey, Hash, #state{} = S) when ?IS_ONCHAIN(S) ->
aens_claim(Pubkey, NameBin, SaltInt, NameFee, #state{} = S) when ?IS_ONCHAIN(S) ->
PreclaimDelta = aec_governance:name_claim_preclaim_delta(),
DeltaTTL = aec_governance:name_claim_max_expiration(),
Instructions = [ aeprimop:lock_amount_op(Pubkey, NameFee)
, aeprimop:name_claim_op(Pubkey, NameBin, SaltInt, NameFee,
DeltaTTL, PreclaimDelta)
],
Instructions = [ aeprimop:name_claim_op(Pubkey, NameBin, SaltInt, NameFee, PreclaimDelta) ],
eval_primops(Instructions, S, size_gas([NameBin])).

aens_transfer(FromPubkey, HashBin, ToPubkey, #state{} = S) when ?IS_ONCHAIN(S) ->
Expand Down
4 changes: 3 additions & 1 deletion apps/aehttp/test/aehttp_integration_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,9 @@ init_per_suite(Config) ->
#{<<"persist">> => true,
<<"hard_forks">> => Forks},
<<"mining">> =>
#{<<"micro_block_cycle">> => 1}},
#{<<"micro_block_cycle">> => 1,
<<"name_claim_bid_timeout">> => 0 %% NO name auctions
}},
{ok, StartedApps} = application:ensure_all_started(gproc),
Config1 = aecore_suite_utils:init_per_suite([?NODE], DefCfg, [{symlink_name, "latest.http_endpoints"}, {test_module, ?MODULE}] ++ Config),
[ {nodes, [aecore_suite_utils:node_tuple(?NODE)]}
Expand Down
4 changes: 3 additions & 1 deletion apps/aehttp/test/aehttp_sc_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ init_per_suite(Config) ->
#{<<"persist">> => true,
<<"hard_forks">> => Forks},
<<"mining">> =>
#{<<"micro_block_cycle">> => 1}},
#{<<"micro_block_cycle">> => 1,
%% disable name claim auction
<<"name_claim_bid_timeout">> => 0}},
{ok, StartedApps} = application:ensure_all_started(gproc),
Config1 = aecore_suite_utils:init_per_suite([?NODE], DefCfg, [{symlink_name, "latest.http_sc"}, {test_module, ?MODULE}] ++ Config),
start_node([ {nodes, [aecore_suite_utils:node_tuple(?NODE)]}
Expand Down
142 changes: 142 additions & 0 deletions apps/aens/src/aens_auctions.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
%%%=============================================================================
%%% @copyright (C) 2018, Aeternity Anstalt
%%% @doc
%%% ADT for names auction objects
%%% Idea: whenever a new claim comes in within auction period,
%%% then - if namefee too low, just charge for transaction, but not the fee
%%% - if namefee exceeds previous bid with right margin
%%% then we end up here and create a new auction object,
%%% the previous highest bidder should get its namefee unlocked and
%%% the new one get it locked.
%%% Invariant: we can only start claiming names when name is not claimed
%%% hence, we cannot start an auction before the name is available
%%% We delete all auction objects after the auction, therefore no
%%% risk ??? that previous name holder get returned name fee when new auction starts.
%%% @end
%%%=============================================================================

-module(aens_auctions).

%% API
-export([new/5,
serialize/1,
deserialize/2,
deserialize_from_fields/3,
serialization_type/0,
serialization_template/1
]).

%% Getters
-export([hash/1,
bidder_pubkey/1,
ttl/1,
name_fee/1,
started/1]).

-behavior(aens_cache).
%%%===================================================================
%%% Types
%%%===================================================================
-record(auction,
{id :: aeser_id:id(),
started :: aec_blocks:height(),
bidder_id :: aeser_id:id(), %% should there be a preclaim for second bidder?? No.
%% Preclaim owner can start auction by a claim, nobody else
%% Having a second preclaim for same name won't restart auction
bid :: non_neg_integer(), %% the name_fee provided
ttl :: aec_blocks:height()
}).

-opaque auction() :: #auction{}.

-type id() :: aeser_id:id().
-type pubkey() :: aec_keys:pubkey().
-type serialized() :: binary().

-export_type([id/0,
auction/0,
serialized/0]).

-define(AUCTION_TYPE, name_auction).
-define(AUCTION_VSN, 1).

%%%===================================================================
%%% API
%%%===================================================================

-spec new(aens_hash:auction_hash(), aec_keys:pubkey(), non_neg_integer(),
non_neg_integer(), aec_blocks:height()) -> auction().
new(AuctionHash, Bidder, NameFee, DeltaTTL, BlockHeight) ->
NameHash = aens_hash:from_auction_hash(AuctionHash),
#auction{id = aeser_id:create(name, NameHash),
bidder_id = aeser_id:create(account, Bidder),
started = BlockHeight,
bid = NameFee,
ttl = BlockHeight + DeltaTTL}.

-spec serialize(auction()) -> serialized().
serialize(#auction{bidder_id = BidderId,
bid = NameFee,
started = Started,
ttl = TTL}) ->
aeser_chain_objects:serialize(
?AUCTION_TYPE,
?AUCTION_VSN,
serialization_template(?AUCTION_VSN),
[ {bidder_id, BidderId}
, {bid, NameFee}
, {started, Started}
, {ttl, TTL}]).

-spec deserialize(aens_hash:auction_hash(), binary()) -> auction().
deserialize(AuctionHash, Bin) ->
NameHash = aens_hash:from_auction_hash(AuctionHash),
Fields = aeser_chain_objects:deserialize(
?AUCTION_TYPE,
?AUCTION_VSN,
serialization_template(?AUCTION_VSN),
Bin),
deserialize_from_fields(?AUCTION_VSN, NameHash, Fields).

deserialize_from_fields(?AUCTION_VSN, NameHash,
[ {bidder_id, BidderId}
, {bid, NameFee}
, {started, Started}
, {ttl, TTL} ]) ->
#auction{id = aeser_id:create(name, NameHash),
bidder_id = BidderId,
bid = NameFee,
started = Started,
ttl = TTL}.

serialization_template(?AUCTION_VSN) ->
[ {bidder_id, id}
, {bid, int}
, {started, int}
, {ttl, int}].

serialization_type() -> ?AUCTION_TYPE.
%%%===================================================================
%%% Getters
%%%===================================================================

-spec hash(auction()) -> aens_hash:auction_hash().
hash(#auction{id = Id}) ->
NameHash = aeser_id:specialize(Id, name),
aens_hash:to_auction_hash(NameHash).

-spec bidder_pubkey(auction()) -> pubkey().
bidder_pubkey(#auction{bidder_id = BidderId}) ->
aeser_id:specialize(BidderId, account).

-spec name_fee(auction()) -> non_neg_integer().
name_fee(#auction{bid = NameFee}) ->
NameFee.

-spec ttl(auction()) -> aec_blocks:height().
ttl(#auction{ttl = TTL}) ->
TTL.

-spec started(auction()) -> aec_blocks:height().
started(#auction{started = Started}) ->
Started.
18 changes: 16 additions & 2 deletions apps/aens/src/aens_hash.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,26 @@

%% API
-export([name_hash/1,
commitment_hash/2]).
commitment_hash/2,
to_auction_hash/1,
from_auction_hash/1]).

%%%===================================================================
%%% Types
%%%===================================================================

-type name_hash() :: binary().
-type commitment_hash() :: binary().
-type auction_hash() :: binary().

-export_type([name_hash/0,
commitment_hash/0]).
commitment_hash/0,
auction_hash/0]).

-define(NAME_HASH_BYTES, 32).
-define(COMMITMENT_HASH_BYTES, 32).
-define(AUCTION_HASH_BYTES, 33).


%%%===================================================================
%%% API
Expand Down Expand Up @@ -62,6 +68,14 @@ name_hash(NameAscii) ->
pre_lima_name_hash(NameAscii)
end.

-spec to_auction_hash(name_hash()) -> auction_hash().
to_auction_hash(NameHash) ->
<<NameHash/binary, 0:8>>.

-spec from_auction_hash(auction_hash()) -> name_hash().
from_auction_hash(AuctionHash) ->
<<NameHash:?NAME_HASH_BYTES/unit:8, 0:8>> = AuctionHash,
<<NameHash:?NAME_HASH_BYTES/unit:8>>.

-spec pre_lima_commitment_hash(binary(), integer()) -> commitment_hash().
pre_lima_commitment_hash(NameAscii, Salt) ->
Expand Down

0 comments on commit 6880ce5

Please sign in to comment.