From c63ac888dd71c305cbc6d4f70953a176bf1f78f7 Mon Sep 17 00:00:00 2001 From: Tobias Lindahl Date: Wed, 26 Jun 2019 13:19:44 +0200 Subject: [PATCH] Pt 166233700 fate nameservice (#60) * Introduce AENS instructions in FATE * Remove name object and fixup some documentation --- README.md | 10 ++++------ include/aeb_fate_data.hrl | 4 ---- quickcheck/aefate_eqc.erl | 3 +-- quickcheck/aefate_type_eqc.erl | 1 - src/aeb_fate_asm.erl | 17 ++++++----------- src/aeb_fate_asm_scan.template | 1 - src/aeb_fate_data.erl | 12 ++---------- src/aeb_fate_encoding.erl | 8 +------- src/aeb_fate_generate_ops.erl | 12 ++++++------ test/aeb_fate_asm_test.erl | 1 + test/aeb_serialize_test.erl | 1 - test/asm_code/immediates.fate | 3 --- test/asm_code/names.fate | 23 +++++++++++++++++++++++ 13 files changed, 44 insertions(+), 52 deletions(-) create mode 100644 test/asm_code/names.fate diff --git a/README.md b/README.md index 3ec4343..c8cce21 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ or start with stack followed by an integer `stack1` `a` -Immediate values can be of 11 types: +Immediate values can be of 10 types: 1. Integers as decimals: {Digits} or -{Digits} `42` @@ -70,8 +70,8 @@ Immediate values can be of 11 types: 2c. Oracle address: @ok_{base58char}+ `@ok_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` -2d. Name address: @nm_{base58char}+ - `@nm_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` +2d. Oracle query: @oq_{base58char}+ + `@oq_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` 2e. Channel address: @ch_{base58char}+ `@ch_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` @@ -104,11 +104,9 @@ Immediate values can be of 11 types: 9. Variants: (| [Arities] | Tag | ( Elements ) |) `(| [1,3,5,2] | 3 | ( "foo", 12) |)` -10. Hashes: #{base64char}+ +10. Bytes: #{base64char}+ `#AQIDCioLFQ==` -11. Signatures: $sg_{base58char}+ - Where diff --git a/include/aeb_fate_data.hrl b/include/aeb_fate_data.hrl index 958eae9..3160b4d 100644 --- a/include/aeb_fate_data.hrl +++ b/include/aeb_fate_data.hrl @@ -11,7 +11,6 @@ -define(FATE_CONTRACT_T, {contract, <<_:256>>}). -define(FATE_ORACLE_T, {oracle, <<_:256>>}). -define(FATE_ORACLE_Q_T, {oracle_query, <<_:256>>}). --define(FATE_NAME_T, {name, <<_:256>>}). -define(FATE_CHANNEL_T, {channel, <<_:256>>}). -define(FATE_VARIANT_T, {variant, [byte()], ?FATE_BYTE_T, tuple()}). -define(FATE_VOID_T, void). @@ -29,7 +28,6 @@ -define(IS_FATE_CONTRACT(X), (is_tuple(X) andalso (contract == element(1, X) andalso is_binary(element(2, X))))). -define(IS_FATE_ORACLE(X), (is_tuple(X) andalso (oracle == element(1, X) andalso is_binary(element(2, X))))). -define(IS_FATE_ORACLE_Q(X), (is_tuple(X) andalso (oracle_query == element(1, X) andalso is_binary(element(2, X))))). --define(IS_FATE_NAME(X), (is_tuple(X) andalso (name == element(1, X) andalso is_binary(element(2, X))))). -define(IS_FATE_CHANNEL(X), (is_tuple(X) andalso (channel == element(1, X) andalso is_binary(element(2, X))))). -define(IS_FATE_BITS(X), (is_tuple(X) andalso (bits == element(1, X) andalso is_integer(element(2, X))))). -define(IS_FATE_VARIANT(X), (is_tuple(X) @@ -49,7 +47,6 @@ -define(FATE_CONTRACT(X), {contract, X}). -define(FATE_ORACLE(X), {oracle, X}). -define(FATE_ORACLE_Q(X), {oracle_query, X}). --define(FATE_NAME(X), {name, X}). -define(FATE_CHANNEL(X), {channel, X}). -define(FATE_BITS(B), {bits, B}). -define(FATE_TYPEREP(T), {typerep, T}). @@ -63,7 +60,6 @@ -define(FATE_BYTES_VALUE(X), (element(2, X))). -define(FATE_CONTRACT_VALUE(X), (element(2, X))). -define(FATE_ORACLE_VALUE(X), (element(2, X))). --define(FATE_NAME_VALUE(X), (element(2, X))). -define(FATE_CHANNEL_VALUE(X), (element(2, X))). -define(FATE_BITS_VALUE(X), (element(2, X))). -define(FATE_MAP_VALUE(X), (X)). diff --git a/quickcheck/aefate_eqc.erl b/quickcheck/aefate_eqc.erl index 4a06401..6b6db82 100644 --- a/quickcheck/aefate_eqc.erl +++ b/quickcheck/aefate_eqc.erl @@ -99,7 +99,7 @@ fate_data(0, _Options) -> frequency( [{5, oneof([fate_integer(), fate_boolean(), fate_nil(), fate_unit()])}, {1, oneof([fate_string(), fate_address(), fate_bytes(), fate_contract(), - fate_oracle(), fate_oracle_q(), fate_name(), fate_bits(), fate_channel()])}])); + fate_oracle(), fate_oracle_q(), fate_bits(), fate_channel()])}])); fate_data(Size, Options) -> ?LAZY( oneof([fate_data(0, Options), @@ -124,7 +124,6 @@ fate_bytes() -> ?LET(X, non_empty(binary()), return(aeb_fate_data:make_byte fate_contract() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_contract(X))). fate_oracle() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_oracle(X))). fate_oracle_q() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_oracle_query(X))). -fate_name() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_name(X))). fate_channel() -> ?LET(X, binary(256 div 8), return(aeb_fate_data:make_channel(X))). fate_values(Size, N, Options) -> diff --git a/quickcheck/aefate_type_eqc.erl b/quickcheck/aefate_type_eqc.erl index d81f6d2..e55382a 100644 --- a/quickcheck/aefate_type_eqc.erl +++ b/quickcheck/aefate_type_eqc.erl @@ -38,7 +38,6 @@ fate_type(0) -> {bytes, nat()}, contract, oracle, - name, channel, bits, string]); diff --git a/src/aeb_fate_asm.erl b/src/aeb_fate_asm.erl index e2ebca3..9803909 100644 --- a/src/aeb_fate_asm.erl +++ b/src/aeb_fate_asm.erl @@ -33,7 +33,7 @@ %%% References to the top of the stack is the letter a (for accumulator) %%% a %%% -%%% Immediate values can be of 11 types: +%%% Immediate values can be of 10 types: %%% 1a. Integers as decimals: {Digits} or -{Digits} %%% 42 %%% -2374683271468723648732648736498712634876147 @@ -42,7 +42,7 @@ %%% 2a. account addresses, a base58c encoded string prefixed with @ak_ %%% 2b. contract address: @ct_{base58char}+ %%% 2c. oracle address: @ok_{base58char}+ -%%% 2d. name address: @nm_{base58char}+ +%%% 2d. oracle query id: @oq_{base58char}+ %%% 2e. channel address: @ch_{base58char}+ %%% 3. Boolean true or false %%% true @@ -65,9 +65,8 @@ %%% (1, "foo") %%% 9. Variants: (| [Arities] | Tag | ( Elements ) |) %%% (| [0,1,2] | 2 | ( "foo", 12) |) -%%% 10. Hashes: #{base64char}+ +%%% 10. Bytes: #{base64char}+ %%% #AQIDCioLFQ== -%%% 11. Signatures: $sg_{base58char}+ %%% %%% Where Digits: [0123456789] %%% Hexdigits: [0123456789abcdef] @@ -272,11 +271,6 @@ to_bytecode([{object,_line, {oracle_query, Value}}|Rest], to_bytecode(Rest, Address, Env, [{immediate, aeb_fate_data:make_oracle_query(Value)}|Code], Opts); -to_bytecode([{object,_line, {name, Value}}|Rest], - Address, Env, Code, Opts) -> - to_bytecode(Rest, Address, Env, - [{immediate, aeb_fate_data:make_name(Value)}|Code], - Opts); to_bytecode([{object,_line, {channel, Value}}|Rest], Address, Env, Code, Opts) -> to_bytecode(Rest, Address, Env, @@ -402,8 +396,6 @@ parse_value([{object,_line, {oracle, Address}} | Rest]) -> {aeb_fate_data:make_oracle(Address), Rest}; parse_value([{object,_line, {oracle_query, Address}} | Rest]) -> {aeb_fate_data:make_oracle_query(Address), Rest}; -parse_value([{object,_line, {name, Address}} | Rest]) -> - {aeb_fate_data:make_name(Address), Rest}; parse_value([{object,_line, {channel, Address}} | Rest]) -> {aeb_fate_data:make_channel(Address), Rest}; parse_value([{hash,_line, Hash} | Rest]) -> @@ -456,6 +448,9 @@ to_type([{'{', _}, {id, _, "map"}, {',', _} | Rest]) -> {KeyType, [{',', _}| Rest2]} = to_type(Rest), {ValueType, [{'}', _}| Rest3]} = to_type(Rest2), {{map, KeyType, ValueType}, Rest3}; +to_type([{'{', _}, {id, _, "bytes"}, {',', _}, {int, _, Size}, {'}', _} | Rest]) -> + %% TODO: Error handling + {{bytes, Size}, Rest}; to_type([{'{', _} , {id, _, "variant"} , {',', _} diff --git a/src/aeb_fate_asm_scan.template b/src/aeb_fate_asm_scan.template index 0fadbb2..8f7f463 100644 --- a/src/aeb_fate_asm_scan.template +++ b/src/aeb_fate_asm_scan.template @@ -117,7 +117,6 @@ parse_object([_|Chars]) -> {contract_pubkey, Bin} -> {contract, Bin}; {oracle_pubkey, Bin} -> {oracle, Bin}; {oracle_query_id, Bin} -> {oracle_query, Bin}; - {name, Bin} -> {name, Bin}; {channel, Bin} -> {channel, Bin}; {signature, Bin} -> {signature, Bin} end. diff --git a/src/aeb_fate_data.erl b/src/aeb_fate_data.erl index cb16f61..94a6343 100644 --- a/src/aeb_fate_data.erl +++ b/src/aeb_fate_data.erl @@ -16,7 +16,6 @@ -type fate_signature() :: ?FATE_BYTES_T(64). -type fate_contract() :: ?FATE_CONTRACT_T. -type fate_oracle() :: ?FATE_ORACLE_T. --type fate_name() :: ?FATE_NAME_T. -type fate_channel() :: ?FATE_CHANNEL_T. -type fate_variant() :: ?FATE_VARIANT_T. -type fate_tuple() :: ?FATE_TUPLE_T. @@ -32,7 +31,6 @@ | signature | contract | oracle - | name | channel | bits | string @@ -52,7 +50,6 @@ | fate_signature() | fate_contract() | fate_oracle() - | fate_name() | fate_channel() | fate_variant() | fate_map() @@ -71,7 +68,6 @@ , fate_signature/0 , fate_contract/0 , fate_oracle/0 - , fate_name/0 , fate_channel/0 , fate_variant/0 , fate_map/0 @@ -93,7 +89,6 @@ , make_contract/1 , make_oracle/1 , make_oracle_query/1 - , make_name/1 , make_channel/1 , make_bits/1 , make_unit/0 @@ -120,7 +115,6 @@ make_signature(X) -> make_bytes(X). make_contract(X) -> ?FATE_CONTRACT(X). make_oracle(X) -> ?FATE_ORACLE(X). make_oracle_query(X) -> ?FATE_ORACLE_Q(X). -make_name(X) -> ?FATE_NAME(X). make_channel(X) -> ?FATE_CHANNEL(X). make_integer(I) when is_integer(I) -> ?MAKE_FATE_INTEGER(I). make_bits(I) when is_integer(I) -> ?FATE_BITS(I). @@ -179,8 +173,6 @@ format(?FATE_ORACLE(X)) -> ["@", aeser_api_encoder:encode(oracle_pubkey, X)]; format(?FATE_ORACLE_Q(X)) -> ["@", aeser_api_encoder:encode(oracle_query_id, X)]; -format(?FATE_NAME(X)) -> - ["@", aeser_api_encoder:encode(name, X)]; format(?FATE_CHANNEL(X)) -> ["@", aeser_api_encoder:encode(channel, X)]; format(?FATE_TYPEREP(X)) -> @@ -208,7 +200,7 @@ format_kvs(List) -> %% Total order of FATE terms. -%% Integers < Booleans < Address < Channel < Contract < Name < Oracle +%% Integers < Booleans < Address < Channel < Contract < Oracle %% < Hash < Signature < Bits < String < Tuple < Map < List < Variant -spec ordinal(fate_type()) -> integer(). ordinal(T) when ?IS_FATE_INTEGER(T) -> 0; @@ -216,7 +208,7 @@ ordinal(T) when ?IS_FATE_BOOLEAN(T) -> 1; ordinal(T) when ?IS_FATE_ADDRESS(T) -> 2; ordinal(T) when ?IS_FATE_CHANNEL(T) -> 3; ordinal(T) when ?IS_FATE_CONTRACT(T) -> 4; -ordinal(T) when ?IS_FATE_NAME(T) -> 5; +%% 5 ordinal(T) when ?IS_FATE_ORACLE(T) -> 6; ordinal(T) when ?IS_FATE_BYTES(T) -> 7; %% 8; diff --git a/src/aeb_fate_encoding.erl b/src/aeb_fate_encoding.erl index 8a62178..2475c1d 100644 --- a/src/aeb_fate_encoding.erl +++ b/src/aeb_fate_encoding.erl @@ -112,8 +112,7 @@ -define(OTYPE_CONTRACT, 2). -define(OTYPE_ORACLE, 3). -define(OTYPE_ORACLE_Q, 4). --define(OTYPE_NAME, 5). --define(OTYPE_CHANNEL, 6). +-define(OTYPE_CHANNEL, 5). -define(IS_TYPE_TAG(X), (X =:= ?TYPE_INTEGER orelse X =:= ?TYPE_BOOLEAN orelse @@ -162,8 +161,6 @@ serialize(?FATE_ORACLE(Address)) when is_binary(Address) -> <>; serialize(?FATE_ORACLE_Q(Address)) when is_binary(Address) -> <>; -serialize(?FATE_NAME(Address)) when is_binary(Address) -> - <>; serialize(?FATE_CHANNEL(Address)) when is_binary(Address) -> <>; serialize(?FATE_TUPLE(T)) when size(T) > 0 -> @@ -236,7 +233,6 @@ serialize_type(address) -> [?TYPE_OBJECT, ?OTYPE_ADDRESS]; serialize_type(contract) -> [?TYPE_OBJECT, ?OTYPE_CONTRACT]; serialize_type(oracle) -> [?TYPE_OBJECT, ?OTYPE_ORACLE]; serialize_type(oracle_query)-> [?TYPE_OBJECT, ?OTYPE_ORACLE_Q]; -serialize_type(name) -> [?TYPE_OBJECT, ?OTYPE_NAME]; serialize_type(channel) -> [?TYPE_OBJECT, ?OTYPE_CHANNEL]; serialize_type(bits) -> [?TYPE_BITS]; serialize_type({map, K, V}) -> [?TYPE_MAP @@ -270,7 +266,6 @@ deserialize_type(<>) -> ?OTYPE_CONTRACT -> {contract, Rest}; ?OTYPE_ORACLE -> {oracle, Rest}; ?OTYPE_ORACLE_Q -> {oracle_query, Rest}; - ?OTYPE_NAME -> {name, Rest}; ?OTYPE_CHANNEL -> {channel, Rest} end; deserialize_type(<>) -> {bits, Rest}; @@ -393,7 +388,6 @@ deserialize2(<>) -> ?OTYPE_CONTRACT -> ?FATE_CONTRACT(A); ?OTYPE_ORACLE -> ?FATE_ORACLE(A); ?OTYPE_ORACLE_Q -> ?FATE_ORACLE_Q(A); - ?OTYPE_NAME -> ?FATE_NAME(A); ?OTYPE_CHANNEL -> ?FATE_CHANNEL(A) end, {Val, Rest2}; diff --git a/src/aeb_fate_generate_ops.erl b/src/aeb_fate_generate_ops.erl index 9423bbb..e9afe17 100644 --- a/src/aeb_fate_generate_ops.erl +++ b/src/aeb_fate_generate_ops.erl @@ -149,12 +149,12 @@ ops_defs() -> , { 'ORACLE_GET_ANSWER', 16#65, false, false, 3, [a,a,a,a,a], oracle_get_answer, {oracle, oracle_query, typerep, typerep}, any, "Arg0 := option variant with answer (if any) from oracle query in Arg1 given by oracle Arg0. Typereps for checking oracle type is in Arg3 and Arg4."} , { 'ORACLE_GET_QUESTION', 16#66, false, false, 3, [a,a,a,a,a], oracle_get_question, {oracle, oracle_query, typerep, typerep}, any, "Arg0 := question in oracle query Arg2 given to oracle Arg1. Typereps for checking oracle type is in Arg3 and Arg4."} , { 'ORACLE_QUERY_FEE', 16#67, false, false, 3, [a,a], oracle_query_fee, {oracle}, integer, "Arg0 := query fee for oracle Arg1"} - , { 'AENS_RESOLVE', 16#68, false, false, 3, [], aens_resolve, {}, none, "NYI"} - , { 'AENS_PRECLAIM', 16#69, false, false, 3, [], aens_preclaim, {}, none, "NYI"} - , { 'AENS_CLAIM', 16#6a, false, false, 3, [], aens_claim, {}, none, "NYI"} - , { 'AENS_UPDATE', 16#6b, false, false, 3, [], aend_update, {}, none, "NYI"} - , { 'AENS_TRANSFER', 16#6c, false, false, 3, [], aens_transfer, {}, none, "NYI"} - , { 'AENS_REVOKE', 16#6d, false, false, 3, [], aens_revoke, {}, none, "NYI"} + , { 'AENS_RESOLVE', 16#68, false, false, 3, [a,a,a,a], aens_resolve, {string, string, typerep}, variant, "Resolve name in Arg0 with tag Arg1. Arg2 describes the type parameter of the resolved name."} + , { 'AENS_PRECLAIM', 16#69, false, false, 3, [a,a,a], aens_preclaim, {signature, address, hash}, none, "Preclaim the hash in Arg2 for address in Arg1. Arg0 contains delegation signature."} + , { 'AENS_CLAIM', 16#6a, false, false, 3, [a,a,a,a], aens_claim, {signature, address, string, integer}, none, "Claim the name in Arg2 for address in Arg1. Arg3 contains the salt used to hash the preclaim. Arg0 contains delegation signature."} + , { 'AENS_UPDATE', 16#6b, false, false, 3, [], aens_update, {}, none, "NYI"} + , { 'AENS_TRANSFER', 16#6c, false, false, 3, [a,a,a,a], aens_transfer, {signature, address, address, hash}, none, "Transfer ownership of name Arg3 from account Arg1 to Arg2. Arg0 contains delegation signature."} + , { 'AENS_REVOKE', 16#6d, false, false, 3, [a,a,a], aens_revoke, {signature, address, hash}, none, "Revoke the name in Arg2 from owner Arg1. Arg0 contains delegation signature."} , { 'BALANCE_OTHER', 16#6e, false, true, 3, [a,a], balance_other, {address}, integer, "Arg0 := The balance of address Arg1."} %% TODO: Reorder these before documenting the specification , { 'MAP_SIZE', 16#6f, false, true, 3, [a,a], map_size_, {map}, integer, "Arg0 := The size of the map Arg1."} diff --git a/test/aeb_fate_asm_test.erl b/test/aeb_fate_asm_test.erl index 42df184..9e9cb95 100644 --- a/test/aeb_fate_asm_test.erl +++ b/test/aeb_fate_asm_test.erl @@ -47,6 +47,7 @@ sources() -> , "tuple" , "mapofmap" , "immediates" + , "names" , "oracles" %% , "all_instructions" ]. diff --git a/test/aeb_serialize_test.erl b/test/aeb_serialize_test.erl index c96c006..fa18061 100644 --- a/test/aeb_serialize_test.erl +++ b/test/aeb_serialize_test.erl @@ -50,7 +50,6 @@ sources() -> aeb_fate_data:make_hash(<<1,2,3,4,5>>), aeb_fate_data:make_signature(<<1,2,3,4,5>>), aeb_fate_data:make_contract(<<1,2,3,4,5>>), - aeb_fate_data:make_name(<<1,2,3,4,5>>), aeb_fate_data:make_channel(<<1,2,3,4,5>>), aeb_fate_data:make_list([True]), aeb_fate_data:make_address( diff --git a/test/asm_code/immediates.fate b/test/asm_code/immediates.fate index 558e1b6..b0d2706 100644 --- a/test/asm_code/immediates.fate +++ b/test/asm_code/immediates.fate @@ -74,9 +74,6 @@ FUNCTION oracle() : oracle FUNCTION contract() : contract RETURNR @ct_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv -FUNCTION name() : name - RETURNR @nm_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv - FUNCTION channel() : channel RETURNR @ch_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv diff --git a/test/asm_code/names.fate b/test/asm_code/names.fate new file mode 100644 index 0000000..056335a --- /dev/null +++ b/test/asm_code/names.fate @@ -0,0 +1,23 @@ +;; CONTRACT names + +FUNCTION preclaim(address, {bytes, 32}) : {tuple, []} + AENS_PRECLAIM #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== arg0 arg1 + RETURNR {} + +FUNCTION claim(address, string, integer) : {tuple, []} + AENS_CLAIM #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== arg0 arg1 arg2 + RETURNR {} + +FUNCTION transfer(address, address, {bytes, 32}) : {tuple, []} + AENS_TRANSFER #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== arg0 arg1 arg2 + RETURNR {} + +FUNCTION revoke(address, {bytes, 32}) : {tuple, []} + AENS_REVOKE #AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== arg0 arg1 + RETURNR {} + +FUNCTION resolve(string, string) : {variant, [{tuple, []}, {tuple, [address]}]} + AENS_RESOLVE a arg0 arg1 'address + RETURN + +