Skip to content

Commit b8d593e

Browse files
authored
Add instructions for arbitrary sized byte arrays (#114)
* Encode/decode bytes()/{bytes, any} as bytes(-1) * Add 5 new bytes instructions * reorder instructions and clarify some operations
1 parent 0f7529b commit b8d593e

2 files changed

Lines changed: 27 additions & 16 deletions

File tree

src/aeb_fate_encoding.erl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ serialize_type({tuple, Ts}) ->
238238
N when N =< 255 ->
239239
[?TYPE_TUPLE, N | [serialize_type(T) || T <- Ts]]
240240
end;
241+
serialize_type({bytes, any}) ->
242+
[?TYPE_BYTES | binary_to_list(serialize_integer(-1))];
241243
serialize_type({bytes, N}) when 0 =< N ->
242244
[?TYPE_BYTES | binary_to_list(serialize_integer(N))];
243245
serialize_type(address) -> [?TYPE_OBJECT, ?OTYPE_ADDRESS];
@@ -270,8 +272,12 @@ deserialize_type(<<?TYPE_TUPLE, N, Rest/binary>>) ->
270272
{{tuple, Ts}, Rest2};
271273
deserialize_type(<<?TYPE_BYTES, Rest/binary>>) ->
272274
{N, Rest2} = deserialize_one(Rest),
273-
true = is_integer(N) andalso N >= 0,
274-
{{bytes, N}, Rest2};
275+
true = is_integer(N),
276+
if N == -1 ->
277+
{{bytes, any}, Rest2};
278+
0 =< N ->
279+
{{bytes, N}, Rest2}
280+
end;
275281
deserialize_type(<<?TYPE_OBJECT, ObjectType, Rest/binary>>) ->
276282
case ObjectType of
277283
?OTYPE_ADDRESS -> {address, Rest};

src/aeb_fate_generate_ops.erl

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -232,20 +232,25 @@ ops_defs() ->
232232

233233
, { 'FEE', 16#a7, false, true, true, ?GAS(10), [a], fee, {}, integer, "Arg0 := The fee for the current call tx."}
234234

235-
, { 'ADDRESS_TO_BYTES', 16#a8, false, true, true, ?GAS(10), [a, a], addr_to_bytes, {address}, bytes, "Arg0 := the byte representation of the address"}
236-
, { 'POSEIDON', 16#a9, false, true, true, ?GAS(6000), [a, a, a], poseidon, {integer, integer}, integer, "Arg0 := the Poseidon hash of Arg1 and Arg2 - all integers in the BLS12-381 scalar field"}
237-
, { 'MULMOD', 16#aa, false, true, true, ?GAS(10), [a, a, a, a], mulmod, {integer, integer, integer}, integer, "Arg0 := (Arg1 * Arg2) mod Arg3"}
238-
, { 'BAND', 16#ab, false, true, true, ?GAS(10), [a, a, a], bin_and, {integer, integer}, integer, "Arg0 := Arg1 & Arg2"}
239-
, { 'BOR', 16#ac, false, true, true, ?GAS(10), [a, a, a], bin_or, {integer, integer}, integer, "Arg0 := Arg1 | Arg2"}
240-
, { 'BXOR', 16#ad, false, true, true, ?GAS(10), [a, a, a], bin_xor, {integer, integer}, integer, "Arg0 := Arg1 ^ Arg2"}
241-
, { 'BNOT', 16#ae, false, true, true, ?GAS(10), [a, a], bin_not, {integer}, integer, "Arg0 := ~Arg1"}
242-
, { 'BSL', 16#af, false, true, true, ?GAS(10), [a, a, a], bin_sl, {integer, integer}, integer, "Arg0 := Arg1 << Arg2"}
243-
, { 'BSR', 16#b0, false, true, true, ?GAS(10), [a, a, a], bin_sr, {integer, integer}, integer, "Arg0 := Arg1 >> Arg2"}
244-
245-
, { 'DBG_LOC', 16#b1, false, true, true, ?GAS(0), [a, a], dbg_loc, {string, integer}, none, "Debug Op: Execution location. Args = {file_name, line_num}" }
246-
, { 'DBG_DEF', 16#b2, false, true, true, ?GAS(0), [a, a], dbg_def, {string, any}, none, "Debug Op: Define a variable. Args = {var_name, register}" }
247-
, { 'DBG_UNDEF', 16#b3, false, true, true, ?GAS(0), [a, a], dbg_undef, {string, any}, none, "Debug Op: Undefine a variable. Args = {var_name, register}" }
248-
, { 'DBG_CONTRACT', 16#b4, false, true, true, ?GAS(0), [a], dbg_contract, {string}, none, "Debug Op: Name the current contract. Args: {contract_name}"}
235+
, { 'ADDRESS_TO_BYTES', 16#a8, false, true, true, ?GAS(10), [a, a], addr_to_bytes, {address}, bytes, "Arg0 := the byte representation of the address"}
236+
, { 'POSEIDON', 16#a9, false, true, true, ?GAS(6000), [a, a, a], poseidon, {integer, integer}, integer, "Arg0 := the Poseidon hash of Arg1 and Arg2 - all integers in the BLS12-381 scalar field"}
237+
, { 'MULMOD', 16#aa, false, true, true, ?GAS(10), [a, a, a, a], mulmod, {integer, integer, integer}, integer, "Arg0 := (Arg1 * Arg2) mod Arg3"}
238+
, { 'BAND', 16#ab, false, true, true, ?GAS(10), [a, a, a], bin_and, {integer, integer}, integer, "Arg0 := Arg1 & Arg2"}
239+
, { 'BOR', 16#ac, false, true, true, ?GAS(10), [a, a, a], bin_or, {integer, integer}, integer, "Arg0 := Arg1 | Arg2"}
240+
, { 'BXOR', 16#ad, false, true, true, ?GAS(10), [a, a, a], bin_xor, {integer, integer}, integer, "Arg0 := Arg1 ^ Arg2"}
241+
, { 'BNOT', 16#ae, false, true, true, ?GAS(10), [a, a], bin_not, {integer}, integer, "Arg0 := ~Arg1"}
242+
, { 'BSL', 16#af, false, true, true, ?GAS(10), [a, a, a], bin_sl, {integer, integer}, integer, "Arg0 := Arg1 << Arg2"}
243+
, { 'BSR', 16#b0, false, true, true, ?GAS(10), [a, a, a], bin_sr, {integer, integer}, integer, "Arg0 := Arg1 >> Arg2"}
244+
, { 'BYTES_SPLIT_ANY', 16#b1, false, true, true, ?GAS(10), [a, a, a], bytes_split_any, {bytes, integer}, variant, "Arg0 := bytes_split_any(Arg1, Arg2), where a positive Arg2 is the length of the first chunk, and a negative Arg2 is the length of the second chunk. Returns None if byte array is not long enough."}
245+
, { 'BYTES_SIZE', 16#b2, false, true, true, ?GAS(10), [a, a], bytes_size, {bytes}, integer, "Arg0 := bytes_size(Arg1), returns the number of bytes in the byte array."}
246+
, { 'BYTES_TO_FIXED_SIZE', 16#b3, false, true, true, ?GAS(10), [a, a, a], bytes_to_fixed_size, {bytes, integer}, variant, "Arg0 := bytes_to_fixed_size(Arg1, Arg2), returns Some(Arg1') if byte_size(Arg1) == Arg2, None otherwise. The type of Arg1' is bytes(Arg2) but the value is unchanged"}
247+
, { 'INT_TO_BYTES', 16#b4, false, true, true, ?GAS(10), [a, a, a], int_to_bytes, {integer, integer}, bytes, "Arg0 := turn integer Arg1 into a byte array (big endian) length Arg2 (truncating if not fit)."}
248+
, { 'STR_TO_BYTES', 16#b5, false, true, true, ?GAS(10), [a, a], str_to_bytes, {integer}, bytes, "Arg0 := turn string Arg1 into the corresponding byte array."}
249+
250+
, { 'DBG_LOC', 16#b6, false, true, true, ?GAS(0), [a, a], dbg_loc, {string, integer}, none, "Debug Op: Execution location. Args = {file_name, line_num}" }
251+
, { 'DBG_DEF', 16#b7, false, true, true, ?GAS(0), [a, a], dbg_def, {string, any}, none, "Debug Op: Define a variable. Args = {var_name, register}" }
252+
, { 'DBG_UNDEF', 16#b8, false, true, true, ?GAS(0), [a, a], dbg_undef, {string, any}, none, "Debug Op: Undefine a variable. Args = {var_name, register}" }
253+
, { 'DBG_CONTRACT', 16#b9, false, true, true, ?GAS(0), [a], dbg_contract, {string}, none, "Debug Op: Name the current contract. Args: {contract_name}"}
249254

250255
, { 'DEACTIVATE', 16#fa, false, true, true, ?GAS(10), [], deactivate, {}, none, "Mark the current contract for deactivation."}
251256
, { 'ABORT', 16#fb, true, true, true, ?GAS(10), [a], abort, {string}, none, "Abort execution (dont use all gas) with error message in Arg0."}

0 commit comments

Comments
 (0)