diff --git a/docs/alpha/michelson.rst b/docs/alpha/michelson.rst index ee1702794cbd4560a29c00ae8660cd1866645bf6..f9ae7bc60a0e402a76dd24af9f7d03b14dfbac33 100644 --- a/docs/alpha/michelson.rst +++ b/docs/alpha/michelson.rst @@ -3336,7 +3336,7 @@ name the root of the type. The conventional name for that is ``root``. Let us recapitulate this by tweaking the names of the previous example. -``parameter %root (or (or (nat %A) (bool %B)) (or (unit %default) string))`` +``parameter (or %root (or (nat %A) (bool %B)) (or (unit %default) string))`` The input values will be wrapped as in the following examples. diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index d35c510ad77dfe49cbaebae225277018b9d31953..c6a15a2d78d8d4b214dd8e1ff02bb9f80fa453a6 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -97,6 +97,11 @@ Michelson - Field annotations are ignored and not propagated on comparable types and on regular pairs (MR :gl:`!4175`) +- Annotating the parameter toplevel constructor to designate the root entrypoint + is now forbidden. Put the annotation on the parameter type instead. + E.g. replace ``parameter %a int;`` by ``parameter (int %a);`` + (MR :gl:`!4366`) + Internal -------- diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index fd4782c37a1b36a8fee7a173796423427008a72a..f6806f9b93f9d075991aa060679e663b14207f91 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -5056,7 +5056,7 @@ and parse_view_name ctxt : Script.node -> (Script_string.t * context) tzresult = and parse_toplevel : context -> legacy:bool -> Script.expr -> (toplevel * context) tzresult = - fun ctxt ~legacy:_ toplevel -> + fun ctxt ~legacy toplevel -> record_trace (Ill_typed_contract (toplevel, [])) @@ match root toplevel with @@ -5120,14 +5120,15 @@ and parse_toplevel : views ) -> let maybe_root_name = (* root name can be attached to either the parameter - primitive or the toplevel constructor *) + primitive or the toplevel constructor (legacy only) *) Script_ir_annot.extract_field_annot p >>? fun (p, root_name) -> match root_name with | Some _ -> ok (p, pannot, root_name) | None -> ( match pannot with | [single] - when Compare.Int.(String.length single > 0) + when legacy + && Compare.Int.(String.length single > 0) && Compare.Char.(single.[0] = '%') -> parse_field_annot ploc [single] >>? fun pannot -> ok (p, [], pannot) diff --git a/tests_python/contracts_alpha/ill_typed/create_contract_rootname.tz b/tests_python/contracts_alpha/ill_typed/create_contract_rootname.tz new file mode 100644 index 0000000000000000000000000000000000000000..b85b4cf8bb414ff256a62fadd41d5e50755d5d9e --- /dev/null +++ b/tests_python/contracts_alpha/ill_typed/create_contract_rootname.tz @@ -0,0 +1,15 @@ +# this contract creates a contract +parameter unit; +storage (option address); +code { DROP; + UNIT; # starting storage for contract + AMOUNT; # Push the starting balance + NONE key_hash; # No delegate + CREATE_CONTRACT # Create the contract + { parameter %root unit ; + storage unit ; + code + { CDR; + NIL operation; + PAIR; } }; + DIP {SOME;NIL operation}; CONS ; PAIR} # Ending calling convention stuff diff --git a/tests_python/contracts_alpha/opcodes/create_contract_rootname.tz b/tests_python/contracts_alpha/opcodes/create_contract_rootname.tz index b85b4cf8bb414ff256a62fadd41d5e50755d5d9e..85fb97922fe7c1a9e790c9ee8ce38ef449e19b9f 100644 --- a/tests_python/contracts_alpha/opcodes/create_contract_rootname.tz +++ b/tests_python/contracts_alpha/opcodes/create_contract_rootname.tz @@ -6,7 +6,7 @@ code { DROP; AMOUNT; # Push the starting balance NONE key_hash; # No delegate CREATE_CONTRACT # Create the contract - { parameter %root unit ; + { parameter (unit %root) ; storage unit ; code { CDR; diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out index e1fbc7c9c83ce5bfa88197085b499a2b0e322004..f6457c33156ed780d737dfcc2ae59261b03abb3d 100644 --- a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out @@ -151,7 +151,7 @@ expruYk7GXYQ7bKbUcqcHDKs97USVBrxAkzSo2Bkj5AXVjSawDkNAS [CONTRACT_PATH]/opcodes/c expruMW9W9kkb2JaQWzKVThky4ULQ6ckgLzE2xD49XUp5E1iwWfUbe [CONTRACT_PATH]/opcodes/contains_all.tz exprvDvotLP1G2qjPJiqz2RvVUm8wJ2cEuFvKtm7YUNW3w6krDponF [CONTRACT_PATH]/opcodes/contract.tz exprvNrgGoLvfEaXw6QmjQrkXESpWo72JHR4G4mhTJy7Y266YXa3fe [CONTRACT_PATH]/opcodes/create_contract.tz -exprv8no3WSXCsf89WYazUNurLm8hwZRwTWYBQrzihscQcR6M1uKEu [CONTRACT_PATH]/opcodes/create_contract_rootname.tz +exprttdxhC3YwJ9SGJNTDMQRpyWX1KwqAUuPbkQHX3uMPHNt3GKkZK [CONTRACT_PATH]/opcodes/create_contract_rootname.tz exprttdxhC3YwJ9SGJNTDMQRpyWX1KwqAUuPbkQHX3uMPHNt3GKkZK [CONTRACT_PATH]/opcodes/create_contract_rootname_alt.tz expruxUAUoijmC6A4rZK9XHcQL4WmgreJwT17hrgpuYkg1VeELBdbF [CONTRACT_PATH]/opcodes/create_contract_with_view.tz exprteqmco8PDGH1PnTGgF5jPjBPCYyZfyvER2ULtv2y3MRgGdcP8T [CONTRACT_PATH]/opcodes/diff_timestamps.tz diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out index b1c8f67e84dfebd754df9cf3ef5b585c467a33c2..fef637c9b41a05be999b96e194b36df28d368c60 100644 --- a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out @@ -14,7 +14,7 @@ Gas remaining: 1039988.704 units remaining NONE key_hash /* [ option key_hash : mutez : unit ] */ ; CREATE_CONTRACT - { parameter %root unit ; + { parameter (unit %root) ; storage unit ; code { CDR ; NIL operation ; PAIR } } /* [ operation : address ] */ ; diff --git a/tests_python/tests_alpha/test_contract_annotations.py b/tests_python/tests_alpha/test_contract_annotations.py index c34dcc016ee148b71e324b5ea1a35bb30b9b5b09..b1f67007c91453996fdc179cc608b8beaa608852 100644 --- a/tests_python/tests_alpha/test_contract_annotations.py +++ b/tests_python/tests_alpha/test_contract_annotations.py @@ -51,14 +51,34 @@ class TestAnnotations: 'unexpected annotation', ) - def test_field_annotation_in_root_alphabetic(self, client): + def test_field_annotation_in_root_alphabetic_legacy(self, client): client.typecheck( - 'parameter %r unit; storage unit; code {FAILWITH}', file=False + 'parameter %r unit; storage unit; code {FAILWITH}', + file=False, + legacy=True, ) - def test_field_annotation_in_root_numeral(self, client): + def test_field_annotation_in_root_numeral_legacy(self, client): client.typecheck( - 'parameter %1 unit; storage unit; code {FAILWITH}', file=False + 'parameter %1 unit; storage unit; code {FAILWITH}', + file=False, + legacy=True, + ) + + def test_field_annotation_in_root_alphabetic(self, client): + assert_typecheck_failure( + client, + 'parameter %r unit; storage unit; code {FAILWITH}', + 'unexpected annotation', + file=False, + ) + + def test_field_annotation_in_root_numeral(self, client): + assert_typecheck_failure( + client, + 'parameter %1 unit; storage unit; code {FAILWITH}', + 'unexpected annotation', + file=False, ) def test_field_annotation_in_root_invalid_character(self, client):