From cd9dd32665c78e325c42174a7915dcc292a3476e Mon Sep 17 00:00:00 2001 From: Benjamin Canou Date: Tue, 19 Jun 2018 14:44:15 +0200 Subject: [PATCH] Michelson: add CONCAT on bytes --- src/bin_client/test/contracts/list_iter2_bytes.tz | 3 +++ src/bin_client/test/test_contracts.sh | 4 ++++ src/proto_alpha/lib_protocol/src/michelson_v1_gas.ml | 4 +++- src/proto_alpha/lib_protocol/src/michelson_v1_gas.mli | 1 + .../lib_protocol/src/script_interpreter.ml | 7 ++++++- .../lib_protocol/src/script_ir_translator.ml | 11 +++++++++-- src/proto_alpha/lib_protocol/src/script_typed_ir.ml | 5 ++++- 7 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 src/bin_client/test/contracts/list_iter2_bytes.tz diff --git a/src/bin_client/test/contracts/list_iter2_bytes.tz b/src/bin_client/test/contracts/list_iter2_bytes.tz new file mode 100644 index 000000000..0fc8e1620 --- /dev/null +++ b/src/bin_client/test/contracts/list_iter2_bytes.tz @@ -0,0 +1,3 @@ +parameter (list bytes); +storage bytes; +code { UNPAIR ; SWAP ; CONS ; CONCAT; NIL operation; PAIR} diff --git a/src/bin_client/test/test_contracts.sh b/src/bin_client/test/test_contracts.sh index 6596da926..3c8f69d01 100755 --- a/src/bin_client/test/test_contracts.sh +++ b/src/bin_client/test/test_contracts.sh @@ -117,6 +117,10 @@ assert_storage $contract_dir/list_iter.tz 0 '{ 3 ; 6 ; 9 }' 162 assert_storage $contract_dir/list_iter2.tz '"abc"' '{ "d" ; "e" ; "f" }' '"abcdef"' assert_storage $contract_dir/list_iter2.tz '"abc"' '{}' '"abc"' +assert_storage $contract_dir/list_iter2_bytes.tz '0x00ab' '{ 0xcd ; 0xef ; 0x00 }' '0x00abcdef00' +assert_storage $contract_dir/list_iter2_bytes.tz '0x' '{ 0x00 ; 0x11 ; 0x00 }' '0x001100' +assert_storage $contract_dir/list_iter2_bytes.tz '0xabcd' '{}' '0xabcd' +assert_storage $contract_dir/list_iter2_bytes.tz '0x' '{}' '0x' # Identity on sets assert_storage $contract_dir/set_id.tz '{}' '{ "a" ; "b" ; "c" }' '{ "a" ; "b" ; "c" }' diff --git a/src/proto_alpha/lib_protocol/src/michelson_v1_gas.ml b/src/proto_alpha/lib_protocol/src/michelson_v1_gas.ml index caee17d83..93aeecfde 100644 --- a/src/proto_alpha/lib_protocol/src/michelson_v1_gas.ml +++ b/src/proto_alpha/lib_protocol/src/michelson_v1_gas.ml @@ -60,6 +60,7 @@ module Cost_of = struct cum free ss let concat_string ss = concat string String.length ss + let concat_bytes ss = concat bytes MBytes.length ss (* Cost per cycle of a loop, fold, etc *) let loop_cycle = step_cost 2 @@ -305,7 +306,8 @@ module Cost_of = struct | Big_map_mem -> alloc_cost 1 | Big_map_get -> alloc_cost 1 | Big_map_update -> alloc_cost 1 - | Concat -> alloc_cost 1 + | Concat_string -> alloc_cost 1 + | Concat_bytes -> alloc_cost 1 | Add_seconds_to_timestamp -> alloc_cost 1 | Add_timestamp_to_seconds -> alloc_cost 1 | Sub_timestamp_seconds -> alloc_cost 1 diff --git a/src/proto_alpha/lib_protocol/src/michelson_v1_gas.mli b/src/proto_alpha/lib_protocol/src/michelson_v1_gas.mli index 1ba1bd217..e8d7d16c6 100644 --- a/src/proto_alpha/lib_protocol/src/michelson_v1_gas.mli +++ b/src/proto_alpha/lib_protocol/src/michelson_v1_gas.mli @@ -39,6 +39,7 @@ module Cost_of : sig val variant_no_data : Gas.cost val branch : Gas.cost val concat_string : string list -> Gas.cost + val concat_bytes : MBytes.t list -> Gas.cost val map_mem : 'a -> ('b, 'c) Script_typed_ir.map -> Gas.cost val map_to_list : diff --git a/src/proto_alpha/lib_protocol/src/script_interpreter.ml b/src/proto_alpha/lib_protocol/src/script_interpreter.ml index bb758aecf..833b9cdc3 100644 --- a/src/proto_alpha/lib_protocol/src/script_interpreter.ml +++ b/src/proto_alpha/lib_protocol/src/script_interpreter.ml @@ -415,10 +415,15 @@ let rec interp consume_gas_binop descr (Script_timestamp.diff, t1, t2) Interp_costs.diff_timestamps rest ctxt (* string operations *) - | Concat, Item (ss, rest) -> + | Concat_string, Item (ss, rest) -> Lwt.return (Gas.consume ctxt (Interp_costs.concat_string ss)) >>=? fun ctxt -> let s = String.concat "" ss in logged_return (Item (s, rest), ctxt) + (* bytes operations *) + | Concat_bytes, Item (ss, rest) -> + Lwt.return (Gas.consume ctxt (Interp_costs.concat_bytes ss)) >>=? fun ctxt -> + let s = MBytes.concat "" ss in + logged_return (Item (s, rest), ctxt) (* currency operations *) | Add_tez, Item (x, Item (y, rest)) -> Lwt.return (Gas.consume ctxt Interp_costs.int64_op) >>=? fun ctxt -> diff --git a/src/proto_alpha/lib_protocol/src/script_ir_translator.ml b/src/proto_alpha/lib_protocol/src/script_ir_translator.ml index 553db4628..53c6fe0f2 100644 --- a/src/proto_alpha/lib_protocol/src/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/src/script_ir_translator.ml @@ -155,7 +155,8 @@ let number_of_generated_growing_types : type b a. (b, a) instr -> int = function | Big_map_get -> 0 | Big_map_update -> 0 | Big_map_mem -> 0 - | Concat -> 0 + | Concat_string -> 0 + | Concat_bytes -> 0 | Add_seconds_to_timestamp -> 0 | Add_timestamp_to_seconds -> 0 | Sub_timestamp_seconds -> 0 @@ -2113,8 +2114,14 @@ and parse_instr | Prim (loc, I_CONCAT, [], annot), Item_t (List_t (String_t tname, _), rest, list_annot) -> parse_var_annot ~default:list_annot loc annot >>=? fun annot -> - typed ctxt loc Concat + typed ctxt loc Concat_string (Item_t (String_t tname, rest, annot)) + (* bytes operations *) + | Prim (loc, I_CONCAT, [], annot), + Item_t (List_t (Bytes_t tname, _), rest, list_annot) -> + parse_var_annot ~default:list_annot loc annot >>=? fun annot -> + typed ctxt loc Concat_bytes + (Item_t (Bytes_t tname, rest, annot)) (* currency operations *) | Prim (loc, I_ADD, [], annot), Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) -> diff --git a/src/proto_alpha/lib_protocol/src/script_typed_ir.ml b/src/proto_alpha/lib_protocol/src/script_typed_ir.ml index ef824c5b4..c5718923f 100644 --- a/src/proto_alpha/lib_protocol/src/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/src/script_typed_ir.ml @@ -202,8 +202,11 @@ and ('bef, 'aft) instr = | Big_map_update : ('key * ('value option * (('key, 'value) big_map * 'rest)), ('key, 'value) big_map * 'rest) instr (* string operations *) - | Concat : + | Concat_string : (string list * 'rest, string * 'rest) instr + (* bytes operations *) + | Concat_bytes : + (MBytes.t list * 'rest, MBytes.t * 'rest) instr (* timestamp operations *) | Add_seconds_to_timestamp : (z num * (Script_timestamp.t * 'rest),