Compare commits

..

3 Commits

Author SHA1 Message Date
skkw 81d0daa9d5 add support for encoding/decoding of subname id 2019-08-27 10:39:36 +02:00
skkw 7994428e56 changed encoding of subnames to base64 2019-08-26 12:01:42 +02:00
skkw 91b83cfb89 add subname id 2019-08-26 12:01:42 +02:00
10 changed files with 27 additions and 189 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ version: 2.1
executors: executors:
aebuilder: aebuilder:
docker: docker:
- image: aeternity/builder:bionic-otp23 - image: aeternity/builder
user: builder user: builder
working_directory: ~/src working_directory: ~/src
+1 -1
View File
@@ -1,4 +1,4 @@
{erl_opts, [debug_info]}. {erl_opts, [debug_info]}.
{deps, [ {base58, {git, "https://github.com/aeternity/erl-base58.git", {ref, "60a3356"}}} {deps, [ {base58, {git, "https://github.com/aeternity/erl-base58.git", {ref, "60a3356"}}}
, {enacl, {git, "https://github.com/aeternity/enacl.git", {ref, "67fceef"}}} , {enacl, {git, "https://github.com/aeternity/enacl.git", {ref, "26180f4"}}}
]}. ]}.
-8
View File
@@ -1,8 +0,0 @@
[{<<"base58">>,
{git,"https://github.com/aeternity/erl-base58.git",
{ref,"60a335668a60328a29f9731b67c4a0e9e3d50ab6"}},
0},
{<<"enacl">>,
{git,"https://github.com/aeternity/enacl.git",
{ref,"67fceef42c0d055570f2e67b571f8d1f8de2f204"}},
0}].
+5 -5
View File
@@ -30,9 +30,9 @@
| oracle_query_id | oracle_query_id
| oracle_response | oracle_response
| account_pubkey | account_pubkey
| account_seckey
| signature | signature
| name | name
| subname
| commitment | commitment
| peer_pubkey | peer_pubkey
| state | state
@@ -192,11 +192,11 @@ type2enc(oracle_query) -> ?BASE64;
type2enc(oracle_query_id) -> ?BASE58; type2enc(oracle_query_id) -> ?BASE58;
type2enc(oracle_response) -> ?BASE64; type2enc(oracle_response) -> ?BASE64;
type2enc(account_pubkey) -> ?BASE58; type2enc(account_pubkey) -> ?BASE58;
type2enc(account_seckey) -> ?BASE58;
type2enc(signature) -> ?BASE58; type2enc(signature) -> ?BASE58;
type2enc(commitment) -> ?BASE58; type2enc(commitment) -> ?BASE58;
type2enc(peer_pubkey) -> ?BASE58; type2enc(peer_pubkey) -> ?BASE58;
type2enc(name) -> ?BASE58; type2enc(name) -> ?BASE58;
type2enc(subname) -> ?BASE64;
type2enc(state) -> ?BASE64; type2enc(state) -> ?BASE64;
type2enc(poi) -> ?BASE64; type2enc(poi) -> ?BASE64;
type2enc(state_trees) -> ?BASE64; type2enc(state_trees) -> ?BASE64;
@@ -221,11 +221,11 @@ type2pfx(oracle_query) -> <<"ov">>;
type2pfx(oracle_query_id) -> <<"oq">>; type2pfx(oracle_query_id) -> <<"oq">>;
type2pfx(oracle_response) -> <<"or">>; type2pfx(oracle_response) -> <<"or">>;
type2pfx(account_pubkey) -> <<"ak">>; type2pfx(account_pubkey) -> <<"ak">>;
type2pfx(account_seckey) -> <<"sk">>;
type2pfx(signature) -> <<"sg">>; type2pfx(signature) -> <<"sg">>;
type2pfx(commitment) -> <<"cm">>; type2pfx(commitment) -> <<"cm">>;
type2pfx(peer_pubkey) -> <<"pp">>; type2pfx(peer_pubkey) -> <<"pp">>;
type2pfx(name) -> <<"nm">>; type2pfx(name) -> <<"nm">>;
type2pfx(subname) -> <<"sn">>;
type2pfx(state) -> <<"st">>; type2pfx(state) -> <<"st">>;
type2pfx(poi) -> <<"pi">>; type2pfx(poi) -> <<"pi">>;
type2pfx(state_trees) -> <<"ss">>; type2pfx(state_trees) -> <<"ss">>;
@@ -249,11 +249,11 @@ pfx2type(<<"ov">>) -> oracle_query;
pfx2type(<<"oq">>) -> oracle_query_id; pfx2type(<<"oq">>) -> oracle_query_id;
pfx2type(<<"or">>) -> oracle_response; pfx2type(<<"or">>) -> oracle_response;
pfx2type(<<"ak">>) -> account_pubkey; pfx2type(<<"ak">>) -> account_pubkey;
pfx2type(<<"sk">>) -> account_seckey;
pfx2type(<<"sg">>) -> signature; pfx2type(<<"sg">>) -> signature;
pfx2type(<<"cm">>) -> commitment; pfx2type(<<"cm">>) -> commitment;
pfx2type(<<"pp">>) -> peer_pubkey; pfx2type(<<"pp">>) -> peer_pubkey;
pfx2type(<<"nm">>) -> name; pfx2type(<<"nm">>) -> name;
pfx2type(<<"sn">>) -> subname;
pfx2type(<<"st">>) -> state; pfx2type(<<"st">>) -> state;
pfx2type(<<"pi">>) -> poi; pfx2type(<<"pi">>) -> poi;
pfx2type(<<"ss">>) -> state_trees; pfx2type(<<"ss">>) -> state_trees;
@@ -279,9 +279,9 @@ byte_size_for_type(oracle_query) -> not_applicable;
byte_size_for_type(oracle_query_id) -> 32; byte_size_for_type(oracle_query_id) -> 32;
byte_size_for_type(oracle_response) -> not_applicable; byte_size_for_type(oracle_response) -> not_applicable;
byte_size_for_type(account_pubkey) -> 32; byte_size_for_type(account_pubkey) -> 32;
byte_size_for_type(account_seckey) -> 32;
byte_size_for_type(signature) -> 64; byte_size_for_type(signature) -> 64;
byte_size_for_type(name) -> not_applicable; byte_size_for_type(name) -> not_applicable;
byte_size_for_type(subname) -> not_applicable;
byte_size_for_type(commitment) -> 32; byte_size_for_type(commitment) -> 32;
byte_size_for_type(peer_pubkey) -> 32; byte_size_for_type(peer_pubkey) -> 32;
byte_size_for_type(state) -> 32; byte_size_for_type(state) -> 32;
+4 -8
View File
@@ -52,13 +52,13 @@ tag(name_preclaim_tx) -> 33;
tag(name_update_tx) -> 34; tag(name_update_tx) -> 34;
tag(name_revoke_tx) -> 35; tag(name_revoke_tx) -> 35;
tag(name_transfer_tx) -> 36; tag(name_transfer_tx) -> 36;
tag(name_auction) -> 37; tag(subname) -> 38;
tag(subname_tx) -> 39;
tag(contract) -> 40; tag(contract) -> 40;
tag(contract_call) -> 41; tag(contract_call) -> 41;
tag(contract_create_tx) -> 42; tag(contract_create_tx) -> 42;
tag(contract_call_tx) -> 43; tag(contract_call_tx) -> 43;
tag(channel_create_tx) -> 50; tag(channel_create_tx) -> 50;
tag(channel_set_delegates_tx) -> 501;
tag(channel_deposit_tx) -> 51; tag(channel_deposit_tx) -> 51;
tag(channel_withdraw_tx) -> 52; tag(channel_withdraw_tx) -> 52;
tag(channel_force_progress_tx) -> 521; tag(channel_force_progress_tx) -> 521;
@@ -90,8 +90,6 @@ tag(accounts_mtree) -> 626;
tag(compiler_sophia) -> 70; tag(compiler_sophia) -> 70;
tag(ga_attach_tx) -> 80; tag(ga_attach_tx) -> 80;
tag(ga_meta_tx) -> 81; tag(ga_meta_tx) -> 81;
tag(paying_for_tx) -> 82;
tag(ga_meta_tx_auth_data) -> 810;
tag(key_block) -> 100; tag(key_block) -> 100;
tag(micro_block) -> 101; tag(micro_block) -> 101;
tag(light_micro_block) -> 102; tag(light_micro_block) -> 102;
@@ -113,13 +111,13 @@ rev_tag(33) -> name_preclaim_tx;
rev_tag(34) -> name_update_tx; rev_tag(34) -> name_update_tx;
rev_tag(35) -> name_revoke_tx; rev_tag(35) -> name_revoke_tx;
rev_tag(36) -> name_transfer_tx; rev_tag(36) -> name_transfer_tx;
rev_tag(37) -> name_auction; rev_tag(38) -> subname;
rev_tag(39) -> subname_tx;
rev_tag(40) -> contract; rev_tag(40) -> contract;
rev_tag(41) -> contract_call; rev_tag(41) -> contract_call;
rev_tag(42) -> contract_create_tx; rev_tag(42) -> contract_create_tx;
rev_tag(43) -> contract_call_tx; rev_tag(43) -> contract_call_tx;
rev_tag(50) -> channel_create_tx; rev_tag(50) -> channel_create_tx;
rev_tag(501) -> channel_set_delegates_tx;
rev_tag(51) -> channel_deposit_tx; rev_tag(51) -> channel_deposit_tx;
rev_tag(52) -> channel_withdraw_tx; rev_tag(52) -> channel_withdraw_tx;
rev_tag(521) -> channel_force_progress_tx; rev_tag(521) -> channel_force_progress_tx;
@@ -151,8 +149,6 @@ rev_tag(626) -> accounts_mtree;
rev_tag(70) -> compiler_sophia; rev_tag(70) -> compiler_sophia;
rev_tag(80) -> ga_attach_tx; rev_tag(80) -> ga_attach_tx;
rev_tag(81) -> ga_meta_tx; rev_tag(81) -> ga_meta_tx;
rev_tag(82) -> paying_for_tx;
rev_tag(810) -> ga_meta_tx_auth_data;
rev_tag(100) -> key_block; rev_tag(100) -> key_block;
rev_tag(101) -> micro_block; rev_tag(101) -> micro_block;
rev_tag(102) -> light_micro_block; rev_tag(102) -> light_micro_block;
+2 -1
View File
@@ -23,7 +23,8 @@ serialize(CodeMap = #{ byte_code := ByteCode
SourceHash = case CodeMap of SourceHash = case CodeMap of
#{ source_hash := SHash } -> SHash; #{ source_hash := SHash } -> SHash;
#{ contract_source := SrcStr } -> #{ contract_source := SrcStr } ->
enacl:generichash(32, list_to_binary(SrcStr)) {ok, SHash} = enacl:generichash(32, list_to_binary(SrcStr)),
SHash
end, end,
%% Compiler version %% Compiler version
-81
View File
@@ -1,81 +0,0 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2023, Aeternity Anstalt
%%% @doc
%%% Serialization of delegation signatures
%%% @end
%%%-------------------------------------------------------------------
-module(aeser_delegation).
-export([ aens_preclaim_sig/3
, aens_name_sig/4
, aens_sig/3
, oracle_sig/3
, oracle_response_sig/3
]).
%% Delegation signatures are prefixed with a unique tag, ensuring not to
%% collide with serialized transactions.
-define(DELEGATION_TAG, 16#1a01).
-define(TYPE_AENS, 1).
-define(TYPE_AENS_NAME, 2).
-define(TYPE_AENS_PRECLAIM, 3).
-define(TYPE_ORACLE, 4).
-define(TYPE_ORACLE_RESPONSE, 5).
-define(VSN, 1).
-type sig_data() :: binary().
-spec aens_preclaim_sig(binary(), aeser_id:id(), aeser_id:id()) -> sig_data().
aens_preclaim_sig(NetworkId, Account, Contract) ->
assert_id(account, Account),
assert_id(contract, Contract),
Template = [{account, id}, {contract, id}],
Fields = [{account, Account}, {contract, Contract}],
serialize(?TYPE_AENS_PRECLAIM, NetworkId, Template, Fields).
-spec aens_name_sig(binary(), aeser_id:id(), aeser_id:id(), aeser_id:id()) -> sig_data().
aens_name_sig(NetworkId, Account, Name, Contract) ->
assert_id(account, Account),
assert_id(name, Name),
assert_id(contract, Contract),
Template = [{account, id}, {name, id}, {contract, id}],
Fields = [{account, Account}, {name, Name}, {contract, Contract}],
serialize(?TYPE_AENS_NAME, NetworkId, Template, Fields).
-spec aens_sig(binary(), aeser_id:id(), aeser_id:id()) -> sig_data().
aens_sig(NetworkId, Account, Contract) ->
assert_id(account, Account),
assert_id(contract, Contract),
Template = [{account, id}, {contract, id}],
Fields = [{account, Account}, {contract, Contract}],
serialize(?TYPE_AENS, NetworkId, Template, Fields).
-spec oracle_sig(binary(), aeser_id:id(), aeser_id:id()) -> sig_data().
oracle_sig(NetworkId, Account, Contract) ->
assert_id(account, Account),
assert_id(contract, Contract),
Template = [{account, id}, {contract, id}],
Fields = [{account, Account}, {contract, Contract}],
serialize(?TYPE_ORACLE, NetworkId, Template, Fields).
-spec oracle_response_sig(binary(), aeser_id:id(), aeser_id:id()) -> sig_data().
oracle_response_sig(NetworkId, QueryId, Contract) ->
assert_id(oracle, QueryId),
assert_id(contract, Contract),
Template = [{query, id}, {contract, id}],
Fields = [{query, QueryId}, {contract, Contract}],
serialize(?TYPE_ORACLE_RESPONSE, NetworkId, Template, Fields).
%% ------------------------------------------------------------------------
%% -- Internal functions
%% ------------------------------------------------------------------------
serialize(Type, NetworkId, Template, Fields) ->
Data = aeserialization:serialize(Type, ?VSN, Template, Fields),
<<?DELEGATION_TAG:16, NetworkId/binary, Data/binary>>.
assert_id(Type, AeserId) ->
Type = aeser_id:specialize_type(AeserId).
+14 -2
View File
@@ -24,7 +24,7 @@
, val , val
}). }).
-type tag() :: 'account' | 'oracle' | 'name' -type tag() :: 'account' | 'oracle' | 'name' | 'subname'
| 'commitment' | 'contract' | 'channel'. | 'commitment' | 'contract' | 'channel'.
-type val() :: <<_:256>>. -type val() :: <<_:256>>.
-opaque(id() :: #id{}). -opaque(id() :: #id{}).
@@ -37,10 +37,12 @@
-define(PUB_SIZE, 32). -define(PUB_SIZE, 32).
-define(TAG_SIZE, 1). -define(TAG_SIZE, 1).
-define(SERIALIZED_SIZE, 33). %% ?TAG_SIZE + ?PUB_SIZE -define(SERIALIZED_SIZE, 33). %% ?TAG_SIZE + ?PUB_SIZE
-define(SUBNAME_SERIALIZED_SIZE, 65). %% ?TAG_SIZE + ?PUB_SIZE + ?PUB_SIZE
-define(IS_TAG(___TAG___), ___TAG___ =:= account; -define(IS_TAG(___TAG___), ___TAG___ =:= account;
___TAG___ =:= oracle; ___TAG___ =:= oracle;
___TAG___ =:= name; ___TAG___ =:= name;
___TAG___ =:= subname;
___TAG___ =:= commitment; ___TAG___ =:= commitment;
___TAG___ =:= contract; ___TAG___ =:= contract;
___TAG___ =:= channel ___TAG___ =:= channel
@@ -82,24 +84,33 @@ is_id(_) -> false.
-spec encode(id()) -> binary(). -spec encode(id()) -> binary().
encode(#id{tag = Tag, val = Val}) -> encode(#id{tag = Tag, val = Val}) ->
Res = <<(encode_tag(Tag)):?TAG_SIZE/unit:8, Val/binary>>, Res = <<(encode_tag(Tag)):?TAG_SIZE/unit:8, Val/binary>>,
true = ?SERIALIZED_SIZE =:= byte_size(Res), true = serialized_size(Tag) =:= byte_size(Res),
Res. Res.
-spec decode(binary()) -> id(). -spec decode(binary()) -> id().
decode(<<Tag:?TAG_SIZE/unit:8, Val:?PUB_SIZE/binary>>) -> decode(<<Tag:?TAG_SIZE/unit:8, Val:?PUB_SIZE/binary>>) ->
#id{ tag = decode_tag(Tag) #id{ tag = decode_tag(Tag)
, val = Val};
decode(<<SubnameTag:?TAG_SIZE/unit:8, Val:(?PUB_SIZE+?PUB_SIZE)/binary>>) ->
#id{ tag = subname = decode_tag(SubnameTag)
, val = Val}. , val = Val}.
%%%=================================================================== %%%===================================================================
%%% Internal functions %%% Internal functions
%%%=================================================================== %%%===================================================================
serialized_size(subname) -> ?SUBNAME_SERIALIZED_SIZE;
serialized_size(_) -> ?SERIALIZED_SIZE.
encode_tag(account) -> 1; encode_tag(account) -> 1;
encode_tag(name) -> 2; encode_tag(name) -> 2;
encode_tag(commitment) -> 3; encode_tag(commitment) -> 3;
encode_tag(oracle) -> 4; encode_tag(oracle) -> 4;
encode_tag(contract) -> 5; encode_tag(contract) -> 5;
encode_tag(channel) -> 6; encode_tag(channel) -> 6;
encode_tag(subname) -> 7;
encode_tag(Other) -> error({illegal_id_tag_name, Other}). encode_tag(Other) -> error({illegal_id_tag_name, Other}).
decode_tag(1) -> account; decode_tag(1) -> account;
@@ -108,4 +119,5 @@ decode_tag(3) -> commitment;
decode_tag(4) -> oracle; decode_tag(4) -> oracle;
decode_tag(5) -> contract; decode_tag(5) -> contract;
decode_tag(6) -> channel; decode_tag(6) -> channel;
decode_tag(7) -> subname;
decode_tag(X) -> error({illegal_id_tag, X}). decode_tag(X) -> error({illegal_id_tag, X}).
-15
View File
@@ -28,14 +28,12 @@
| 'binary' | 'binary'
| 'id' %% As defined in aec_id.erl | 'id' %% As defined in aec_id.erl
| [type()] %% Length one in the type. This means a list of any length. | [type()] %% Length one in the type. This means a list of any length.
| #{items := [{field_name(), type()}]} %% Record with named fields represented as a map. Encoded as a list in the given order.
| tuple(). %% Any arity, containing type(). This means a static size array. | tuple(). %% Any arity, containing type(). This means a static size array.
-type encodable_term() :: non_neg_integer() -type encodable_term() :: non_neg_integer()
| binary() | binary()
| boolean() | boolean()
| [encodable_term()] %% Of any length | [encodable_term()] %% Of any length
| #{atom() => encodable_term()}
| tuple() %% Any arity, containing encodable_term(). | tuple() %% Any arity, containing encodable_term().
| aeser_id:id(). | aeser_id:id().
@@ -103,12 +101,6 @@ decode_fields(Template, Values) ->
encode_field([Type], L) when is_list(L) -> encode_field([Type], L) when is_list(L) ->
[encode_field(Type, X) || X <- L]; [encode_field(Type, X) || X <- L];
encode_field(#{items := Items}, Map) ->
lists:map(
fun({K, Type}) ->
V = maps:get(K, Map),
encode_field(Type, V)
end, Items);
encode_field(Type, T) when tuple_size(Type) =:= tuple_size(T) -> encode_field(Type, T) when tuple_size(Type) =:= tuple_size(T) ->
Zipped = lists:zip(tuple_to_list(Type), tuple_to_list(T)), Zipped = lists:zip(tuple_to_list(Type), tuple_to_list(T)),
[encode_field(X, Y) || {X, Y} <- Zipped]; [encode_field(X, Y) || {X, Y} <- Zipped];
@@ -125,13 +117,6 @@ encode_field(Type, Val) -> error({illegal, Type, Val}).
decode_field([Type], List) when is_list(List) -> decode_field([Type], List) when is_list(List) ->
[decode_field(Type, X) || X <- List]; [decode_field(Type, X) || X <- List];
decode_field(#{items := Items}, List) when length(List) =:= length(Items) ->
Zipped = lists:zip(Items, List),
lists:foldl(
fun({{K, Type}, V}, Map) ->
maps:is_key(K, Map) andalso error(badarg, duplicate_field),
Map#{ K => decode_field(Type, V) }
end, #{}, Zipped);
decode_field(Type, List) when length(List) =:= tuple_size(Type) -> decode_field(Type, List) when length(List) =:= tuple_size(Type) ->
Zipped = lists:zip(tuple_to_list(Type), List), Zipped = lists:zip(tuple_to_list(Type), List),
list_to_tuple([decode_field(X, Y) || {X, Y} <- Zipped]); list_to_tuple([decode_field(X, Y) || {X, Y} <- Zipped]);
-67
View File
@@ -1,67 +0,0 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2023, Aeternity Anstalt
%%%-------------------------------------------------------------------
-module(aeser_delegation_tests).
-include_lib("eunit/include/eunit.hrl").
-define(TEST_MODULE, aeser_delegation).
-define(ACCOUNT, aeser_id:create(account, <<1:256>>)).
-define(CONTRACT, aeser_id:create(contract, <<2:256>>)).
-define(NAME, aeser_id:create(name, <<3:256>>)).
-define(ORACLE, aeser_id:create(oracle, <<3:256>>)).
-define(NETWORK_ID, <<"my_fancy_network"/utf8>>).
encode_correct_test_() ->
[{"Encode preclaim sig",
fun() ->
aeser_delegation:aens_preclaim_sig(?NETWORK_ID, ?ACCOUNT, ?CONTRACT)
end},
{"Encode name sig",
fun() ->
aeser_delegation:aens_name_sig(?NETWORK_ID, ?ACCOUNT, ?NAME, ?CONTRACT)
end},
{"Encode aens wildcard sig",
fun() ->
aeser_delegation:aens_sig(?NETWORK_ID, ?ACCOUNT, ?CONTRACT)
end},
{"Encode oracle sig",
fun() ->
aeser_delegation:oracle_sig(?NETWORK_ID, ?ACCOUNT, ?CONTRACT)
end},
{"Encode oracle response sig",
fun() ->
aeser_delegation:oracle_response_sig(?NETWORK_ID, ?ORACLE, ?CONTRACT)
end}
].
encode_fail_test_() ->
[{"Bad encoding preclaim sig",
fun() ->
?assertError(_, aeser_delegation:aens_preclaim_sig(?NETWORK_ID, <<42:256>>, ?CONTRACT)),
?assertError(_, aeser_delegation:aens_preclaim_sig(?NETWORK_ID, ?CONTRACT, ?ACCOUNT))
end},
{"Bad encoding name sig",
fun() ->
?assertError(_, aeser_delegation:aens_name_sig(?NETWORK_ID, ?ACCOUNT, <<42:256>>, ?CONTRACT)),
?assertError(_, aeser_delegation:aens_name_sig(?NETWORK_ID, ?NAME, ?ACCOUNT, ?CONTRACT))
end},
{"Bad encoding aens wildcard sig",
fun() ->
?assertError(_, aeser_delegation:aens_sig(?NETWORK_ID, ?ACCOUNT, <<42:256>>)),
?assertError(_, aeser_delegation:aens_sig(?NETWORK_ID, ?CONTRACT, ?CONTRACT))
end},
{"Bad encoding oracle sig",
fun() ->
?assertError(_, aeser_delegation:oracle_sig(?NETWORK_ID, <<42:256>>, ?CONTRACT)),
?assertError(_, aeser_delegation:oracle_sig(?NETWORK_ID, ?ACCOUNT, ?ACCOUNT))
end},
{"Bad encoding oracle response sig",
fun() ->
?assertError(_, aeser_delegation:oracle_response_sig(?NETWORK_ID, <<42:256>>, ?CONTRACT)),
?assertError(_, aeser_delegation:oracle_response_sig(?NETWORK_ID, ?ORACLE, ?ORACLE))
end}
].